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 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
47 (UNSPEC_TLSLD_BASE 35)
59 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
60 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
61 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
62 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
63 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
65 ;; Attribute for cpu type.
66 ;; These must match the values for enum processor_type in sparc.h.
73 hypersparc,sparclite86x,
78 (const (symbol_ref "sparc_cpu_attr")))
80 ;; Attribute for the instruction set.
81 ;; At present we only need to distinguish v9/!v9, but for clarity we
82 ;; test TARGET_V8 too.
83 (define_attr "isa" "v7,v8,v9,sparclet"
85 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
86 (symbol_ref "TARGET_V8") (const_string "v8")
87 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
88 (const_string "v7"))))
94 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
102 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
105 multi,savew,flushw,iflush,trap"
106 (const_string "ialu"))
108 ;; True if branch/call has empty delay slot and will emit a nop in it
109 (define_attr "empty_delay_slot" "false,true"
110 (symbol_ref "empty_delay_slot (insn)"))
112 (define_attr "branch_type" "none,icc,fcc,reg"
113 (const_string "none"))
115 (define_attr "pic" "false,true"
116 (symbol_ref "flag_pic != 0"))
118 (define_attr "calls_alloca" "false,true"
119 (symbol_ref "current_function_calls_alloca != 0"))
121 (define_attr "calls_eh_return" "false,true"
122 (symbol_ref "current_function_calls_eh_return !=0 "))
124 (define_attr "leaf_function" "false,true"
125 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
127 (define_attr "delayed_branch" "false,true"
128 (symbol_ref "flag_delayed_branch != 0"))
130 ;; Length (in # of insns).
131 ;; Beware that setting a length greater or equal to 3 for conditional branches
132 ;; has a side-effect (see output_cbranch and output_v9branch).
133 (define_attr "length" ""
134 (cond [(eq_attr "type" "uncond_branch,call")
135 (if_then_else (eq_attr "empty_delay_slot" "true")
138 (eq_attr "type" "sibcall")
139 (if_then_else (eq_attr "leaf_function" "true")
140 (if_then_else (eq_attr "empty_delay_slot" "true")
143 (if_then_else (eq_attr "empty_delay_slot" "true")
146 (eq_attr "branch_type" "icc")
147 (if_then_else (match_operand 0 "noov_compare64_op" "")
148 (if_then_else (lt (pc) (match_dup 1))
149 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (if_then_else (eq_attr "empty_delay_slot" "true")
156 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
157 (if_then_else (eq_attr "empty_delay_slot" "true")
160 (if_then_else (eq_attr "empty_delay_slot" "true")
163 (if_then_else (eq_attr "empty_delay_slot" "true")
166 (eq_attr "branch_type" "fcc")
167 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
168 (if_then_else (eq_attr "empty_delay_slot" "true")
169 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
172 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
175 (if_then_else (lt (pc) (match_dup 2))
176 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
177 (if_then_else (eq_attr "empty_delay_slot" "true")
180 (if_then_else (eq_attr "empty_delay_slot" "true")
183 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (eq_attr "branch_type" "reg")
191 (if_then_else (lt (pc) (match_dup 2))
192 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (define_attr "fptype" "single,double"
210 (const_string "single"))
212 ;; UltraSPARC-III integer load type.
213 (define_attr "us3load_type" "2cycle,3cycle"
214 (const_string "2cycle"))
216 (define_asm_attributes
217 [(set_attr "length" "2")
218 (set_attr "type" "multi")])
220 ;; Attributes for instruction and branch scheduling
221 (define_attr "tls_call_delay" "false,true"
222 (symbol_ref "tls_call_delay (insn)"))
224 (define_attr "in_call_delay" "false,true"
225 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
226 (const_string "false")
227 (eq_attr "type" "load,fpload,store,fpstore")
228 (if_then_else (eq_attr "length" "1")
229 (const_string "true")
230 (const_string "false"))]
231 (if_then_else (and (eq_attr "length" "1")
232 (eq_attr "tls_call_delay" "true"))
233 (const_string "true")
234 (const_string "false"))))
236 (define_attr "eligible_for_sibcall_delay" "false,true"
237 (symbol_ref "eligible_for_sibcall_delay (insn)"))
239 (define_attr "eligible_for_return_delay" "false,true"
240 (symbol_ref "eligible_for_return_delay (insn)"))
242 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
243 ;; branches. This would allow us to remove the nop always inserted before
244 ;; a floating point branch.
246 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
247 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
248 ;; This is because doing so will add several pipeline stalls to the path
249 ;; that the load/store did not come from. Unfortunately, there is no way
250 ;; to prevent fill_eager_delay_slots from using load/store without completely
251 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
252 ;; because it prevents us from moving back the final store of inner loops.
254 (define_attr "in_branch_delay" "false,true"
255 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
256 (eq_attr "length" "1"))
257 (const_string "true")
258 (const_string "false")))
260 (define_attr "in_uncond_branch_delay" "false,true"
261 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
262 (eq_attr "length" "1"))
263 (const_string "true")
264 (const_string "false")))
266 (define_attr "in_annul_branch_delay" "false,true"
267 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
268 (eq_attr "length" "1"))
269 (const_string "true")
270 (const_string "false")))
272 (define_delay (eq_attr "type" "call")
273 [(eq_attr "in_call_delay" "true") (nil) (nil)])
275 (define_delay (eq_attr "type" "sibcall")
276 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
278 (define_delay (eq_attr "type" "branch")
279 [(eq_attr "in_branch_delay" "true")
280 (nil) (eq_attr "in_annul_branch_delay" "true")])
282 (define_delay (eq_attr "type" "uncond_branch")
283 [(eq_attr "in_uncond_branch_delay" "true")
286 (define_delay (eq_attr "type" "return")
287 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
289 ;; Include SPARC DFA schedulers
291 (include "cypress.md")
292 (include "supersparc.md")
293 (include "hypersparc.md")
294 (include "sparclet.md")
295 (include "ultra1_2.md")
296 (include "ultra3.md")
299 ;; Compare instructions.
300 ;; This controls RTL generation and register allocation.
302 ;; We generate RTL for comparisons and branches by having the cmpxx
303 ;; patterns store away the operands. Then, the scc and bcc patterns
304 ;; emit RTL for both the compare and the branch.
306 ;; We do this because we want to generate different code for an sne and
307 ;; seq insn. In those cases, if the second operand of the compare is not
308 ;; const0_rtx, we want to compute the xor of the two operands and test
311 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
312 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
313 ;; insns that actually require more than one machine instruction.
315 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
317 (define_expand "cmpsi"
319 (compare:CC (match_operand:SI 0 "compare_operand" "")
320 (match_operand:SI 1 "arith_operand" "")))]
323 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
324 operands[0] = force_reg (SImode, operands[0]);
326 sparc_compare_op0 = operands[0];
327 sparc_compare_op1 = operands[1];
331 (define_expand "cmpdi"
333 (compare:CCX (match_operand:DI 0 "compare_operand" "")
334 (match_operand:DI 1 "arith_double_operand" "")))]
337 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
338 operands[0] = force_reg (DImode, operands[0]);
340 sparc_compare_op0 = operands[0];
341 sparc_compare_op1 = operands[1];
345 (define_expand "cmpsf"
346 ;; The 96 here isn't ever used by anyone.
348 (compare:CCFP (match_operand:SF 0 "register_operand" "")
349 (match_operand:SF 1 "register_operand" "")))]
352 sparc_compare_op0 = operands[0];
353 sparc_compare_op1 = operands[1];
357 (define_expand "cmpdf"
358 ;; The 96 here isn't ever used by anyone.
360 (compare:CCFP (match_operand:DF 0 "register_operand" "")
361 (match_operand:DF 1 "register_operand" "")))]
364 sparc_compare_op0 = operands[0];
365 sparc_compare_op1 = operands[1];
369 (define_expand "cmptf"
370 ;; The 96 here isn't ever used by anyone.
372 (compare:CCFP (match_operand:TF 0 "register_operand" "")
373 (match_operand:TF 1 "register_operand" "")))]
376 sparc_compare_op0 = operands[0];
377 sparc_compare_op1 = operands[1];
381 ;; Now the compare DEFINE_INSNs.
383 (define_insn "*cmpsi_insn"
385 (compare:CC (match_operand:SI 0 "register_operand" "r")
386 (match_operand:SI 1 "arith_operand" "rI")))]
389 [(set_attr "type" "compare")])
391 (define_insn "*cmpdi_sp64"
393 (compare:CCX (match_operand:DI 0 "register_operand" "r")
394 (match_operand:DI 1 "arith_double_operand" "rHI")))]
397 [(set_attr "type" "compare")])
399 (define_insn "*cmpsf_fpe"
400 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
401 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
402 (match_operand:SF 2 "register_operand" "f")))]
406 return "fcmpes\t%0, %1, %2";
407 return "fcmpes\t%1, %2";
409 [(set_attr "type" "fpcmp")])
411 (define_insn "*cmpdf_fpe"
412 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
413 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
414 (match_operand:DF 2 "register_operand" "e")))]
418 return "fcmped\t%0, %1, %2";
419 return "fcmped\t%1, %2";
421 [(set_attr "type" "fpcmp")
422 (set_attr "fptype" "double")])
424 (define_insn "*cmptf_fpe"
425 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
426 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
427 (match_operand:TF 2 "register_operand" "e")))]
428 "TARGET_FPU && TARGET_HARD_QUAD"
431 return "fcmpeq\t%0, %1, %2";
432 return "fcmpeq\t%1, %2";
434 [(set_attr "type" "fpcmp")])
436 (define_insn "*cmpsf_fp"
437 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
438 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
439 (match_operand:SF 2 "register_operand" "f")))]
443 return "fcmps\t%0, %1, %2";
444 return "fcmps\t%1, %2";
446 [(set_attr "type" "fpcmp")])
448 (define_insn "*cmpdf_fp"
449 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
450 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
451 (match_operand:DF 2 "register_operand" "e")))]
455 return "fcmpd\t%0, %1, %2";
456 return "fcmpd\t%1, %2";
458 [(set_attr "type" "fpcmp")
459 (set_attr "fptype" "double")])
461 (define_insn "*cmptf_fp"
462 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
463 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
464 (match_operand:TF 2 "register_operand" "e")))]
465 "TARGET_FPU && TARGET_HARD_QUAD"
468 return "fcmpq\t%0, %1, %2";
469 return "fcmpq\t%1, %2";
471 [(set_attr "type" "fpcmp")])
473 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
474 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
475 ;; the same code as v8 (the addx/subx method has more applications). The
476 ;; exception to this is "reg != 0" which can be done in one instruction on v9
477 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
480 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
481 ;; generate addcc/subcc instructions.
483 (define_expand "seqsi_special"
485 (xor:SI (match_operand:SI 1 "register_operand" "")
486 (match_operand:SI 2 "register_operand" "")))
487 (parallel [(set (match_operand:SI 0 "register_operand" "")
488 (eq:SI (match_dup 3) (const_int 0)))
489 (clobber (reg:CC 100))])]
491 { operands[3] = gen_reg_rtx (SImode); })
493 (define_expand "seqdi_special"
495 (xor:DI (match_operand:DI 1 "register_operand" "")
496 (match_operand:DI 2 "register_operand" "")))
497 (set (match_operand:DI 0 "register_operand" "")
498 (eq:DI (match_dup 3) (const_int 0)))]
500 { operands[3] = gen_reg_rtx (DImode); })
502 (define_expand "snesi_special"
504 (xor:SI (match_operand:SI 1 "register_operand" "")
505 (match_operand:SI 2 "register_operand" "")))
506 (parallel [(set (match_operand:SI 0 "register_operand" "")
507 (ne:SI (match_dup 3) (const_int 0)))
508 (clobber (reg:CC 100))])]
510 { operands[3] = gen_reg_rtx (SImode); })
512 (define_expand "snedi_special"
514 (xor:DI (match_operand:DI 1 "register_operand" "")
515 (match_operand:DI 2 "register_operand" "")))
516 (set (match_operand:DI 0 "register_operand" "")
517 (ne:DI (match_dup 3) (const_int 0)))]
519 { operands[3] = gen_reg_rtx (DImode); })
521 (define_expand "seqdi_special_trunc"
523 (xor:DI (match_operand:DI 1 "register_operand" "")
524 (match_operand:DI 2 "register_operand" "")))
525 (set (match_operand:SI 0 "register_operand" "")
526 (eq:SI (match_dup 3) (const_int 0)))]
528 { operands[3] = gen_reg_rtx (DImode); })
530 (define_expand "snedi_special_trunc"
532 (xor:DI (match_operand:DI 1 "register_operand" "")
533 (match_operand:DI 2 "register_operand" "")))
534 (set (match_operand:SI 0 "register_operand" "")
535 (ne:SI (match_dup 3) (const_int 0)))]
537 { operands[3] = gen_reg_rtx (DImode); })
539 (define_expand "seqsi_special_extend"
541 (xor:SI (match_operand:SI 1 "register_operand" "")
542 (match_operand:SI 2 "register_operand" "")))
543 (parallel [(set (match_operand:DI 0 "register_operand" "")
544 (eq:DI (match_dup 3) (const_int 0)))
545 (clobber (reg:CC 100))])]
547 { operands[3] = gen_reg_rtx (SImode); })
549 (define_expand "snesi_special_extend"
551 (xor:SI (match_operand:SI 1 "register_operand" "")
552 (match_operand:SI 2 "register_operand" "")))
553 (parallel [(set (match_operand:DI 0 "register_operand" "")
554 (ne:DI (match_dup 3) (const_int 0)))
555 (clobber (reg:CC 100))])]
557 { operands[3] = gen_reg_rtx (SImode); })
559 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
560 ;; However, the code handles both SImode and DImode.
562 [(set (match_operand:SI 0 "intreg_operand" "")
563 (eq:SI (match_dup 1) (const_int 0)))]
566 if (GET_MODE (sparc_compare_op0) == SImode)
570 if (GET_MODE (operands[0]) == SImode)
571 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
573 else if (! TARGET_ARCH64)
576 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
581 else if (GET_MODE (sparc_compare_op0) == DImode)
587 else if (GET_MODE (operands[0]) == SImode)
588 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
591 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
596 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
598 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
599 emit_jump_insn (gen_sne (operands[0]));
604 if (gen_v9_scc (EQ, operands))
611 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
612 ;; However, the code handles both SImode and DImode.
614 [(set (match_operand:SI 0 "intreg_operand" "")
615 (ne:SI (match_dup 1) (const_int 0)))]
618 if (GET_MODE (sparc_compare_op0) == SImode)
622 if (GET_MODE (operands[0]) == SImode)
623 pat = gen_snesi_special (operands[0], sparc_compare_op0,
625 else if (! TARGET_ARCH64)
628 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
633 else if (GET_MODE (sparc_compare_op0) == DImode)
639 else if (GET_MODE (operands[0]) == SImode)
640 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
643 pat = gen_snedi_special (operands[0], sparc_compare_op0,
648 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
650 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
651 emit_jump_insn (gen_sne (operands[0]));
656 if (gen_v9_scc (NE, operands))
664 [(set (match_operand:SI 0 "intreg_operand" "")
665 (gt:SI (match_dup 1) (const_int 0)))]
668 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
670 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
671 emit_jump_insn (gen_sne (operands[0]));
676 if (gen_v9_scc (GT, operands))
684 [(set (match_operand:SI 0 "intreg_operand" "")
685 (lt:SI (match_dup 1) (const_int 0)))]
688 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
690 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
691 emit_jump_insn (gen_sne (operands[0]));
696 if (gen_v9_scc (LT, operands))
704 [(set (match_operand:SI 0 "intreg_operand" "")
705 (ge:SI (match_dup 1) (const_int 0)))]
708 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
710 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
711 emit_jump_insn (gen_sne (operands[0]));
716 if (gen_v9_scc (GE, operands))
724 [(set (match_operand:SI 0 "intreg_operand" "")
725 (le:SI (match_dup 1) (const_int 0)))]
728 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
730 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
731 emit_jump_insn (gen_sne (operands[0]));
736 if (gen_v9_scc (LE, operands))
743 (define_expand "sgtu"
744 [(set (match_operand:SI 0 "intreg_operand" "")
745 (gtu:SI (match_dup 1) (const_int 0)))]
752 /* We can do ltu easily, so if both operands are registers, swap them and
754 if ((GET_CODE (sparc_compare_op0) == REG
755 || GET_CODE (sparc_compare_op0) == SUBREG)
756 && (GET_CODE (sparc_compare_op1) == REG
757 || GET_CODE (sparc_compare_op1) == SUBREG))
759 tem = sparc_compare_op0;
760 sparc_compare_op0 = sparc_compare_op1;
761 sparc_compare_op1 = tem;
762 pat = gen_sltu (operands[0]);
771 if (gen_v9_scc (GTU, operands))
777 (define_expand "sltu"
778 [(set (match_operand:SI 0 "intreg_operand" "")
779 (ltu:SI (match_dup 1) (const_int 0)))]
784 if (gen_v9_scc (LTU, operands))
787 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
790 (define_expand "sgeu"
791 [(set (match_operand:SI 0 "intreg_operand" "")
792 (geu:SI (match_dup 1) (const_int 0)))]
797 if (gen_v9_scc (GEU, operands))
800 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
803 (define_expand "sleu"
804 [(set (match_operand:SI 0 "intreg_operand" "")
805 (leu:SI (match_dup 1) (const_int 0)))]
812 /* We can do geu easily, so if both operands are registers, swap them and
814 if ((GET_CODE (sparc_compare_op0) == REG
815 || GET_CODE (sparc_compare_op0) == SUBREG)
816 && (GET_CODE (sparc_compare_op1) == REG
817 || GET_CODE (sparc_compare_op1) == SUBREG))
819 tem = sparc_compare_op0;
820 sparc_compare_op0 = sparc_compare_op1;
821 sparc_compare_op1 = tem;
822 pat = gen_sgeu (operands[0]);
831 if (gen_v9_scc (LEU, operands))
837 ;; Now the DEFINE_INSNs for the scc cases.
839 ;; The SEQ and SNE patterns are special because they can be done
840 ;; without any branching and do not involve a COMPARE. We want
841 ;; them to always use the splitz below so the results can be
844 (define_insn_and_split "*snesi_zero"
845 [(set (match_operand:SI 0 "register_operand" "=r")
846 (ne:SI (match_operand:SI 1 "register_operand" "r")
848 (clobber (reg:CC 100))]
852 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
854 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
856 [(set_attr "length" "2")])
858 (define_insn_and_split "*neg_snesi_zero"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
862 (clobber (reg:CC 100))]
866 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
868 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
870 [(set_attr "length" "2")])
872 (define_insn_and_split "*snesi_zero_extend"
873 [(set (match_operand:DI 0 "register_operand" "=r")
874 (ne:DI (match_operand:SI 1 "register_operand" "r")
876 (clobber (reg:CC 100))]
880 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
883 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
885 (ltu:SI (reg:CC_NOOV 100)
888 [(set_attr "length" "2")])
890 (define_insn_and_split "*snedi_zero"
891 [(set (match_operand:DI 0 "register_operand" "=&r")
892 (ne:DI (match_operand:DI 1 "register_operand" "r")
896 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
897 [(set (match_dup 0) (const_int 0))
898 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
903 [(set_attr "length" "2")])
905 (define_insn_and_split "*neg_snedi_zero"
906 [(set (match_operand:DI 0 "register_operand" "=&r")
907 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
911 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
912 [(set (match_dup 0) (const_int 0))
913 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
918 [(set_attr "length" "2")])
920 (define_insn_and_split "*snedi_zero_trunc"
921 [(set (match_operand:SI 0 "register_operand" "=&r")
922 (ne:SI (match_operand:DI 1 "register_operand" "r")
926 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
927 [(set (match_dup 0) (const_int 0))
928 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
933 [(set_attr "length" "2")])
935 (define_insn_and_split "*seqsi_zero"
936 [(set (match_operand:SI 0 "register_operand" "=r")
937 (eq:SI (match_operand:SI 1 "register_operand" "r")
939 (clobber (reg:CC 100))]
943 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
945 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
947 [(set_attr "length" "2")])
949 (define_insn_and_split "*neg_seqsi_zero"
950 [(set (match_operand:SI 0 "register_operand" "=r")
951 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
953 (clobber (reg:CC 100))]
957 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
959 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
961 [(set_attr "length" "2")])
963 (define_insn_and_split "*seqsi_zero_extend"
964 [(set (match_operand:DI 0 "register_operand" "=r")
965 (eq:DI (match_operand:SI 1 "register_operand" "r")
967 (clobber (reg:CC 100))]
971 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
974 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
976 (ltu:SI (reg:CC_NOOV 100)
979 [(set_attr "length" "2")])
981 (define_insn_and_split "*seqdi_zero"
982 [(set (match_operand:DI 0 "register_operand" "=&r")
983 (eq:DI (match_operand:DI 1 "register_operand" "r")
987 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
988 [(set (match_dup 0) (const_int 0))
989 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
994 [(set_attr "length" "2")])
996 (define_insn_and_split "*neg_seqdi_zero"
997 [(set (match_operand:DI 0 "register_operand" "=&r")
998 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1002 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1003 [(set (match_dup 0) (const_int 0))
1004 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1009 [(set_attr "length" "2")])
1011 (define_insn_and_split "*seqdi_zero_trunc"
1012 [(set (match_operand:SI 0 "register_operand" "=&r")
1013 (eq:SI (match_operand:DI 1 "register_operand" "r")
1017 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1018 [(set (match_dup 0) (const_int 0))
1019 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1024 [(set_attr "length" "2")])
1026 ;; We can also do (x + (i == 0)) and related, so put them in.
1027 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1030 (define_insn_and_split "*x_plus_i_ne_0"
1031 [(set (match_operand:SI 0 "register_operand" "=r")
1032 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1034 (match_operand:SI 2 "register_operand" "r")))
1035 (clobber (reg:CC 100))]
1039 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1041 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1044 [(set_attr "length" "2")])
1046 (define_insn_and_split "*x_minus_i_ne_0"
1047 [(set (match_operand:SI 0 "register_operand" "=r")
1048 (minus:SI (match_operand:SI 2 "register_operand" "r")
1049 (ne:SI (match_operand:SI 1 "register_operand" "r")
1051 (clobber (reg:CC 100))]
1055 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1057 (set (match_dup 0) (minus:SI (match_dup 2)
1058 (ltu:SI (reg:CC 100) (const_int 0))))]
1060 [(set_attr "length" "2")])
1062 (define_insn_and_split "*x_plus_i_eq_0"
1063 [(set (match_operand:SI 0 "register_operand" "=r")
1064 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1066 (match_operand:SI 2 "register_operand" "r")))
1067 (clobber (reg:CC 100))]
1071 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1073 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1076 [(set_attr "length" "2")])
1078 (define_insn_and_split "*x_minus_i_eq_0"
1079 [(set (match_operand:SI 0 "register_operand" "=r")
1080 (minus:SI (match_operand:SI 2 "register_operand" "r")
1081 (eq:SI (match_operand:SI 1 "register_operand" "r")
1083 (clobber (reg:CC 100))]
1087 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1089 (set (match_dup 0) (minus:SI (match_dup 2)
1090 (geu:SI (reg:CC 100) (const_int 0))))]
1092 [(set_attr "length" "2")])
1094 ;; We can also do GEU and LTU directly, but these operate after a compare.
1095 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1098 (define_insn "*sltu_insn"
1099 [(set (match_operand:SI 0 "register_operand" "=r")
1100 (ltu:SI (reg:CC 100) (const_int 0)))]
1103 [(set_attr "type" "ialuX")])
1105 (define_insn "*neg_sltu_insn"
1106 [(set (match_operand:SI 0 "register_operand" "=r")
1107 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1110 [(set_attr "type" "ialuX")])
1112 ;; ??? Combine should canonicalize these next two to the same pattern.
1113 (define_insn "*neg_sltu_minus_x"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1116 (match_operand:SI 1 "arith_operand" "rI")))]
1118 "subx\t%%g0, %1, %0"
1119 [(set_attr "type" "ialuX")])
1121 (define_insn "*neg_sltu_plus_x"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1124 (match_operand:SI 1 "arith_operand" "rI"))))]
1126 "subx\t%%g0, %1, %0"
1127 [(set_attr "type" "ialuX")])
1129 (define_insn "*sgeu_insn"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (geu:SI (reg:CC 100) (const_int 0)))]
1133 "subx\t%%g0, -1, %0"
1134 [(set_attr "type" "ialuX")])
1136 (define_insn "*neg_sgeu_insn"
1137 [(set (match_operand:SI 0 "register_operand" "=r")
1138 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1140 "addx\t%%g0, -1, %0"
1141 [(set_attr "type" "ialuX")])
1143 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1144 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1147 (define_insn "*sltu_plus_x"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1150 (match_operand:SI 1 "arith_operand" "rI")))]
1152 "addx\t%%g0, %1, %0"
1153 [(set_attr "type" "ialuX")])
1155 (define_insn "*sltu_plus_x_plus_y"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1158 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1159 (match_operand:SI 2 "arith_operand" "rI"))))]
1162 [(set_attr "type" "ialuX")])
1164 (define_insn "*x_minus_sltu"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (minus:SI (match_operand:SI 1 "register_operand" "r")
1167 (ltu:SI (reg:CC 100) (const_int 0))))]
1170 [(set_attr "type" "ialuX")])
1172 ;; ??? Combine should canonicalize these next two to the same pattern.
1173 (define_insn "*x_minus_y_minus_sltu"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1176 (match_operand:SI 2 "arith_operand" "rI"))
1177 (ltu:SI (reg:CC 100) (const_int 0))))]
1180 [(set_attr "type" "ialuX")])
1182 (define_insn "*x_minus_sltu_plus_y"
1183 [(set (match_operand:SI 0 "register_operand" "=r")
1184 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1185 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1186 (match_operand:SI 2 "arith_operand" "rI"))))]
1189 [(set_attr "type" "ialuX")])
1191 (define_insn "*sgeu_plus_x"
1192 [(set (match_operand:SI 0 "register_operand" "=r")
1193 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1194 (match_operand:SI 1 "register_operand" "r")))]
1197 [(set_attr "type" "ialuX")])
1199 (define_insn "*x_minus_sgeu"
1200 [(set (match_operand:SI 0 "register_operand" "=r")
1201 (minus:SI (match_operand:SI 1 "register_operand" "r")
1202 (geu:SI (reg:CC 100) (const_int 0))))]
1205 [(set_attr "type" "ialuX")])
1208 [(set (match_operand:SI 0 "register_operand" "")
1209 (match_operator:SI 2 "noov_compare_op"
1210 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1213 && REGNO (operands[1]) == SPARC_ICC_REG
1214 && (GET_MODE (operands[1]) == CCXmode
1215 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1216 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1217 [(set (match_dup 0) (const_int 0))
1219 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1225 ;; These control RTL generation for conditional jump insns
1227 ;; The quad-word fp compare library routines all return nonzero to indicate
1228 ;; true, which is different from the equivalent libgcc routines, so we must
1229 ;; handle them specially here.
1231 (define_expand "beq"
1233 (if_then_else (eq (match_dup 1) (const_int 0))
1234 (label_ref (match_operand 0 "" ""))
1238 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1239 && GET_CODE (sparc_compare_op0) == REG
1240 && GET_MODE (sparc_compare_op0) == DImode)
1242 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1245 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1247 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1248 emit_jump_insn (gen_bne (operands[0]));
1251 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1254 (define_expand "bne"
1256 (if_then_else (ne (match_dup 1) (const_int 0))
1257 (label_ref (match_operand 0 "" ""))
1261 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1262 && GET_CODE (sparc_compare_op0) == REG
1263 && GET_MODE (sparc_compare_op0) == DImode)
1265 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1268 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1270 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1271 emit_jump_insn (gen_bne (operands[0]));
1274 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1277 (define_expand "bgt"
1279 (if_then_else (gt (match_dup 1) (const_int 0))
1280 (label_ref (match_operand 0 "" ""))
1284 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1285 && GET_CODE (sparc_compare_op0) == REG
1286 && GET_MODE (sparc_compare_op0) == DImode)
1288 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1291 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1293 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1294 emit_jump_insn (gen_bne (operands[0]));
1297 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1300 (define_expand "bgtu"
1302 (if_then_else (gtu (match_dup 1) (const_int 0))
1303 (label_ref (match_operand 0 "" ""))
1307 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1310 (define_expand "blt"
1312 (if_then_else (lt (match_dup 1) (const_int 0))
1313 (label_ref (match_operand 0 "" ""))
1317 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1318 && GET_CODE (sparc_compare_op0) == REG
1319 && GET_MODE (sparc_compare_op0) == DImode)
1321 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1324 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1326 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1327 emit_jump_insn (gen_bne (operands[0]));
1330 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1333 (define_expand "bltu"
1335 (if_then_else (ltu (match_dup 1) (const_int 0))
1336 (label_ref (match_operand 0 "" ""))
1340 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1343 (define_expand "bge"
1345 (if_then_else (ge (match_dup 1) (const_int 0))
1346 (label_ref (match_operand 0 "" ""))
1350 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1351 && GET_CODE (sparc_compare_op0) == REG
1352 && GET_MODE (sparc_compare_op0) == DImode)
1354 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1357 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1359 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1360 emit_jump_insn (gen_bne (operands[0]));
1363 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1366 (define_expand "bgeu"
1368 (if_then_else (geu (match_dup 1) (const_int 0))
1369 (label_ref (match_operand 0 "" ""))
1373 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1376 (define_expand "ble"
1378 (if_then_else (le (match_dup 1) (const_int 0))
1379 (label_ref (match_operand 0 "" ""))
1383 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1384 && GET_CODE (sparc_compare_op0) == REG
1385 && GET_MODE (sparc_compare_op0) == DImode)
1387 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1390 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1392 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1393 emit_jump_insn (gen_bne (operands[0]));
1396 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1399 (define_expand "bleu"
1401 (if_then_else (leu (match_dup 1) (const_int 0))
1402 (label_ref (match_operand 0 "" ""))
1406 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1409 (define_expand "bunordered"
1411 (if_then_else (unordered (match_dup 1) (const_int 0))
1412 (label_ref (match_operand 0 "" ""))
1416 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1418 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1420 emit_jump_insn (gen_beq (operands[0]));
1423 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1427 (define_expand "bordered"
1429 (if_then_else (ordered (match_dup 1) (const_int 0))
1430 (label_ref (match_operand 0 "" ""))
1434 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1436 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1437 emit_jump_insn (gen_bne (operands[0]));
1440 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1444 (define_expand "bungt"
1446 (if_then_else (ungt (match_dup 1) (const_int 0))
1447 (label_ref (match_operand 0 "" ""))
1451 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1453 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1454 emit_jump_insn (gen_bgt (operands[0]));
1457 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1460 (define_expand "bunlt"
1462 (if_then_else (unlt (match_dup 1) (const_int 0))
1463 (label_ref (match_operand 0 "" ""))
1467 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1469 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1470 emit_jump_insn (gen_bne (operands[0]));
1473 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1476 (define_expand "buneq"
1478 (if_then_else (uneq (match_dup 1) (const_int 0))
1479 (label_ref (match_operand 0 "" ""))
1483 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1485 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1486 emit_jump_insn (gen_beq (operands[0]));
1489 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1492 (define_expand "bunge"
1494 (if_then_else (unge (match_dup 1) (const_int 0))
1495 (label_ref (match_operand 0 "" ""))
1499 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1501 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1502 emit_jump_insn (gen_bne (operands[0]));
1505 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1508 (define_expand "bunle"
1510 (if_then_else (unle (match_dup 1) (const_int 0))
1511 (label_ref (match_operand 0 "" ""))
1515 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1517 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1518 emit_jump_insn (gen_bne (operands[0]));
1521 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1524 (define_expand "bltgt"
1526 (if_then_else (ltgt (match_dup 1) (const_int 0))
1527 (label_ref (match_operand 0 "" ""))
1531 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1533 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1534 emit_jump_insn (gen_bne (operands[0]));
1537 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1540 ;; Now match both normal and inverted jump.
1542 ;; XXX fpcmp nop braindamage
1543 (define_insn "*normal_branch"
1545 (if_then_else (match_operator 0 "noov_compare_op"
1546 [(reg 100) (const_int 0)])
1547 (label_ref (match_operand 1 "" ""))
1551 return output_cbranch (operands[0], operands[1], 1, 0,
1552 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1555 [(set_attr "type" "branch")
1556 (set_attr "branch_type" "icc")])
1558 ;; XXX fpcmp nop braindamage
1559 (define_insn "*inverted_branch"
1561 (if_then_else (match_operator 0 "noov_compare_op"
1562 [(reg 100) (const_int 0)])
1564 (label_ref (match_operand 1 "" ""))))]
1567 return output_cbranch (operands[0], operands[1], 1, 1,
1568 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1571 [(set_attr "type" "branch")
1572 (set_attr "branch_type" "icc")])
1574 ;; XXX fpcmp nop braindamage
1575 (define_insn "*normal_fp_branch"
1577 (if_then_else (match_operator 1 "comparison_operator"
1578 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1580 (label_ref (match_operand 2 "" ""))
1584 return output_cbranch (operands[1], operands[2], 2, 0,
1585 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1588 [(set_attr "type" "branch")
1589 (set_attr "branch_type" "fcc")])
1591 ;; XXX fpcmp nop braindamage
1592 (define_insn "*inverted_fp_branch"
1594 (if_then_else (match_operator 1 "comparison_operator"
1595 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1598 (label_ref (match_operand 2 "" ""))))]
1601 return output_cbranch (operands[1], operands[2], 2, 1,
1602 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1605 [(set_attr "type" "branch")
1606 (set_attr "branch_type" "fcc")])
1608 ;; XXX fpcmp nop braindamage
1609 (define_insn "*normal_fpe_branch"
1611 (if_then_else (match_operator 1 "comparison_operator"
1612 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1614 (label_ref (match_operand 2 "" ""))
1618 return output_cbranch (operands[1], operands[2], 2, 0,
1619 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1622 [(set_attr "type" "branch")
1623 (set_attr "branch_type" "fcc")])
1625 ;; XXX fpcmp nop braindamage
1626 (define_insn "*inverted_fpe_branch"
1628 (if_then_else (match_operator 1 "comparison_operator"
1629 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1632 (label_ref (match_operand 2 "" ""))))]
1635 return output_cbranch (operands[1], operands[2], 2, 1,
1636 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1639 [(set_attr "type" "branch")
1640 (set_attr "branch_type" "fcc")])
1642 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1643 ;; in the architecture.
1645 ;; There are no 32 bit brreg insns.
1648 (define_insn "*normal_int_branch_sp64"
1650 (if_then_else (match_operator 0 "v9_regcmp_op"
1651 [(match_operand:DI 1 "register_operand" "r")
1653 (label_ref (match_operand 2 "" ""))
1657 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1658 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1661 [(set_attr "type" "branch")
1662 (set_attr "branch_type" "reg")])
1665 (define_insn "*inverted_int_branch_sp64"
1667 (if_then_else (match_operator 0 "v9_regcmp_op"
1668 [(match_operand:DI 1 "register_operand" "r")
1671 (label_ref (match_operand 2 "" ""))))]
1674 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1675 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1678 [(set_attr "type" "branch")
1679 (set_attr "branch_type" "reg")])
1681 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1682 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1683 ;; that adds the PC value at the call point to operand 0.
1685 (define_insn "load_pcrel_sym"
1686 [(set (match_operand 0 "register_operand" "=r")
1687 (unspec [(match_operand 1 "symbolic_operand" "")
1688 (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1689 (clobber (reg:SI 15))]
1692 if (flag_delayed_branch)
1693 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1695 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1697 [(set (attr "type") (const_string "multi"))
1698 (set (attr "length")
1699 (if_then_else (eq_attr "delayed_branch" "true")
1703 ;; Move instructions
1705 (define_expand "movqi"
1706 [(set (match_operand:QI 0 "general_operand" "")
1707 (match_operand:QI 1 "general_operand" ""))]
1710 /* Working with CONST_INTs is easier, so convert
1711 a double if needed. */
1712 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1714 operands[1] = GEN_INT (trunc_int_for_mode
1715 (CONST_DOUBLE_LOW (operands[1]), QImode));
1718 /* Handle sets of MEM first. */
1719 if (GET_CODE (operands[0]) == MEM)
1721 if (reg_or_0_operand (operands[1], QImode))
1724 if (! reload_in_progress)
1726 operands[0] = validize_mem (operands[0]);
1727 operands[1] = force_reg (QImode, operands[1]);
1731 /* Fixup TLS cases. */
1732 if (tls_symbolic_operand (operands [1]))
1733 operands[1] = legitimize_tls_address (operands[1]);
1735 /* Fixup PIC cases. */
1738 if (CONSTANT_P (operands[1])
1739 && pic_address_needs_scratch (operands[1]))
1740 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1742 if (symbolic_operand (operands[1], QImode))
1744 operands[1] = legitimize_pic_address (operands[1],
1746 (reload_in_progress ?
1753 /* All QI constants require only one insn, so proceed. */
1759 (define_insn "*movqi_insn"
1760 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1761 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1762 "(register_operand (operands[0], QImode)
1763 || reg_or_0_operand (operands[1], QImode))"
1768 [(set_attr "type" "*,load,store")
1769 (set_attr "us3load_type" "*,3cycle,*")])
1771 (define_expand "movhi"
1772 [(set (match_operand:HI 0 "general_operand" "")
1773 (match_operand:HI 1 "general_operand" ""))]
1776 /* Working with CONST_INTs is easier, so convert
1777 a double if needed. */
1778 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1779 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1781 /* Handle sets of MEM first. */
1782 if (GET_CODE (operands[0]) == MEM)
1784 if (reg_or_0_operand (operands[1], HImode))
1787 if (! reload_in_progress)
1789 operands[0] = validize_mem (operands[0]);
1790 operands[1] = force_reg (HImode, operands[1]);
1794 /* Fixup TLS cases. */
1795 if (tls_symbolic_operand (operands [1]))
1796 operands[1] = legitimize_tls_address (operands[1]);
1798 /* Fixup PIC cases. */
1801 if (CONSTANT_P (operands[1])
1802 && pic_address_needs_scratch (operands[1]))
1803 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1805 if (symbolic_operand (operands[1], HImode))
1807 operands[1] = legitimize_pic_address (operands[1],
1809 (reload_in_progress ?
1816 /* This makes sure we will not get rematched due to splittage. */
1817 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1819 else if (CONSTANT_P (operands[1])
1820 && GET_CODE (operands[1]) != HIGH
1821 && GET_CODE (operands[1]) != LO_SUM)
1823 sparc_emit_set_const32 (operands[0], operands[1]);
1830 (define_insn "*movhi_const64_special"
1831 [(set (match_operand:HI 0 "register_operand" "=r")
1832 (match_operand:HI 1 "const64_high_operand" ""))]
1834 "sethi\t%%hi(%a1), %0")
1836 (define_insn "*movhi_insn"
1837 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1838 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1839 "(register_operand (operands[0], HImode)
1840 || reg_or_0_operand (operands[1], HImode))"
1843 sethi\t%%hi(%a1), %0
1846 [(set_attr "type" "*,*,load,store")
1847 (set_attr "us3load_type" "*,*,3cycle,*")])
1849 ;; We always work with constants here.
1850 (define_insn "*movhi_lo_sum"
1851 [(set (match_operand:HI 0 "register_operand" "=r")
1852 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1853 (match_operand:HI 2 "small_int" "I")))]
1857 (define_expand "movsi"
1858 [(set (match_operand:SI 0 "general_operand" "")
1859 (match_operand:SI 1 "general_operand" ""))]
1862 /* Working with CONST_INTs is easier, so convert
1863 a double if needed. */
1864 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1865 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1867 /* Handle sets of MEM first. */
1868 if (GET_CODE (operands[0]) == MEM)
1870 if (reg_or_0_operand (operands[1], SImode))
1873 if (! reload_in_progress)
1875 operands[0] = validize_mem (operands[0]);
1876 operands[1] = force_reg (SImode, operands[1]);
1880 /* Fixup TLS cases. */
1881 if (tls_symbolic_operand (operands [1]))
1882 operands[1] = legitimize_tls_address (operands[1]);
1884 /* Fixup PIC cases. */
1887 if (CONSTANT_P (operands[1])
1888 && pic_address_needs_scratch (operands[1]))
1889 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1891 if (GET_CODE (operands[1]) == LABEL_REF)
1894 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1898 if (symbolic_operand (operands[1], SImode))
1900 operands[1] = legitimize_pic_address (operands[1],
1902 (reload_in_progress ?
1909 /* If we are trying to toss an integer constant into the
1910 FPU registers, force it into memory. */
1911 if (GET_CODE (operands[0]) == REG
1912 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1913 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1914 && CONSTANT_P (operands[1]))
1915 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1918 /* This makes sure we will not get rematched due to splittage. */
1919 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1921 else if (CONSTANT_P (operands[1])
1922 && GET_CODE (operands[1]) != HIGH
1923 && GET_CODE (operands[1]) != LO_SUM)
1925 sparc_emit_set_const32 (operands[0], operands[1]);
1932 ;; This is needed to show CSE exactly which bits are set
1933 ;; in a 64-bit register by sethi instructions.
1934 (define_insn "*movsi_const64_special"
1935 [(set (match_operand:SI 0 "register_operand" "=r")
1936 (match_operand:SI 1 "const64_high_operand" ""))]
1938 "sethi\t%%hi(%a1), %0")
1940 (define_insn "*movsi_insn"
1941 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1942 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1943 "(register_operand (operands[0], SImode)
1944 || reg_or_0_operand (operands[1], SImode))"
1948 sethi\t%%hi(%a1), %0
1955 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1957 (define_insn "*movsi_lo_sum"
1958 [(set (match_operand:SI 0 "register_operand" "=r")
1959 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1960 (match_operand:SI 2 "immediate_operand" "in")))]
1962 "or\t%1, %%lo(%a2), %0")
1964 (define_insn "*movsi_high"
1965 [(set (match_operand:SI 0 "register_operand" "=r")
1966 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1968 "sethi\t%%hi(%a1), %0")
1970 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1971 ;; so that CSE won't optimize the address computation away.
1972 (define_insn "movsi_lo_sum_pic"
1973 [(set (match_operand:SI 0 "register_operand" "=r")
1974 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1975 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1977 "or\t%1, %%lo(%a2), %0")
1979 (define_insn "movsi_high_pic"
1980 [(set (match_operand:SI 0 "register_operand" "=r")
1981 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1982 "flag_pic && check_pic (1)"
1983 "sethi\t%%hi(%a1), %0")
1985 (define_expand "movsi_pic_label_ref"
1986 [(set (match_dup 3) (high:SI
1987 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1988 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1989 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1990 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1991 (set (match_operand:SI 0 "register_operand" "=r")
1992 (minus:SI (match_dup 5) (match_dup 4)))]
1995 current_function_uses_pic_offset_table = 1;
1996 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1999 operands[3] = operands[0];
2000 operands[4] = operands[0];
2004 operands[3] = gen_reg_rtx (SImode);
2005 operands[4] = gen_reg_rtx (SImode);
2007 operands[5] = pic_offset_table_rtx;
2010 (define_insn "*movsi_high_pic_label_ref"
2011 [(set (match_operand:SI 0 "register_operand" "=r")
2013 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2014 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2016 "sethi\t%%hi(%a2-(%a1-.)), %0")
2018 (define_insn "*movsi_lo_sum_pic_label_ref"
2019 [(set (match_operand:SI 0 "register_operand" "=r")
2020 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2021 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2022 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2024 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2026 (define_expand "movdi"
2027 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2028 (match_operand:DI 1 "general_operand" ""))]
2031 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2032 if (GET_CODE (operands[1]) == CONST_DOUBLE
2033 #if HOST_BITS_PER_WIDE_INT == 32
2034 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2035 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2036 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2037 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2040 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2042 /* Handle MEM cases first. */
2043 if (GET_CODE (operands[0]) == MEM)
2045 /* If it's a REG, we can always do it.
2046 The const zero case is more complex, on v9
2047 we can always perform it. */
2048 if (register_operand (operands[1], DImode)
2050 && (operands[1] == const0_rtx)))
2053 if (! reload_in_progress)
2055 operands[0] = validize_mem (operands[0]);
2056 operands[1] = force_reg (DImode, operands[1]);
2060 /* Fixup TLS cases. */
2061 if (tls_symbolic_operand (operands [1]))
2062 operands[1] = legitimize_tls_address (operands[1]);
2066 if (CONSTANT_P (operands[1])
2067 && pic_address_needs_scratch (operands[1]))
2068 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2070 if (GET_CODE (operands[1]) == LABEL_REF)
2072 if (! TARGET_ARCH64)
2074 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2078 if (symbolic_operand (operands[1], DImode))
2080 operands[1] = legitimize_pic_address (operands[1],
2082 (reload_in_progress ?
2089 /* If we are trying to toss an integer constant into the
2090 FPU registers, force it into memory. */
2091 if (GET_CODE (operands[0]) == REG
2092 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2093 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2094 && CONSTANT_P (operands[1]))
2095 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2098 /* This makes sure we will not get rematched due to splittage. */
2099 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2101 else if (TARGET_ARCH64
2102 && GET_CODE (operands[1]) != HIGH
2103 && GET_CODE (operands[1]) != LO_SUM)
2105 sparc_emit_set_const64 (operands[0], operands[1]);
2113 ;; Be careful, fmovd does not exist when !v9.
2114 ;; We match MEM moves directly when we have correct even
2115 ;; numbered registers, but fall into splits otherwise.
2116 ;; The constraint ordering here is really important to
2117 ;; avoid insane problems in reload, especially for patterns
2120 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2121 ;; (const_int -5016)))
2125 (define_insn "*movdi_insn_sp32_v9"
2126 [(set (match_operand:DI 0 "nonimmediate_operand"
2127 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2128 (match_operand:DI 1 "input_operand"
2129 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2130 "! TARGET_ARCH64 && TARGET_V9
2131 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2148 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2149 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2150 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2152 (define_insn "*movdi_insn_sp32"
2153 [(set (match_operand:DI 0 "nonimmediate_operand"
2154 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2155 (match_operand:DI 1 "input_operand"
2156 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2158 && (register_operand (operands[0], DImode)
2159 || register_operand (operands[1], DImode))"
2173 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2174 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2176 ;; The following are generated by sparc_emit_set_const64
2177 (define_insn "*movdi_sp64_dbl"
2178 [(set (match_operand:DI 0 "register_operand" "=r")
2179 (match_operand:DI 1 "const64_operand" ""))]
2181 && HOST_BITS_PER_WIDE_INT != 64)"
2184 ;; This is needed to show CSE exactly which bits are set
2185 ;; in a 64-bit register by sethi instructions.
2186 (define_insn "*movdi_const64_special"
2187 [(set (match_operand:DI 0 "register_operand" "=r")
2188 (match_operand:DI 1 "const64_high_operand" ""))]
2190 "sethi\t%%hi(%a1), %0")
2192 (define_insn "*movdi_insn_sp64_novis"
2193 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2194 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2195 "TARGET_ARCH64 && ! TARGET_VIS
2196 && (register_operand (operands[0], DImode)
2197 || reg_or_0_operand (operands[1], DImode))"
2200 sethi\t%%hi(%a1), %0
2207 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2208 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2210 ;; We don't define V1SI because SI should work just fine.
2211 (define_mode_macro V64 [DF V4HI V8QI V2SI])
2212 (define_mode_macro V32 [SF V2HI V4QI])
2214 (define_insn "*movdi_insn_sp64_vis"
2215 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2216 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2217 "TARGET_ARCH64 && TARGET_VIS &&
2218 (register_operand (operands[0], DImode)
2219 || reg_or_0_operand (operands[1], DImode))"
2222 sethi\t%%hi(%a1), %0
2230 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2231 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2233 (define_expand "movdi_pic_label_ref"
2234 [(set (match_dup 3) (high:DI
2235 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2236 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2237 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2238 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2239 (set (match_operand:DI 0 "register_operand" "=r")
2240 (minus:DI (match_dup 5) (match_dup 4)))]
2241 "TARGET_ARCH64 && flag_pic"
2243 current_function_uses_pic_offset_table = 1;
2244 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2247 operands[3] = operands[0];
2248 operands[4] = operands[0];
2252 operands[3] = gen_reg_rtx (DImode);
2253 operands[4] = gen_reg_rtx (DImode);
2255 operands[5] = pic_offset_table_rtx;
2258 (define_insn "*movdi_high_pic_label_ref"
2259 [(set (match_operand:DI 0 "register_operand" "=r")
2261 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2262 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2263 "TARGET_ARCH64 && flag_pic"
2264 "sethi\t%%hi(%a2-(%a1-.)), %0")
2266 (define_insn "*movdi_lo_sum_pic_label_ref"
2267 [(set (match_operand:DI 0 "register_operand" "=r")
2268 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2269 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2270 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2271 "TARGET_ARCH64 && flag_pic"
2272 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2274 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2275 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2277 (define_insn "movdi_lo_sum_pic"
2278 [(set (match_operand:DI 0 "register_operand" "=r")
2279 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2280 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2281 "TARGET_ARCH64 && flag_pic"
2282 "or\t%1, %%lo(%a2), %0")
2284 (define_insn "movdi_high_pic"
2285 [(set (match_operand:DI 0 "register_operand" "=r")
2286 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2287 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2288 "sethi\t%%hi(%a1), %0")
2290 (define_insn "*sethi_di_medlow_embmedany_pic"
2291 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2293 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2294 "sethi\t%%hi(%a1), %0")
2296 (define_insn "*sethi_di_medlow"
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2299 "TARGET_CM_MEDLOW && check_pic (1)"
2300 "sethi\t%%hi(%a1), %0")
2302 (define_insn "*losum_di_medlow"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2305 (match_operand:DI 2 "symbolic_operand" "")))]
2307 "or\t%1, %%lo(%a2), %0")
2309 (define_insn "seth44"
2310 [(set (match_operand:DI 0 "register_operand" "=r")
2311 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2313 "sethi\t%%h44(%a1), %0")
2315 (define_insn "setm44"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2317 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2318 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2320 "or\t%1, %%m44(%a2), %0")
2322 (define_insn "setl44"
2323 [(set (match_operand:DI 0 "register_operand" "=r")
2324 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2325 (match_operand:DI 2 "symbolic_operand" "")))]
2327 "or\t%1, %%l44(%a2), %0")
2329 (define_insn "sethh"
2330 [(set (match_operand:DI 0 "register_operand" "=r")
2331 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2333 "sethi\t%%hh(%a1), %0")
2335 (define_insn "setlm"
2336 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2339 "sethi\t%%lm(%a1), %0")
2341 (define_insn "sethm"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2344 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2346 "or\t%1, %%hm(%a2), %0")
2348 (define_insn "setlo"
2349 [(set (match_operand:DI 0 "register_operand" "=r")
2350 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2351 (match_operand:DI 2 "symbolic_operand" "")))]
2353 "or\t%1, %%lo(%a2), %0")
2355 (define_insn "embmedany_sethi"
2356 [(set (match_operand:DI 0 "register_operand" "=r")
2357 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2358 "TARGET_CM_EMBMEDANY && check_pic (1)"
2359 "sethi\t%%hi(%a1), %0")
2361 (define_insn "embmedany_losum"
2362 [(set (match_operand:DI 0 "register_operand" "=r")
2363 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2364 (match_operand:DI 2 "data_segment_operand" "")))]
2365 "TARGET_CM_EMBMEDANY"
2366 "add\t%1, %%lo(%a2), %0")
2368 (define_insn "embmedany_brsum"
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2371 "TARGET_CM_EMBMEDANY"
2374 (define_insn "embmedany_textuhi"
2375 [(set (match_operand:DI 0 "register_operand" "=r")
2376 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2377 "TARGET_CM_EMBMEDANY && check_pic (1)"
2378 "sethi\t%%uhi(%a1), %0")
2380 (define_insn "embmedany_texthi"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2383 "TARGET_CM_EMBMEDANY && check_pic (1)"
2384 "sethi\t%%hi(%a1), %0")
2386 (define_insn "embmedany_textulo"
2387 [(set (match_operand:DI 0 "register_operand" "=r")
2388 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2389 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2390 "TARGET_CM_EMBMEDANY"
2391 "or\t%1, %%ulo(%a2), %0")
2393 (define_insn "embmedany_textlo"
2394 [(set (match_operand:DI 0 "register_operand" "=r")
2395 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2396 (match_operand:DI 2 "text_segment_operand" "")))]
2397 "TARGET_CM_EMBMEDANY"
2398 "or\t%1, %%lo(%a2), %0")
2400 ;; Now some patterns to help reload out a bit.
2401 (define_expand "reload_indi"
2402 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2403 (match_operand:DI 1 "immediate_operand" "")
2404 (match_operand:TI 2 "register_operand" "=&r")])]
2406 || TARGET_CM_EMBMEDANY)
2409 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2413 (define_expand "reload_outdi"
2414 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2415 (match_operand:DI 1 "immediate_operand" "")
2416 (match_operand:TI 2 "register_operand" "=&r")])]
2418 || TARGET_CM_EMBMEDANY)
2421 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2425 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2427 [(set (match_operand:DI 0 "register_operand" "")
2428 (match_operand:DI 1 "const_int_operand" ""))]
2429 "! TARGET_ARCH64 && reload_completed"
2430 [(clobber (const_int 0))]
2432 #if HOST_BITS_PER_WIDE_INT == 32
2433 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2434 (INTVAL (operands[1]) < 0) ?
2437 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2440 unsigned int low, high;
2442 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2443 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2444 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2446 /* Slick... but this trick loses if this subreg constant part
2447 can be done in one insn. */
2448 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2449 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2450 gen_highpart (SImode, operands[0])));
2452 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2458 [(set (match_operand:DI 0 "register_operand" "")
2459 (match_operand:DI 1 "const_double_operand" ""))]
2463 && ((GET_CODE (operands[0]) == REG
2464 && REGNO (operands[0]) < 32)
2465 || (GET_CODE (operands[0]) == SUBREG
2466 && GET_CODE (SUBREG_REG (operands[0])) == REG
2467 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2468 [(clobber (const_int 0))]
2470 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2471 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2473 /* Slick... but this trick loses if this subreg constant part
2474 can be done in one insn. */
2475 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2476 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2477 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2479 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2480 gen_highpart (SImode, operands[0])));
2484 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2485 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2491 [(set (match_operand:DI 0 "register_operand" "")
2492 (match_operand:DI 1 "register_operand" ""))]
2496 && ((GET_CODE (operands[0]) == REG
2497 && REGNO (operands[0]) < 32)
2498 || (GET_CODE (operands[0]) == SUBREG
2499 && GET_CODE (SUBREG_REG (operands[0])) == REG
2500 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2501 [(clobber (const_int 0))]
2503 rtx set_dest = operands[0];
2504 rtx set_src = operands[1];
2508 dest1 = gen_highpart (SImode, set_dest);
2509 dest2 = gen_lowpart (SImode, set_dest);
2510 src1 = gen_highpart (SImode, set_src);
2511 src2 = gen_lowpart (SImode, set_src);
2513 /* Now emit using the real source and destination we found, swapping
2514 the order if we detect overlap. */
2515 if (reg_overlap_mentioned_p (dest1, src2))
2517 emit_insn (gen_movsi (dest2, src2));
2518 emit_insn (gen_movsi (dest1, src1));
2522 emit_insn (gen_movsi (dest1, src1));
2523 emit_insn (gen_movsi (dest2, src2));
2528 ;; Now handle the cases of memory moves from/to non-even
2529 ;; DI mode register pairs.
2531 [(set (match_operand:DI 0 "register_operand" "")
2532 (match_operand:DI 1 "memory_operand" ""))]
2535 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2536 [(clobber (const_int 0))]
2538 rtx word0 = adjust_address (operands[1], SImode, 0);
2539 rtx word1 = adjust_address (operands[1], SImode, 4);
2540 rtx high_part = gen_highpart (SImode, operands[0]);
2541 rtx low_part = gen_lowpart (SImode, operands[0]);
2543 if (reg_overlap_mentioned_p (high_part, word1))
2545 emit_insn (gen_movsi (low_part, word1));
2546 emit_insn (gen_movsi (high_part, word0));
2550 emit_insn (gen_movsi (high_part, word0));
2551 emit_insn (gen_movsi (low_part, word1));
2557 [(set (match_operand:DI 0 "memory_operand" "")
2558 (match_operand:DI 1 "register_operand" ""))]
2561 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2562 [(clobber (const_int 0))]
2564 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2565 gen_highpart (SImode, operands[1])));
2566 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2567 gen_lowpart (SImode, operands[1])));
2572 [(set (match_operand:DI 0 "memory_operand" "")
2577 && ! mem_min_alignment (operands[0], 8)))
2578 && offsettable_memref_p (operands[0])"
2579 [(clobber (const_int 0))]
2581 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2582 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2586 ;; Floating point move insns
2588 (define_insn "*movsf_insn_novis"
2589 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2590 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2591 "(TARGET_FPU && ! TARGET_VIS)
2592 && (register_operand (operands[0], SFmode)
2593 || register_operand (operands[1], SFmode)
2594 || fp_zero_operand (operands[1], SFmode))"
2596 if (GET_CODE (operands[1]) == CONST_DOUBLE
2597 && (which_alternative == 2
2598 || which_alternative == 3
2599 || which_alternative == 4))
2604 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2605 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2606 operands[1] = GEN_INT (i);
2609 switch (which_alternative)
2612 return "fmovs\t%1, %0";
2616 return "sethi\t%%hi(%a1), %0";
2618 return "mov\t%1, %0";
2623 return "ld\t%1, %0";
2626 return "st\t%r1, %0";
2631 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2633 (define_insn "*movsf_insn_vis"
2634 [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2635 (match_operand:V32 1 "input_operand" "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2636 "(TARGET_FPU && TARGET_VIS)
2637 && (register_operand (operands[0], <V32:MODE>mode)
2638 || register_operand (operands[1], <V32:MODE>mode)
2639 || fp_zero_operand (operands[1], <V32:MODE>mode))"
2641 if (GET_CODE (operands[1]) == CONST_DOUBLE
2642 && (which_alternative == 3
2643 || which_alternative == 4
2644 || which_alternative == 5))
2649 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2650 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2651 operands[1] = GEN_INT (i);
2654 switch (which_alternative)
2657 return "fmovs\t%1, %0";
2659 return "fzeros\t%0";
2663 return "sethi\t%%hi(%a1), %0";
2665 return "mov\t%1, %0";
2670 return "ld\t%1, %0";
2673 return "st\t%r1, %0";
2678 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2680 ;; Exactly the same as above, except that all `f' cases are deleted.
2681 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2684 (define_insn "*movsf_no_f_insn"
2685 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2686 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2688 && (register_operand (operands[0], SFmode)
2689 || register_operand (operands[1], SFmode)
2690 || fp_zero_operand (operands[1], SFmode))"
2692 if (GET_CODE (operands[1]) == CONST_DOUBLE
2693 && (which_alternative == 1
2694 || which_alternative == 2
2695 || which_alternative == 3))
2700 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2701 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2702 operands[1] = GEN_INT (i);
2705 switch (which_alternative)
2710 return "sethi\t%%hi(%a1), %0";
2712 return "mov\t%1, %0";
2716 return "ld\t%1, %0";
2718 return "st\t%r1, %0";
2723 [(set_attr "type" "*,*,*,*,load,store")])
2725 ;; The following 3 patterns build SFmode constants in integer registers.
2727 (define_insn "*movsf_lo_sum"
2728 [(set (match_operand:SF 0 "register_operand" "=r")
2729 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2730 (match_operand:SF 2 "const_double_operand" "S")))]
2731 "fp_high_losum_p (operands[2])"
2736 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2737 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2738 operands[2] = GEN_INT (i);
2739 return "or\t%1, %%lo(%a2), %0";
2742 (define_insn "*movsf_high"
2743 [(set (match_operand:SF 0 "register_operand" "=r")
2744 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2745 "fp_high_losum_p (operands[1])"
2750 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2751 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2752 operands[1] = GEN_INT (i);
2753 return "sethi\t%%hi(%1), %0";
2757 [(set (match_operand:SF 0 "register_operand" "")
2758 (match_operand:SF 1 "const_double_operand" ""))]
2759 "fp_high_losum_p (operands[1])
2760 && (GET_CODE (operands[0]) == REG
2761 && REGNO (operands[0]) < 32)"
2762 [(set (match_dup 0) (high:SF (match_dup 1)))
2763 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2765 ;; Yes, you guessed it right, the former movsf expander.
2766 (define_expand "mov<V32:mode>"
2767 [(set (match_operand:V32 0 "general_operand" "")
2768 (match_operand:V32 1 "general_operand" ""))]
2769 "<V32:MODE>mode == SFmode || TARGET_VIS"
2771 /* Force constants into memory. */
2772 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2774 /* emit_group_store will send such bogosity to us when it is
2775 not storing directly into memory. So fix this up to avoid
2776 crashes in output_constant_pool. */
2777 if (operands [1] == const0_rtx)
2778 operands[1] = CONST0_RTX (<V32:MODE>mode);
2780 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2781 && fp_zero_operand (operands[1], <V32:MODE>mode))
2784 /* We are able to build any SF constant in integer registers
2785 with at most 2 instructions. */
2786 if (REGNO (operands[0]) < 32
2787 && <V32:MODE>mode == SFmode)
2790 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2794 /* Handle sets of MEM first. */
2795 if (GET_CODE (operands[0]) == MEM)
2797 if (register_operand (operands[1], <V32:MODE>mode)
2798 || fp_zero_operand (operands[1], <V32:MODE>mode))
2801 if (! reload_in_progress)
2803 operands[0] = validize_mem (operands[0]);
2804 operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2808 /* Fixup PIC cases. */
2811 if (CONSTANT_P (operands[1])
2812 && pic_address_needs_scratch (operands[1]))
2813 operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2815 if (symbolic_operand (operands[1], <V32:MODE>mode))
2817 operands[1] = legitimize_pic_address (operands[1],
2819 (reload_in_progress ?
2829 ;; Yes, you again guessed it right, the former movdf expander.
2830 (define_expand "mov<V64:mode>"
2831 [(set (match_operand:V64 0 "general_operand" "")
2832 (match_operand:V64 1 "general_operand" ""))]
2833 "<V64:MODE>mode == DFmode || TARGET_VIS"
2835 /* Force constants into memory. */
2836 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2838 /* emit_group_store will send such bogosity to us when it is
2839 not storing directly into memory. So fix this up to avoid
2840 crashes in output_constant_pool. */
2841 if (operands [1] == const0_rtx)
2842 operands[1] = CONST0_RTX (<V64:MODE>mode);
2844 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2845 && fp_zero_operand (operands[1], <V64:MODE>mode))
2848 /* We are able to build any DF constant in integer registers. */
2849 if (REGNO (operands[0]) < 32
2850 && <V64:MODE>mode == DFmode
2851 && (reload_completed || reload_in_progress))
2854 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2858 /* Handle MEM cases first. */
2859 if (GET_CODE (operands[0]) == MEM)
2861 if (register_operand (operands[1], <V64:MODE>mode)
2862 || fp_zero_operand (operands[1], <V64:MODE>mode))
2865 if (! reload_in_progress)
2867 operands[0] = validize_mem (operands[0]);
2868 operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2872 /* Fixup PIC cases. */
2875 if (CONSTANT_P (operands[1])
2876 && pic_address_needs_scratch (operands[1]))
2877 operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2879 if (symbolic_operand (operands[1], <V64:MODE>mode))
2881 operands[1] = legitimize_pic_address (operands[1],
2883 (reload_in_progress ?
2893 ;; Be careful, fmovd does not exist when !v9.
2894 (define_insn "*movdf_insn_sp32"
2895 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2896 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2899 && (register_operand (operands[0], DFmode)
2900 || register_operand (operands[1], DFmode)
2901 || fp_zero_operand (operands[1], DFmode))"
2913 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2914 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2916 (define_insn "*movdf_no_e_insn_sp32"
2917 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2918 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2922 && (register_operand (operands[0], DFmode)
2923 || register_operand (operands[1], DFmode)
2924 || fp_zero_operand (operands[1], DFmode))"
2931 [(set_attr "type" "load,store,*,*,*")
2932 (set_attr "length" "*,*,2,2,2")])
2934 (define_insn "*movdf_no_e_insn_v9_sp32"
2935 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2936 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2940 && (register_operand (operands[0], DFmode)
2941 || register_operand (operands[1], DFmode)
2942 || fp_zero_operand (operands[1], DFmode))"
2949 [(set_attr "type" "load,store,store,*,*")
2950 (set_attr "length" "*,*,*,2,2")])
2952 ;; We have available v9 double floats but not 64-bit
2953 ;; integer registers and no VIS.
2954 (define_insn "*movdf_insn_v9only_novis"
2955 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2956 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2961 && (register_operand (operands[0], DFmode)
2962 || register_operand (operands[1], DFmode)
2963 || fp_zero_operand (operands[1], DFmode))"
2974 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2975 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2976 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2978 ;; We have available v9 double floats but not 64-bit
2979 ;; integer registers but we have VIS.
2980 (define_insn "*movdf_insn_v9only_vis"
2981 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2982 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2986 && (register_operand (operands[0], <V64:MODE>mode)
2987 || register_operand (operands[1], <V64:MODE>mode)
2988 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3000 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3001 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3002 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3004 ;; We have available both v9 double floats and 64-bit
3005 ;; integer registers. No VIS though.
3006 (define_insn "*movdf_insn_sp64_novis"
3007 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3008 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3012 && (register_operand (operands[0], DFmode)
3013 || register_operand (operands[1], DFmode)
3014 || fp_zero_operand (operands[1], DFmode))"
3023 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3024 (set_attr "length" "*,*,*,*,*,*,2")
3025 (set_attr "fptype" "double,*,*,*,*,*,*")])
3027 ;; We have available both v9 double floats and 64-bit
3028 ;; integer registers. And we have VIS.
3029 (define_insn "*movdf_insn_sp64_vis"
3030 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3031 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3035 && (register_operand (operands[0], <V64:MODE>mode)
3036 || register_operand (operands[1], <V64:MODE>mode)
3037 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3047 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3048 (set_attr "length" "*,*,*,*,*,*,*,2")
3049 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3051 (define_insn "*movdf_no_e_insn_sp64"
3052 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3053 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3056 && (register_operand (operands[0], DFmode)
3057 || register_operand (operands[1], DFmode)
3058 || fp_zero_operand (operands[1], DFmode))"
3063 [(set_attr "type" "*,load,store")])
3065 ;; This pattern build DFmode constants in integer registers.
3067 [(set (match_operand:DF 0 "register_operand" "")
3068 (match_operand:DF 1 "const_double_operand" ""))]
3070 && (GET_CODE (operands[0]) == REG
3071 && REGNO (operands[0]) < 32)
3072 && ! fp_zero_operand(operands[1], DFmode)
3073 && reload_completed"
3074 [(clobber (const_int 0))]
3079 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3080 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3081 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3085 #if HOST_BITS_PER_WIDE_INT == 64
3088 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3089 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3090 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3092 emit_insn (gen_movdi (operands[0],
3093 immed_double_const (l[1], l[0], DImode)));
3098 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3101 /* Slick... but this trick loses if this subreg constant part
3102 can be done in one insn. */
3104 && !(SPARC_SETHI32_P (l[0])
3105 || SPARC_SIMM13_P (l[0])))
3107 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3108 gen_highpart (SImode, operands[0])));
3112 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3119 ;; Ok, now the splits to handle all the multi insn and
3120 ;; mis-aligned memory address cases.
3121 ;; In these splits please take note that we must be
3122 ;; careful when V9 but not ARCH64 because the integer
3123 ;; register DFmode cases must be handled.
3125 [(set (match_operand:V64 0 "register_operand" "")
3126 (match_operand:V64 1 "register_operand" ""))]
3129 && ((GET_CODE (operands[0]) == REG
3130 && REGNO (operands[0]) < 32)
3131 || (GET_CODE (operands[0]) == SUBREG
3132 && GET_CODE (SUBREG_REG (operands[0])) == REG
3133 && REGNO (SUBREG_REG (operands[0])) < 32))))
3134 && reload_completed"
3135 [(clobber (const_int 0))]
3137 rtx set_dest = operands[0];
3138 rtx set_src = operands[1];
3141 enum machine_mode half_mode;
3143 /* We can be expanded for DFmode or integral vector modes. */
3144 if (<V64:MODE>mode == DFmode)
3149 dest1 = gen_highpart (half_mode, set_dest);
3150 dest2 = gen_lowpart (half_mode, set_dest);
3151 src1 = gen_highpart (half_mode, set_src);
3152 src2 = gen_lowpart (half_mode, set_src);
3154 /* Now emit using the real source and destination we found, swapping
3155 the order if we detect overlap. */
3156 if (reg_overlap_mentioned_p (dest1, src2))
3158 emit_move_insn_1 (dest2, src2);
3159 emit_move_insn_1 (dest1, src1);
3163 emit_move_insn_1 (dest1, src1);
3164 emit_move_insn_1 (dest2, src2);
3170 [(set (match_operand:V64 0 "register_operand" "")
3171 (match_operand:V64 1 "memory_operand" ""))]
3174 && (((REGNO (operands[0]) % 2) != 0)
3175 || ! mem_min_alignment (operands[1], 8))
3176 && offsettable_memref_p (operands[1])"
3177 [(clobber (const_int 0))]
3179 enum machine_mode half_mode;
3182 /* We can be expanded for DFmode or integral vector modes. */
3183 if (<V64:MODE>mode == DFmode)
3188 word0 = adjust_address (operands[1], half_mode, 0);
3189 word1 = adjust_address (operands[1], half_mode, 4);
3191 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3193 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3194 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3198 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3199 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3205 [(set (match_operand:V64 0 "memory_operand" "")
3206 (match_operand:V64 1 "register_operand" ""))]
3209 && (((REGNO (operands[1]) % 2) != 0)
3210 || ! mem_min_alignment (operands[0], 8))
3211 && offsettable_memref_p (operands[0])"
3212 [(clobber (const_int 0))]
3214 enum machine_mode half_mode;
3217 /* We can be expanded for DFmode or integral vector modes. */
3218 if (<V64:MODE>mode == DFmode)
3223 word0 = adjust_address (operands[0], half_mode, 0);
3224 word1 = adjust_address (operands[0], half_mode, 4);
3226 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3227 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3232 [(set (match_operand:V64 0 "memory_operand" "")
3233 (match_operand:V64 1 "fp_zero_operand" ""))]
3237 && ! mem_min_alignment (operands[0], 8)))
3238 && offsettable_memref_p (operands[0])"
3239 [(clobber (const_int 0))]
3241 enum machine_mode half_mode;
3244 /* We can be expanded for DFmode or integral vector modes. */
3245 if (<V64:MODE>mode == DFmode)
3250 dest1 = adjust_address (operands[0], half_mode, 0);
3251 dest2 = adjust_address (operands[0], half_mode, 4);
3253 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3254 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3259 [(set (match_operand:V64 0 "register_operand" "")
3260 (match_operand:V64 1 "fp_zero_operand" ""))]
3263 && ((GET_CODE (operands[0]) == REG
3264 && REGNO (operands[0]) < 32)
3265 || (GET_CODE (operands[0]) == SUBREG
3266 && GET_CODE (SUBREG_REG (operands[0])) == REG
3267 && REGNO (SUBREG_REG (operands[0])) < 32))"
3268 [(clobber (const_int 0))]
3270 enum machine_mode half_mode;
3271 rtx set_dest = operands[0];
3274 /* We can be expanded for DFmode or integral vector modes. */
3275 if (<V64:MODE>mode == DFmode)
3280 dest1 = gen_highpart (half_mode, set_dest);
3281 dest2 = gen_lowpart (half_mode, set_dest);
3282 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3283 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3287 (define_expand "movtf"
3288 [(set (match_operand:TF 0 "general_operand" "")
3289 (match_operand:TF 1 "general_operand" ""))]
3292 /* Force TFmode constants into memory. */
3293 if (GET_CODE (operands[0]) == REG
3294 && CONSTANT_P (operands[1]))
3296 /* emit_group_store will send such bogosity to us when it is
3297 not storing directly into memory. So fix this up to avoid
3298 crashes in output_constant_pool. */
3299 if (operands [1] == const0_rtx)
3300 operands[1] = CONST0_RTX (TFmode);
3302 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3305 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3309 /* Handle MEM cases first, note that only v9 guarantees
3310 full 16-byte alignment for quads. */
3311 if (GET_CODE (operands[0]) == MEM)
3313 if (register_operand (operands[1], TFmode)
3314 || fp_zero_operand (operands[1], TFmode))
3317 if (! reload_in_progress)
3319 operands[0] = validize_mem (operands[0]);
3320 operands[1] = force_reg (TFmode, operands[1]);
3324 /* Fixup PIC cases. */
3327 if (CONSTANT_P (operands[1])
3328 && pic_address_needs_scratch (operands[1]))
3329 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3331 if (symbolic_operand (operands[1], TFmode))
3333 operands[1] = legitimize_pic_address (operands[1],
3335 (reload_in_progress ?
3345 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3346 ;; we must split them all. :-(
3347 (define_insn "*movtf_insn_sp32"
3348 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3349 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3353 && (register_operand (operands[0], TFmode)
3354 || register_operand (operands[1], TFmode)
3355 || fp_zero_operand (operands[1], TFmode))"
3357 [(set_attr "length" "4")])
3359 (define_insn "*movtf_insn_vis_sp32"
3360 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3361 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3365 && (register_operand (operands[0], TFmode)
3366 || register_operand (operands[1], TFmode)
3367 || fp_zero_operand (operands[1], TFmode))"
3369 [(set_attr "length" "4")])
3371 ;; Exactly the same as above, except that all `e' cases are deleted.
3372 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3375 (define_insn "*movtf_no_e_insn_sp32"
3376 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3377 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3380 && (register_operand (operands[0], TFmode)
3381 || register_operand (operands[1], TFmode)
3382 || fp_zero_operand (operands[1], TFmode))"
3384 [(set_attr "length" "4")])
3386 ;; Now handle the float reg cases directly when arch64,
3387 ;; hard_quad, and proper reg number alignment are all true.
3388 (define_insn "*movtf_insn_hq_sp64"
3389 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3390 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3395 && (register_operand (operands[0], TFmode)
3396 || register_operand (operands[1], TFmode)
3397 || fp_zero_operand (operands[1], TFmode))"
3404 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3405 (set_attr "length" "*,*,*,2,2")])
3407 (define_insn "*movtf_insn_hq_vis_sp64"
3408 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3409 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3414 && (register_operand (operands[0], TFmode)
3415 || register_operand (operands[1], TFmode)
3416 || fp_zero_operand (operands[1], TFmode))"
3424 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3425 (set_attr "length" "*,*,*,2,2,2")])
3427 ;; Now we allow the integer register cases even when
3428 ;; only arch64 is true.
3429 (define_insn "*movtf_insn_sp64"
3430 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3431 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3435 && ! TARGET_HARD_QUAD
3436 && (register_operand (operands[0], TFmode)
3437 || register_operand (operands[1], TFmode)
3438 || fp_zero_operand (operands[1], TFmode))"
3440 [(set_attr "length" "2")])
3442 (define_insn "*movtf_insn_vis_sp64"
3443 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3444 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3448 && ! TARGET_HARD_QUAD
3449 && (register_operand (operands[0], TFmode)
3450 || register_operand (operands[1], TFmode)
3451 || fp_zero_operand (operands[1], TFmode))"
3453 [(set_attr "length" "2")])
3455 (define_insn "*movtf_no_e_insn_sp64"
3456 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3457 (match_operand:TF 1 "input_operand" "orG,rG"))]
3460 && (register_operand (operands[0], TFmode)
3461 || register_operand (operands[1], TFmode)
3462 || fp_zero_operand (operands[1], TFmode))"
3464 [(set_attr "length" "2")])
3466 ;; Now all the splits to handle multi-insn TF mode moves.
3468 [(set (match_operand:TF 0 "register_operand" "")
3469 (match_operand:TF 1 "register_operand" ""))]
3473 && ! TARGET_HARD_QUAD)
3474 || ! fp_register_operand (operands[0], TFmode))"
3475 [(clobber (const_int 0))]
3477 rtx set_dest = operands[0];
3478 rtx set_src = operands[1];
3482 dest1 = gen_df_reg (set_dest, 0);
3483 dest2 = gen_df_reg (set_dest, 1);
3484 src1 = gen_df_reg (set_src, 0);
3485 src2 = gen_df_reg (set_src, 1);
3487 /* Now emit using the real source and destination we found, swapping
3488 the order if we detect overlap. */
3489 if (reg_overlap_mentioned_p (dest1, src2))
3491 emit_insn (gen_movdf (dest2, src2));
3492 emit_insn (gen_movdf (dest1, src1));
3496 emit_insn (gen_movdf (dest1, src1));
3497 emit_insn (gen_movdf (dest2, src2));
3503 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3504 (match_operand:TF 1 "fp_zero_operand" ""))]
3506 [(clobber (const_int 0))]
3508 rtx set_dest = operands[0];
3511 switch (GET_CODE (set_dest))
3514 dest1 = gen_df_reg (set_dest, 0);
3515 dest2 = gen_df_reg (set_dest, 1);
3518 dest1 = adjust_address (set_dest, DFmode, 0);
3519 dest2 = adjust_address (set_dest, DFmode, 8);
3525 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3526 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3531 [(set (match_operand:TF 0 "register_operand" "")
3532 (match_operand:TF 1 "memory_operand" ""))]
3534 && offsettable_memref_p (operands[1])
3536 || ! TARGET_HARD_QUAD
3537 || ! fp_register_operand (operands[0], TFmode)))"
3538 [(clobber (const_int 0))]
3540 rtx word0 = adjust_address (operands[1], DFmode, 0);
3541 rtx word1 = adjust_address (operands[1], DFmode, 8);
3542 rtx set_dest, dest1, dest2;
3544 set_dest = operands[0];
3546 dest1 = gen_df_reg (set_dest, 0);
3547 dest2 = gen_df_reg (set_dest, 1);
3549 /* Now output, ordering such that we don't clobber any registers
3550 mentioned in the address. */
3551 if (reg_overlap_mentioned_p (dest1, word1))
3554 emit_insn (gen_movdf (dest2, word1));
3555 emit_insn (gen_movdf (dest1, word0));
3559 emit_insn (gen_movdf (dest1, word0));
3560 emit_insn (gen_movdf (dest2, word1));
3566 [(set (match_operand:TF 0 "memory_operand" "")
3567 (match_operand:TF 1 "register_operand" ""))]
3569 && offsettable_memref_p (operands[0])
3571 || ! TARGET_HARD_QUAD
3572 || ! fp_register_operand (operands[1], TFmode)))"
3573 [(clobber (const_int 0))]
3575 rtx set_src = operands[1];
3577 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3578 gen_df_reg (set_src, 0)));
3579 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3580 gen_df_reg (set_src, 1)));
3584 ;; SPARC V9 conditional move instructions.
3586 ;; We can handle larger constants here for some flavors, but for now we keep
3587 ;; it simple and only allow those constants supported by all flavors.
3588 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3589 ;; 3 contains the constant if one is present, but we handle either for
3590 ;; generality (sparc.c puts a constant in operand 2).
3592 (define_expand "movqicc"
3593 [(set (match_operand:QI 0 "register_operand" "")
3594 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3595 (match_operand:QI 2 "arith10_operand" "")
3596 (match_operand:QI 3 "arith10_operand" "")))]
3599 enum rtx_code code = GET_CODE (operands[1]);
3601 if (GET_MODE (sparc_compare_op0) == DImode
3605 if (sparc_compare_op1 == const0_rtx
3606 && GET_CODE (sparc_compare_op0) == REG
3607 && GET_MODE (sparc_compare_op0) == DImode
3608 && v9_regcmp_p (code))
3610 operands[1] = gen_rtx_fmt_ee (code, DImode,
3611 sparc_compare_op0, sparc_compare_op1);
3615 rtx cc_reg = gen_compare_reg (code,
3616 sparc_compare_op0, sparc_compare_op1);
3617 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3621 (define_expand "movhicc"
3622 [(set (match_operand:HI 0 "register_operand" "")
3623 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3624 (match_operand:HI 2 "arith10_operand" "")
3625 (match_operand:HI 3 "arith10_operand" "")))]
3628 enum rtx_code code = GET_CODE (operands[1]);
3630 if (GET_MODE (sparc_compare_op0) == DImode
3634 if (sparc_compare_op1 == const0_rtx
3635 && GET_CODE (sparc_compare_op0) == REG
3636 && GET_MODE (sparc_compare_op0) == DImode
3637 && v9_regcmp_p (code))
3639 operands[1] = gen_rtx_fmt_ee (code, DImode,
3640 sparc_compare_op0, sparc_compare_op1);
3644 rtx cc_reg = gen_compare_reg (code,
3645 sparc_compare_op0, sparc_compare_op1);
3646 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3650 (define_expand "movsicc"
3651 [(set (match_operand:SI 0 "register_operand" "")
3652 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3653 (match_operand:SI 2 "arith10_operand" "")
3654 (match_operand:SI 3 "arith10_operand" "")))]
3657 enum rtx_code code = GET_CODE (operands[1]);
3658 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3660 if (sparc_compare_op1 == const0_rtx
3661 && GET_CODE (sparc_compare_op0) == REG
3662 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3664 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3665 sparc_compare_op0, sparc_compare_op1);
3669 rtx cc_reg = gen_compare_reg (code,
3670 sparc_compare_op0, sparc_compare_op1);
3671 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3672 cc_reg, const0_rtx);
3676 (define_expand "movdicc"
3677 [(set (match_operand:DI 0 "register_operand" "")
3678 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3679 (match_operand:DI 2 "arith10_double_operand" "")
3680 (match_operand:DI 3 "arith10_double_operand" "")))]
3683 enum rtx_code code = GET_CODE (operands[1]);
3685 if (sparc_compare_op1 == const0_rtx
3686 && GET_CODE (sparc_compare_op0) == REG
3687 && GET_MODE (sparc_compare_op0) == DImode
3688 && v9_regcmp_p (code))
3690 operands[1] = gen_rtx_fmt_ee (code, DImode,
3691 sparc_compare_op0, sparc_compare_op1);
3695 rtx cc_reg = gen_compare_reg (code,
3696 sparc_compare_op0, sparc_compare_op1);
3697 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3698 cc_reg, const0_rtx);
3702 (define_expand "movsfcc"
3703 [(set (match_operand:SF 0 "register_operand" "")
3704 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3705 (match_operand:SF 2 "register_operand" "")
3706 (match_operand:SF 3 "register_operand" "")))]
3707 "TARGET_V9 && TARGET_FPU"
3709 enum rtx_code code = GET_CODE (operands[1]);
3711 if (GET_MODE (sparc_compare_op0) == DImode
3715 if (sparc_compare_op1 == const0_rtx
3716 && GET_CODE (sparc_compare_op0) == REG
3717 && GET_MODE (sparc_compare_op0) == DImode
3718 && v9_regcmp_p (code))
3720 operands[1] = gen_rtx_fmt_ee (code, DImode,
3721 sparc_compare_op0, sparc_compare_op1);
3725 rtx cc_reg = gen_compare_reg (code,
3726 sparc_compare_op0, sparc_compare_op1);
3727 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3731 (define_expand "movdfcc"
3732 [(set (match_operand:DF 0 "register_operand" "")
3733 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3734 (match_operand:DF 2 "register_operand" "")
3735 (match_operand:DF 3 "register_operand" "")))]
3736 "TARGET_V9 && TARGET_FPU"
3738 enum rtx_code code = GET_CODE (operands[1]);
3740 if (GET_MODE (sparc_compare_op0) == DImode
3744 if (sparc_compare_op1 == const0_rtx
3745 && GET_CODE (sparc_compare_op0) == REG
3746 && GET_MODE (sparc_compare_op0) == DImode
3747 && v9_regcmp_p (code))
3749 operands[1] = gen_rtx_fmt_ee (code, DImode,
3750 sparc_compare_op0, sparc_compare_op1);
3754 rtx cc_reg = gen_compare_reg (code,
3755 sparc_compare_op0, sparc_compare_op1);
3756 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3760 (define_expand "movtfcc"
3761 [(set (match_operand:TF 0 "register_operand" "")
3762 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3763 (match_operand:TF 2 "register_operand" "")
3764 (match_operand:TF 3 "register_operand" "")))]
3765 "TARGET_V9 && TARGET_FPU"
3767 enum rtx_code code = GET_CODE (operands[1]);
3769 if (GET_MODE (sparc_compare_op0) == DImode
3773 if (sparc_compare_op1 == const0_rtx
3774 && GET_CODE (sparc_compare_op0) == REG
3775 && GET_MODE (sparc_compare_op0) == DImode
3776 && v9_regcmp_p (code))
3778 operands[1] = gen_rtx_fmt_ee (code, DImode,
3779 sparc_compare_op0, sparc_compare_op1);
3783 rtx cc_reg = gen_compare_reg (code,
3784 sparc_compare_op0, sparc_compare_op1);
3785 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3789 ;; Conditional move define_insns.
3791 (define_insn "*movqi_cc_sp64"
3792 [(set (match_operand:QI 0 "register_operand" "=r,r")
3793 (if_then_else:QI (match_operator 1 "comparison_operator"
3794 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3796 (match_operand:QI 3 "arith11_operand" "rL,0")
3797 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3801 mov%c1\t%x2, %4, %0"
3802 [(set_attr "type" "cmove")])
3804 (define_insn "*movhi_cc_sp64"
3805 [(set (match_operand:HI 0 "register_operand" "=r,r")
3806 (if_then_else:HI (match_operator 1 "comparison_operator"
3807 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809 (match_operand:HI 3 "arith11_operand" "rL,0")
3810 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3814 mov%c1\t%x2, %4, %0"
3815 [(set_attr "type" "cmove")])
3817 (define_insn "*movsi_cc_sp64"
3818 [(set (match_operand:SI 0 "register_operand" "=r,r")
3819 (if_then_else:SI (match_operator 1 "comparison_operator"
3820 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3822 (match_operand:SI 3 "arith11_operand" "rL,0")
3823 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3827 mov%c1\t%x2, %4, %0"
3828 [(set_attr "type" "cmove")])
3830 ;; ??? The constraints of operands 3,4 need work.
3831 (define_insn "*movdi_cc_sp64"
3832 [(set (match_operand:DI 0 "register_operand" "=r,r")
3833 (if_then_else:DI (match_operator 1 "comparison_operator"
3834 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3836 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3837 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3841 mov%c1\t%x2, %4, %0"
3842 [(set_attr "type" "cmove")])
3844 (define_insn "*movdi_cc_sp64_trunc"
3845 [(set (match_operand:SI 0 "register_operand" "=r,r")
3846 (if_then_else:SI (match_operator 1 "comparison_operator"
3847 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3849 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3850 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3854 mov%c1\t%x2, %4, %0"
3855 [(set_attr "type" "cmove")])
3857 (define_insn "*movsf_cc_sp64"
3858 [(set (match_operand:SF 0 "register_operand" "=f,f")
3859 (if_then_else:SF (match_operator 1 "comparison_operator"
3860 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3862 (match_operand:SF 3 "register_operand" "f,0")
3863 (match_operand:SF 4 "register_operand" "0,f")))]
3864 "TARGET_V9 && TARGET_FPU"
3866 fmovs%C1\t%x2, %3, %0
3867 fmovs%c1\t%x2, %4, %0"
3868 [(set_attr "type" "fpcmove")])
3870 (define_insn "movdf_cc_sp64"
3871 [(set (match_operand:DF 0 "register_operand" "=e,e")
3872 (if_then_else:DF (match_operator 1 "comparison_operator"
3873 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3875 (match_operand:DF 3 "register_operand" "e,0")
3876 (match_operand:DF 4 "register_operand" "0,e")))]
3877 "TARGET_V9 && TARGET_FPU"
3879 fmovd%C1\t%x2, %3, %0
3880 fmovd%c1\t%x2, %4, %0"
3881 [(set_attr "type" "fpcmove")
3882 (set_attr "fptype" "double")])
3884 (define_insn "*movtf_cc_hq_sp64"
3885 [(set (match_operand:TF 0 "register_operand" "=e,e")
3886 (if_then_else:TF (match_operator 1 "comparison_operator"
3887 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3889 (match_operand:TF 3 "register_operand" "e,0")
3890 (match_operand:TF 4 "register_operand" "0,e")))]
3891 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3893 fmovq%C1\t%x2, %3, %0
3894 fmovq%c1\t%x2, %4, %0"
3895 [(set_attr "type" "fpcmove")])
3897 (define_insn_and_split "*movtf_cc_sp64"
3898 [(set (match_operand:TF 0 "register_operand" "=e,e")
3899 (if_then_else:TF (match_operator 1 "comparison_operator"
3900 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3902 (match_operand:TF 3 "register_operand" "e,0")
3903 (match_operand:TF 4 "register_operand" "0,e")))]
3904 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3906 "&& reload_completed"
3907 [(clobber (const_int 0))]
3909 rtx set_dest = operands[0];
3910 rtx set_srca = operands[3];
3911 rtx set_srcb = operands[4];
3912 int third = rtx_equal_p (set_dest, set_srca);
3914 rtx srca1, srca2, srcb1, srcb2;
3916 dest1 = gen_df_reg (set_dest, 0);
3917 dest2 = gen_df_reg (set_dest, 1);
3918 srca1 = gen_df_reg (set_srca, 0);
3919 srca2 = gen_df_reg (set_srca, 1);
3920 srcb1 = gen_df_reg (set_srcb, 0);
3921 srcb2 = gen_df_reg (set_srcb, 1);
3923 /* Now emit using the real source and destination we found, swapping
3924 the order if we detect overlap. */
3925 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3926 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3928 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3929 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3933 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3934 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3938 [(set_attr "length" "2")])
3940 (define_insn "*movqi_cc_reg_sp64"
3941 [(set (match_operand:QI 0 "register_operand" "=r,r")
3942 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3943 [(match_operand:DI 2 "register_operand" "r,r")
3945 (match_operand:QI 3 "arith10_operand" "rM,0")
3946 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3949 movr%D1\t%2, %r3, %0
3950 movr%d1\t%2, %r4, %0"
3951 [(set_attr "type" "cmove")])
3953 (define_insn "*movhi_cc_reg_sp64"
3954 [(set (match_operand:HI 0 "register_operand" "=r,r")
3955 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3956 [(match_operand:DI 2 "register_operand" "r,r")
3958 (match_operand:HI 3 "arith10_operand" "rM,0")
3959 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3962 movr%D1\t%2, %r3, %0
3963 movr%d1\t%2, %r4, %0"
3964 [(set_attr "type" "cmove")])
3966 (define_insn "*movsi_cc_reg_sp64"
3967 [(set (match_operand:SI 0 "register_operand" "=r,r")
3968 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3969 [(match_operand:DI 2 "register_operand" "r,r")
3971 (match_operand:SI 3 "arith10_operand" "rM,0")
3972 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3975 movr%D1\t%2, %r3, %0
3976 movr%d1\t%2, %r4, %0"
3977 [(set_attr "type" "cmove")])
3979 ;; ??? The constraints of operands 3,4 need work.
3980 (define_insn "*movdi_cc_reg_sp64"
3981 [(set (match_operand:DI 0 "register_operand" "=r,r")
3982 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3983 [(match_operand:DI 2 "register_operand" "r,r")
3985 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3986 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3989 movr%D1\t%2, %r3, %0
3990 movr%d1\t%2, %r4, %0"
3991 [(set_attr "type" "cmove")])
3993 (define_insn "*movdi_cc_reg_sp64_trunc"
3994 [(set (match_operand:SI 0 "register_operand" "=r,r")
3995 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3996 [(match_operand:DI 2 "register_operand" "r,r")
3998 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3999 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4002 movr%D1\t%2, %r3, %0
4003 movr%d1\t%2, %r4, %0"
4004 [(set_attr "type" "cmove")])
4006 (define_insn "*movsf_cc_reg_sp64"
4007 [(set (match_operand:SF 0 "register_operand" "=f,f")
4008 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4009 [(match_operand:DI 2 "register_operand" "r,r")
4011 (match_operand:SF 3 "register_operand" "f,0")
4012 (match_operand:SF 4 "register_operand" "0,f")))]
4013 "TARGET_ARCH64 && TARGET_FPU"
4015 fmovrs%D1\t%2, %3, %0
4016 fmovrs%d1\t%2, %4, %0"
4017 [(set_attr "type" "fpcrmove")])
4019 (define_insn "movdf_cc_reg_sp64"
4020 [(set (match_operand:DF 0 "register_operand" "=e,e")
4021 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4022 [(match_operand:DI 2 "register_operand" "r,r")
4024 (match_operand:DF 3 "register_operand" "e,0")
4025 (match_operand:DF 4 "register_operand" "0,e")))]
4026 "TARGET_ARCH64 && TARGET_FPU"
4028 fmovrd%D1\t%2, %3, %0
4029 fmovrd%d1\t%2, %4, %0"
4030 [(set_attr "type" "fpcrmove")
4031 (set_attr "fptype" "double")])
4033 (define_insn "*movtf_cc_reg_hq_sp64"
4034 [(set (match_operand:TF 0 "register_operand" "=e,e")
4035 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4036 [(match_operand:DI 2 "register_operand" "r,r")
4038 (match_operand:TF 3 "register_operand" "e,0")
4039 (match_operand:TF 4 "register_operand" "0,e")))]
4040 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4042 fmovrq%D1\t%2, %3, %0
4043 fmovrq%d1\t%2, %4, %0"
4044 [(set_attr "type" "fpcrmove")])
4046 (define_insn_and_split "*movtf_cc_reg_sp64"
4047 [(set (match_operand:TF 0 "register_operand" "=e,e")
4048 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4049 [(match_operand:DI 2 "register_operand" "r,r")
4051 (match_operand:TF 3 "register_operand" "e,0")
4052 (match_operand:TF 4 "register_operand" "0,e")))]
4053 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4055 "&& reload_completed"
4056 [(clobber (const_int 0))]
4058 rtx set_dest = operands[0];
4059 rtx set_srca = operands[3];
4060 rtx set_srcb = operands[4];
4061 int third = rtx_equal_p (set_dest, set_srca);
4063 rtx srca1, srca2, srcb1, srcb2;
4065 dest1 = gen_df_reg (set_dest, 0);
4066 dest2 = gen_df_reg (set_dest, 1);
4067 srca1 = gen_df_reg (set_srca, 0);
4068 srca2 = gen_df_reg (set_srca, 1);
4069 srcb1 = gen_df_reg (set_srcb, 0);
4070 srcb2 = gen_df_reg (set_srcb, 1);
4072 /* Now emit using the real source and destination we found, swapping
4073 the order if we detect overlap. */
4074 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4075 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4077 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4078 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4082 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4083 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4087 [(set_attr "length" "2")])
4090 ;;- zero extension instructions
4092 ;; These patterns originally accepted general_operands, however, slightly
4093 ;; better code is generated by only accepting register_operands, and then
4094 ;; letting combine generate the ldu[hb] insns.
4096 (define_expand "zero_extendhisi2"
4097 [(set (match_operand:SI 0 "register_operand" "")
4098 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4101 rtx temp = gen_reg_rtx (SImode);
4102 rtx shift_16 = GEN_INT (16);
4103 int op1_subbyte = 0;
4105 if (GET_CODE (operand1) == SUBREG)
4107 op1_subbyte = SUBREG_BYTE (operand1);
4108 op1_subbyte /= GET_MODE_SIZE (SImode);
4109 op1_subbyte *= GET_MODE_SIZE (SImode);
4110 operand1 = XEXP (operand1, 0);
4113 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4115 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4119 (define_insn "*zero_extendhisi2_insn"
4120 [(set (match_operand:SI 0 "register_operand" "=r")
4121 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4124 [(set_attr "type" "load")
4125 (set_attr "us3load_type" "3cycle")])
4127 (define_expand "zero_extendqihi2"
4128 [(set (match_operand:HI 0 "register_operand" "")
4129 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4133 (define_insn "*zero_extendqihi2_insn"
4134 [(set (match_operand:HI 0 "register_operand" "=r,r")
4135 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4136 "GET_CODE (operands[1]) != CONST_INT"
4140 [(set_attr "type" "*,load")
4141 (set_attr "us3load_type" "*,3cycle")])
4143 (define_expand "zero_extendqisi2"
4144 [(set (match_operand:SI 0 "register_operand" "")
4145 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4149 (define_insn "*zero_extendqisi2_insn"
4150 [(set (match_operand:SI 0 "register_operand" "=r,r")
4151 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4152 "GET_CODE (operands[1]) != CONST_INT"
4156 [(set_attr "type" "*,load")
4157 (set_attr "us3load_type" "*,3cycle")])
4159 (define_expand "zero_extendqidi2"
4160 [(set (match_operand:DI 0 "register_operand" "")
4161 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4165 (define_insn "*zero_extendqidi2_insn"
4166 [(set (match_operand:DI 0 "register_operand" "=r,r")
4167 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4168 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4172 [(set_attr "type" "*,load")
4173 (set_attr "us3load_type" "*,3cycle")])
4175 (define_expand "zero_extendhidi2"
4176 [(set (match_operand:DI 0 "register_operand" "")
4177 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4180 rtx temp = gen_reg_rtx (DImode);
4181 rtx shift_48 = GEN_INT (48);
4182 int op1_subbyte = 0;
4184 if (GET_CODE (operand1) == SUBREG)
4186 op1_subbyte = SUBREG_BYTE (operand1);
4187 op1_subbyte /= GET_MODE_SIZE (DImode);
4188 op1_subbyte *= GET_MODE_SIZE (DImode);
4189 operand1 = XEXP (operand1, 0);
4192 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4194 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4198 (define_insn "*zero_extendhidi2_insn"
4199 [(set (match_operand:DI 0 "register_operand" "=r")
4200 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4203 [(set_attr "type" "load")
4204 (set_attr "us3load_type" "3cycle")])
4207 ;; ??? Write truncdisi pattern using sra?
4209 (define_expand "zero_extendsidi2"
4210 [(set (match_operand:DI 0 "register_operand" "")
4211 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4215 (define_insn "*zero_extendsidi2_insn_sp64"
4216 [(set (match_operand:DI 0 "register_operand" "=r,r")
4217 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4218 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4222 [(set_attr "type" "shift,load")])
4224 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4225 [(set (match_operand:DI 0 "register_operand" "=r")
4226 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4229 "&& reload_completed"
4230 [(set (match_dup 2) (match_dup 3))
4231 (set (match_dup 4) (match_dup 5))]
4235 dest1 = gen_highpart (SImode, operands[0]);
4236 dest2 = gen_lowpart (SImode, operands[0]);
4238 /* Swap the order in case of overlap. */
4239 if (REGNO (dest1) == REGNO (operands[1]))
4241 operands[2] = dest2;
4242 operands[3] = operands[1];
4243 operands[4] = dest1;
4244 operands[5] = const0_rtx;
4248 operands[2] = dest1;
4249 operands[3] = const0_rtx;
4250 operands[4] = dest2;
4251 operands[5] = operands[1];
4254 [(set_attr "length" "2")])
4256 ;; Simplify comparisons of extended values.
4258 (define_insn "*cmp_zero_extendqisi2"
4260 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4263 "andcc\t%0, 0xff, %%g0"
4264 [(set_attr "type" "compare")])
4266 (define_insn "*cmp_zero_qi"
4268 (compare:CC (match_operand:QI 0 "register_operand" "r")
4271 "andcc\t%0, 0xff, %%g0"
4272 [(set_attr "type" "compare")])
4274 (define_insn "*cmp_zero_extendqisi2_set"
4276 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4278 (set (match_operand:SI 0 "register_operand" "=r")
4279 (zero_extend:SI (match_dup 1)))]
4281 "andcc\t%1, 0xff, %0"
4282 [(set_attr "type" "compare")])
4284 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4286 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4289 (set (match_operand:SI 0 "register_operand" "=r")
4290 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4292 "andcc\t%1, 0xff, %0"
4293 [(set_attr "type" "compare")])
4295 (define_insn "*cmp_zero_extendqidi2"
4297 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4300 "andcc\t%0, 0xff, %%g0"
4301 [(set_attr "type" "compare")])
4303 (define_insn "*cmp_zero_qi_sp64"
4305 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4308 "andcc\t%0, 0xff, %%g0"
4309 [(set_attr "type" "compare")])
4311 (define_insn "*cmp_zero_extendqidi2_set"
4313 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4315 (set (match_operand:DI 0 "register_operand" "=r")
4316 (zero_extend:DI (match_dup 1)))]
4318 "andcc\t%1, 0xff, %0"
4319 [(set_attr "type" "compare")])
4321 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4323 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4326 (set (match_operand:DI 0 "register_operand" "=r")
4327 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4329 "andcc\t%1, 0xff, %0"
4330 [(set_attr "type" "compare")])
4332 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4334 (define_insn "*cmp_siqi_trunc"
4336 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4339 "andcc\t%0, 0xff, %%g0"
4340 [(set_attr "type" "compare")])
4342 (define_insn "*cmp_siqi_trunc_set"
4344 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4346 (set (match_operand:QI 0 "register_operand" "=r")
4347 (subreg:QI (match_dup 1) 3))]
4349 "andcc\t%1, 0xff, %0"
4350 [(set_attr "type" "compare")])
4352 (define_insn "*cmp_diqi_trunc"
4354 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4357 "andcc\t%0, 0xff, %%g0"
4358 [(set_attr "type" "compare")])
4360 (define_insn "*cmp_diqi_trunc_set"
4362 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4364 (set (match_operand:QI 0 "register_operand" "=r")
4365 (subreg:QI (match_dup 1) 7))]
4367 "andcc\t%1, 0xff, %0"
4368 [(set_attr "type" "compare")])
4370 ;;- sign extension instructions
4372 ;; These patterns originally accepted general_operands, however, slightly
4373 ;; better code is generated by only accepting register_operands, and then
4374 ;; letting combine generate the lds[hb] insns.
4376 (define_expand "extendhisi2"
4377 [(set (match_operand:SI 0 "register_operand" "")
4378 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4381 rtx temp = gen_reg_rtx (SImode);
4382 rtx shift_16 = GEN_INT (16);
4383 int op1_subbyte = 0;
4385 if (GET_CODE (operand1) == SUBREG)
4387 op1_subbyte = SUBREG_BYTE (operand1);
4388 op1_subbyte /= GET_MODE_SIZE (SImode);
4389 op1_subbyte *= GET_MODE_SIZE (SImode);
4390 operand1 = XEXP (operand1, 0);
4393 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4395 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4399 (define_insn "*sign_extendhisi2_insn"
4400 [(set (match_operand:SI 0 "register_operand" "=r")
4401 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4404 [(set_attr "type" "sload")
4405 (set_attr "us3load_type" "3cycle")])
4407 (define_expand "extendqihi2"
4408 [(set (match_operand:HI 0 "register_operand" "")
4409 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4412 rtx temp = gen_reg_rtx (SImode);
4413 rtx shift_24 = GEN_INT (24);
4414 int op1_subbyte = 0;
4415 int op0_subbyte = 0;
4417 if (GET_CODE (operand1) == SUBREG)
4419 op1_subbyte = SUBREG_BYTE (operand1);
4420 op1_subbyte /= GET_MODE_SIZE (SImode);
4421 op1_subbyte *= GET_MODE_SIZE (SImode);
4422 operand1 = XEXP (operand1, 0);
4424 if (GET_CODE (operand0) == SUBREG)
4426 op0_subbyte = SUBREG_BYTE (operand0);
4427 op0_subbyte /= GET_MODE_SIZE (SImode);
4428 op0_subbyte *= GET_MODE_SIZE (SImode);
4429 operand0 = XEXP (operand0, 0);
4431 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4433 if (GET_MODE (operand0) != SImode)
4434 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4435 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4439 (define_insn "*sign_extendqihi2_insn"
4440 [(set (match_operand:HI 0 "register_operand" "=r")
4441 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4444 [(set_attr "type" "sload")
4445 (set_attr "us3load_type" "3cycle")])
4447 (define_expand "extendqisi2"
4448 [(set (match_operand:SI 0 "register_operand" "")
4449 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4452 rtx temp = gen_reg_rtx (SImode);
4453 rtx shift_24 = GEN_INT (24);
4454 int op1_subbyte = 0;
4456 if (GET_CODE (operand1) == SUBREG)
4458 op1_subbyte = SUBREG_BYTE (operand1);
4459 op1_subbyte /= GET_MODE_SIZE (SImode);
4460 op1_subbyte *= GET_MODE_SIZE (SImode);
4461 operand1 = XEXP (operand1, 0);
4464 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4466 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4470 (define_insn "*sign_extendqisi2_insn"
4471 [(set (match_operand:SI 0 "register_operand" "=r")
4472 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4475 [(set_attr "type" "sload")
4476 (set_attr "us3load_type" "3cycle")])
4478 (define_expand "extendqidi2"
4479 [(set (match_operand:DI 0 "register_operand" "")
4480 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4483 rtx temp = gen_reg_rtx (DImode);
4484 rtx shift_56 = GEN_INT (56);
4485 int op1_subbyte = 0;
4487 if (GET_CODE (operand1) == SUBREG)
4489 op1_subbyte = SUBREG_BYTE (operand1);
4490 op1_subbyte /= GET_MODE_SIZE (DImode);
4491 op1_subbyte *= GET_MODE_SIZE (DImode);
4492 operand1 = XEXP (operand1, 0);
4495 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4497 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4501 (define_insn "*sign_extendqidi2_insn"
4502 [(set (match_operand:DI 0 "register_operand" "=r")
4503 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4506 [(set_attr "type" "sload")
4507 (set_attr "us3load_type" "3cycle")])
4509 (define_expand "extendhidi2"
4510 [(set (match_operand:DI 0 "register_operand" "")
4511 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4514 rtx temp = gen_reg_rtx (DImode);
4515 rtx shift_48 = GEN_INT (48);
4516 int op1_subbyte = 0;
4518 if (GET_CODE (operand1) == SUBREG)
4520 op1_subbyte = SUBREG_BYTE (operand1);
4521 op1_subbyte /= GET_MODE_SIZE (DImode);
4522 op1_subbyte *= GET_MODE_SIZE (DImode);
4523 operand1 = XEXP (operand1, 0);
4526 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4528 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4532 (define_insn "*sign_extendhidi2_insn"
4533 [(set (match_operand:DI 0 "register_operand" "=r")
4534 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4537 [(set_attr "type" "sload")
4538 (set_attr "us3load_type" "3cycle")])
4540 (define_expand "extendsidi2"
4541 [(set (match_operand:DI 0 "register_operand" "")
4542 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4546 (define_insn "*sign_extendsidi2_insn"
4547 [(set (match_operand:DI 0 "register_operand" "=r,r")
4548 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4553 [(set_attr "type" "shift,sload")
4554 (set_attr "us3load_type" "*,3cycle")])
4556 ;; Special pattern for optimizing bit-field compares. This is needed
4557 ;; because combine uses this as a canonical form.
4559 (define_insn "*cmp_zero_extract"
4562 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4563 (match_operand:SI 1 "small_int_or_double" "n")
4564 (match_operand:SI 2 "small_int_or_double" "n"))
4566 "(GET_CODE (operands[2]) == CONST_INT
4567 && INTVAL (operands[2]) > 19)
4568 || (GET_CODE (operands[2]) == CONST_DOUBLE
4569 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4571 int len = (GET_CODE (operands[1]) == CONST_INT
4572 ? INTVAL (operands[1])
4573 : CONST_DOUBLE_LOW (operands[1]));
4575 (GET_CODE (operands[2]) == CONST_INT
4576 ? INTVAL (operands[2])
4577 : CONST_DOUBLE_LOW (operands[2])) - len;
4578 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4580 operands[1] = GEN_INT (mask);
4581 return "andcc\t%0, %1, %%g0";
4583 [(set_attr "type" "compare")])
4585 (define_insn "*cmp_zero_extract_sp64"
4588 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4589 (match_operand:SI 1 "small_int_or_double" "n")
4590 (match_operand:SI 2 "small_int_or_double" "n"))
4593 && ((GET_CODE (operands[2]) == CONST_INT
4594 && INTVAL (operands[2]) > 51)
4595 || (GET_CODE (operands[2]) == CONST_DOUBLE
4596 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4598 int len = (GET_CODE (operands[1]) == CONST_INT
4599 ? INTVAL (operands[1])
4600 : CONST_DOUBLE_LOW (operands[1]));
4602 (GET_CODE (operands[2]) == CONST_INT
4603 ? INTVAL (operands[2])
4604 : CONST_DOUBLE_LOW (operands[2])) - len;
4605 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4607 operands[1] = GEN_INT (mask);
4608 return "andcc\t%0, %1, %%g0";
4610 [(set_attr "type" "compare")])
4612 ;; Conversions between float, double and long double.
4614 (define_insn "extendsfdf2"
4615 [(set (match_operand:DF 0 "register_operand" "=e")
4617 (match_operand:SF 1 "register_operand" "f")))]
4620 [(set_attr "type" "fp")
4621 (set_attr "fptype" "double")])
4623 (define_expand "extendsftf2"
4624 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4626 (match_operand:SF 1 "register_operand" "")))]
4627 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4628 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4630 (define_insn "*extendsftf2_hq"
4631 [(set (match_operand:TF 0 "register_operand" "=e")
4633 (match_operand:SF 1 "register_operand" "f")))]
4634 "TARGET_FPU && TARGET_HARD_QUAD"
4636 [(set_attr "type" "fp")])
4638 (define_expand "extenddftf2"
4639 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4641 (match_operand:DF 1 "register_operand" "")))]
4642 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4643 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4645 (define_insn "*extenddftf2_hq"
4646 [(set (match_operand:TF 0 "register_operand" "=e")
4648 (match_operand:DF 1 "register_operand" "e")))]
4649 "TARGET_FPU && TARGET_HARD_QUAD"
4651 [(set_attr "type" "fp")])
4653 (define_insn "truncdfsf2"
4654 [(set (match_operand:SF 0 "register_operand" "=f")
4656 (match_operand:DF 1 "register_operand" "e")))]
4659 [(set_attr "type" "fp")
4660 (set_attr "fptype" "double")])
4662 (define_expand "trunctfsf2"
4663 [(set (match_operand:SF 0 "register_operand" "")
4665 (match_operand:TF 1 "general_operand" "")))]
4666 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4667 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4669 (define_insn "*trunctfsf2_hq"
4670 [(set (match_operand:SF 0 "register_operand" "=f")
4672 (match_operand:TF 1 "register_operand" "e")))]
4673 "TARGET_FPU && TARGET_HARD_QUAD"
4675 [(set_attr "type" "fp")])
4677 (define_expand "trunctfdf2"
4678 [(set (match_operand:DF 0 "register_operand" "")
4680 (match_operand:TF 1 "general_operand" "")))]
4681 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4682 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4684 (define_insn "*trunctfdf2_hq"
4685 [(set (match_operand:DF 0 "register_operand" "=e")
4687 (match_operand:TF 1 "register_operand" "e")))]
4688 "TARGET_FPU && TARGET_HARD_QUAD"
4690 [(set_attr "type" "fp")])
4692 ;; Conversion between fixed point and floating point.
4694 (define_insn "floatsisf2"
4695 [(set (match_operand:SF 0 "register_operand" "=f")
4696 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4699 [(set_attr "type" "fp")
4700 (set_attr "fptype" "double")])
4702 (define_insn "floatsidf2"
4703 [(set (match_operand:DF 0 "register_operand" "=e")
4704 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4707 [(set_attr "type" "fp")
4708 (set_attr "fptype" "double")])
4710 (define_expand "floatsitf2"
4711 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4712 (float:TF (match_operand:SI 1 "register_operand" "")))]
4713 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4714 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4716 (define_insn "*floatsitf2_hq"
4717 [(set (match_operand:TF 0 "register_operand" "=e")
4718 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4719 "TARGET_FPU && TARGET_HARD_QUAD"
4721 [(set_attr "type" "fp")])
4723 (define_expand "floatunssitf2"
4724 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4725 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4726 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4727 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4729 ;; Now the same for 64 bit sources.
4731 (define_insn "floatdisf2"
4732 [(set (match_operand:SF 0 "register_operand" "=f")
4733 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4734 "TARGET_V9 && TARGET_FPU"
4736 [(set_attr "type" "fp")
4737 (set_attr "fptype" "double")])
4739 (define_expand "floatunsdisf2"
4740 [(use (match_operand:SF 0 "register_operand" ""))
4741 (use (match_operand:DI 1 "general_operand" ""))]
4742 "TARGET_ARCH64 && TARGET_FPU"
4743 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4745 (define_insn "floatdidf2"
4746 [(set (match_operand:DF 0 "register_operand" "=e")
4747 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4748 "TARGET_V9 && TARGET_FPU"
4750 [(set_attr "type" "fp")
4751 (set_attr "fptype" "double")])
4753 (define_expand "floatunsdidf2"
4754 [(use (match_operand:DF 0 "register_operand" ""))
4755 (use (match_operand:DI 1 "general_operand" ""))]
4756 "TARGET_ARCH64 && TARGET_FPU"
4757 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4759 (define_expand "floatditf2"
4760 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4761 (float:TF (match_operand:DI 1 "register_operand" "")))]
4762 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4763 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4765 (define_insn "*floatditf2_hq"
4766 [(set (match_operand:TF 0 "register_operand" "=e")
4767 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4768 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4770 [(set_attr "type" "fp")])
4772 (define_expand "floatunsditf2"
4773 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4774 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4775 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4776 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4778 ;; Convert a float to an actual integer.
4779 ;; Truncation is performed as part of the conversion.
4781 (define_insn "fix_truncsfsi2"
4782 [(set (match_operand:SI 0 "register_operand" "=f")
4783 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4786 [(set_attr "type" "fp")
4787 (set_attr "fptype" "double")])
4789 (define_insn "fix_truncdfsi2"
4790 [(set (match_operand:SI 0 "register_operand" "=f")
4791 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4794 [(set_attr "type" "fp")
4795 (set_attr "fptype" "double")])
4797 (define_expand "fix_trunctfsi2"
4798 [(set (match_operand:SI 0 "register_operand" "")
4799 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4800 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4801 "emit_tfmode_cvt (FIX, operands); DONE;")
4803 (define_insn "*fix_trunctfsi2_hq"
4804 [(set (match_operand:SI 0 "register_operand" "=f")
4805 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4806 "TARGET_FPU && TARGET_HARD_QUAD"
4808 [(set_attr "type" "fp")])
4810 (define_expand "fixuns_trunctfsi2"
4811 [(set (match_operand:SI 0 "register_operand" "")
4812 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4813 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4814 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4816 ;; Now the same, for V9 targets
4818 (define_insn "fix_truncsfdi2"
4819 [(set (match_operand:DI 0 "register_operand" "=e")
4820 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4821 "TARGET_V9 && TARGET_FPU"
4823 [(set_attr "type" "fp")
4824 (set_attr "fptype" "double")])
4826 (define_expand "fixuns_truncsfdi2"
4827 [(use (match_operand:DI 0 "register_operand" ""))
4828 (use (match_operand:SF 1 "general_operand" ""))]
4829 "TARGET_ARCH64 && TARGET_FPU"
4830 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4832 (define_insn "fix_truncdfdi2"
4833 [(set (match_operand:DI 0 "register_operand" "=e")
4834 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4835 "TARGET_V9 && TARGET_FPU"
4837 [(set_attr "type" "fp")
4838 (set_attr "fptype" "double")])
4840 (define_expand "fixuns_truncdfdi2"
4841 [(use (match_operand:DI 0 "register_operand" ""))
4842 (use (match_operand:DF 1 "general_operand" ""))]
4843 "TARGET_ARCH64 && TARGET_FPU"
4844 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4846 (define_expand "fix_trunctfdi2"
4847 [(set (match_operand:DI 0 "register_operand" "")
4848 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4849 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4850 "emit_tfmode_cvt (FIX, operands); DONE;")
4852 (define_insn "*fix_trunctfdi2_hq"
4853 [(set (match_operand:DI 0 "register_operand" "=e")
4854 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4855 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4857 [(set_attr "type" "fp")])
4859 (define_expand "fixuns_trunctfdi2"
4860 [(set (match_operand:DI 0 "register_operand" "")
4861 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4862 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4863 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4865 ;;- arithmetic instructions
4867 (define_expand "adddi3"
4868 [(set (match_operand:DI 0 "register_operand" "")
4869 (plus:DI (match_operand:DI 1 "register_operand" "")
4870 (match_operand:DI 2 "arith_double_add_operand" "")))]
4873 if (! TARGET_ARCH64)
4875 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4876 gen_rtx_SET (VOIDmode, operands[0],
4877 gen_rtx_PLUS (DImode, operands[1],
4879 gen_rtx_CLOBBER (VOIDmode,
4880 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4885 (define_insn_and_split "adddi3_insn_sp32"
4886 [(set (match_operand:DI 0 "register_operand" "=r")
4887 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4888 (match_operand:DI 2 "arith_double_operand" "rHI")))
4889 (clobber (reg:CC 100))]
4892 "&& reload_completed"
4893 [(parallel [(set (reg:CC_NOOV 100)
4894 (compare:CC_NOOV (plus:SI (match_dup 4)
4898 (plus:SI (match_dup 4) (match_dup 5)))])
4900 (plus:SI (plus:SI (match_dup 7)
4902 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4904 operands[3] = gen_lowpart (SImode, operands[0]);
4905 operands[4] = gen_lowpart (SImode, operands[1]);
4906 operands[5] = gen_lowpart (SImode, operands[2]);
4907 operands[6] = gen_highpart (SImode, operands[0]);
4908 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4909 #if HOST_BITS_PER_WIDE_INT == 32
4910 if (GET_CODE (operands[2]) == CONST_INT)
4912 if (INTVAL (operands[2]) < 0)
4913 operands[8] = constm1_rtx;
4915 operands[8] = const0_rtx;
4919 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4921 [(set_attr "length" "2")])
4924 [(set (match_operand:DI 0 "register_operand" "")
4925 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4926 (match_operand:DI 2 "arith_double_operand" "")))
4927 (clobber (reg:CC 100))]
4928 "! TARGET_ARCH64 && reload_completed"
4929 [(parallel [(set (reg:CC_NOOV 100)
4930 (compare:CC_NOOV (minus:SI (match_dup 4)
4934 (minus:SI (match_dup 4) (match_dup 5)))])
4936 (minus:SI (minus:SI (match_dup 7)
4938 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4940 operands[3] = gen_lowpart (SImode, operands[0]);
4941 operands[4] = gen_lowpart (SImode, operands[1]);
4942 operands[5] = gen_lowpart (SImode, operands[2]);
4943 operands[6] = gen_highpart (SImode, operands[0]);
4944 operands[7] = gen_highpart (SImode, operands[1]);
4945 #if HOST_BITS_PER_WIDE_INT == 32
4946 if (GET_CODE (operands[2]) == CONST_INT)
4948 if (INTVAL (operands[2]) < 0)
4949 operands[8] = constm1_rtx;
4951 operands[8] = const0_rtx;
4955 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4958 ;; LTU here means "carry set"
4960 [(set (match_operand:SI 0 "register_operand" "=r")
4961 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4962 (match_operand:SI 2 "arith_operand" "rI"))
4963 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4966 [(set_attr "type" "ialuX")])
4968 (define_insn_and_split "*addx_extend_sp32"
4969 [(set (match_operand:DI 0 "register_operand" "=r")
4970 (zero_extend:DI (plus:SI (plus:SI
4971 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4972 (match_operand:SI 2 "arith_operand" "rI"))
4973 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4976 "&& reload_completed"
4977 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4978 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4979 (set (match_dup 4) (const_int 0))]
4980 "operands[3] = gen_lowpart (SImode, operands[0]);
4981 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4982 [(set_attr "length" "2")])
4984 (define_insn "*addx_extend_sp64"
4985 [(set (match_operand:DI 0 "register_operand" "=r")
4986 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4987 (match_operand:SI 2 "arith_operand" "rI"))
4988 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4991 [(set_attr "type" "ialuX")])
4994 [(set (match_operand:SI 0 "register_operand" "=r")
4995 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4996 (match_operand:SI 2 "arith_operand" "rI"))
4997 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5000 [(set_attr "type" "ialuX")])
5002 (define_insn "*subx_extend_sp64"
5003 [(set (match_operand:DI 0 "register_operand" "=r")
5004 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5005 (match_operand:SI 2 "arith_operand" "rI"))
5006 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5009 [(set_attr "type" "ialuX")])
5011 (define_insn_and_split "*subx_extend"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5013 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5014 (match_operand:SI 2 "arith_operand" "rI"))
5015 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5018 "&& reload_completed"
5019 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5020 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5021 (set (match_dup 4) (const_int 0))]
5022 "operands[3] = gen_lowpart (SImode, operands[0]);
5023 operands[4] = gen_highpart (SImode, operands[0]);"
5024 [(set_attr "length" "2")])
5026 (define_insn_and_split ""
5027 [(set (match_operand:DI 0 "register_operand" "=r")
5028 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5029 (match_operand:DI 2 "register_operand" "r")))
5030 (clobber (reg:CC 100))]
5033 "&& reload_completed"
5034 [(parallel [(set (reg:CC_NOOV 100)
5035 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5037 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5039 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5040 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5041 "operands[3] = gen_lowpart (SImode, operands[2]);
5042 operands[4] = gen_highpart (SImode, operands[2]);
5043 operands[5] = gen_lowpart (SImode, operands[0]);
5044 operands[6] = gen_highpart (SImode, operands[0]);"
5045 [(set_attr "length" "2")])
5047 (define_insn "*adddi3_sp64"
5048 [(set (match_operand:DI 0 "register_operand" "=r,r")
5049 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5050 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5056 (define_insn "addsi3"
5057 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5058 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5059 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5064 fpadd32s\t%1, %2, %0"
5065 [(set_attr "type" "*,*,fga")
5066 (set_attr "fptype" "*,*,single")])
5068 (define_insn "*cmp_cc_plus"
5069 [(set (reg:CC_NOOV 100)
5070 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5071 (match_operand:SI 1 "arith_operand" "rI"))
5074 "addcc\t%0, %1, %%g0"
5075 [(set_attr "type" "compare")])
5077 (define_insn "*cmp_ccx_plus"
5078 [(set (reg:CCX_NOOV 100)
5079 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5080 (match_operand:DI 1 "arith_double_operand" "rHI"))
5083 "addcc\t%0, %1, %%g0"
5084 [(set_attr "type" "compare")])
5086 (define_insn "*cmp_cc_plus_set"
5087 [(set (reg:CC_NOOV 100)
5088 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5089 (match_operand:SI 2 "arith_operand" "rI"))
5091 (set (match_operand:SI 0 "register_operand" "=r")
5092 (plus:SI (match_dup 1) (match_dup 2)))]
5095 [(set_attr "type" "compare")])
5097 (define_insn "*cmp_ccx_plus_set"
5098 [(set (reg:CCX_NOOV 100)
5099 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5100 (match_operand:DI 2 "arith_double_operand" "rHI"))
5102 (set (match_operand:DI 0 "register_operand" "=r")
5103 (plus:DI (match_dup 1) (match_dup 2)))]
5106 [(set_attr "type" "compare")])
5108 (define_expand "subdi3"
5109 [(set (match_operand:DI 0 "register_operand" "")
5110 (minus:DI (match_operand:DI 1 "register_operand" "")
5111 (match_operand:DI 2 "arith_double_add_operand" "")))]
5114 if (! TARGET_ARCH64)
5116 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5117 gen_rtx_SET (VOIDmode, operands[0],
5118 gen_rtx_MINUS (DImode, operands[1],
5120 gen_rtx_CLOBBER (VOIDmode,
5121 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5126 (define_insn_and_split "*subdi3_sp32"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5128 (minus:DI (match_operand:DI 1 "register_operand" "r")
5129 (match_operand:DI 2 "arith_double_operand" "rHI")))
5130 (clobber (reg:CC 100))]
5133 "&& reload_completed
5134 && (GET_CODE (operands[2]) == CONST_INT
5135 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5136 [(clobber (const_int 0))]
5140 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5141 lowp = gen_lowpart (SImode, operands[2]);
5142 if ((lowp == const0_rtx)
5143 && (operands[0] == operands[1]))
5145 emit_insn (gen_rtx_SET (VOIDmode,
5146 gen_highpart (SImode, operands[0]),
5147 gen_rtx_MINUS (SImode,
5148 gen_highpart_mode (SImode, DImode,
5154 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5155 gen_lowpart (SImode, operands[1]),
5157 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5158 gen_highpart_mode (SImode, DImode, operands[1]),
5163 [(set_attr "length" "2")])
5166 [(set (match_operand:DI 0 "register_operand" "")
5167 (minus:DI (match_operand:DI 1 "register_operand" "")
5168 (match_operand:DI 2 "register_operand" "")))
5169 (clobber (reg:CC 100))]
5171 && reload_completed"
5172 [(clobber (const_int 0))]
5174 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5175 gen_lowpart (SImode, operands[1]),
5176 gen_lowpart (SImode, operands[2])));
5177 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5178 gen_highpart (SImode, operands[1]),
5179 gen_highpart (SImode, operands[2])));
5183 (define_insn_and_split ""
5184 [(set (match_operand:DI 0 "register_operand" "=r")
5185 (minus:DI (match_operand:DI 1 "register_operand" "r")
5186 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5187 (clobber (reg:CC 100))]
5190 "&& reload_completed"
5191 [(parallel [(set (reg:CC_NOOV 100)
5192 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5194 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5196 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5197 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5198 "operands[3] = gen_lowpart (SImode, operands[1]);
5199 operands[4] = gen_highpart (SImode, operands[1]);
5200 operands[5] = gen_lowpart (SImode, operands[0]);
5201 operands[6] = gen_highpart (SImode, operands[0]);"
5202 [(set_attr "length" "2")])
5204 (define_insn "*subdi3_sp64"
5205 [(set (match_operand:DI 0 "register_operand" "=r,r")
5206 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5207 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5213 (define_insn "subsi3"
5214 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5215 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5216 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5221 fpsub32s\t%1, %2, %0"
5222 [(set_attr "type" "*,*,fga")
5223 (set_attr "fptype" "*,*,single")])
5225 (define_insn "*cmp_minus_cc"
5226 [(set (reg:CC_NOOV 100)
5227 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5228 (match_operand:SI 1 "arith_operand" "rI"))
5231 "subcc\t%r0, %1, %%g0"
5232 [(set_attr "type" "compare")])
5234 (define_insn "*cmp_minus_ccx"
5235 [(set (reg:CCX_NOOV 100)
5236 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5237 (match_operand:DI 1 "arith_double_operand" "rHI"))
5240 "subcc\t%0, %1, %%g0"
5241 [(set_attr "type" "compare")])
5243 (define_insn "cmp_minus_cc_set"
5244 [(set (reg:CC_NOOV 100)
5245 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5246 (match_operand:SI 2 "arith_operand" "rI"))
5248 (set (match_operand:SI 0 "register_operand" "=r")
5249 (minus:SI (match_dup 1) (match_dup 2)))]
5251 "subcc\t%r1, %2, %0"
5252 [(set_attr "type" "compare")])
5254 (define_insn "*cmp_minus_ccx_set"
5255 [(set (reg:CCX_NOOV 100)
5256 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5257 (match_operand:DI 2 "arith_double_operand" "rHI"))
5259 (set (match_operand:DI 0 "register_operand" "=r")
5260 (minus:DI (match_dup 1) (match_dup 2)))]
5263 [(set_attr "type" "compare")])
5265 ;; Integer Multiply/Divide.
5267 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5268 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5270 (define_insn "mulsi3"
5271 [(set (match_operand:SI 0 "register_operand" "=r")
5272 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5273 (match_operand:SI 2 "arith_operand" "rI")))]
5276 [(set_attr "type" "imul")])
5278 (define_expand "muldi3"
5279 [(set (match_operand:DI 0 "register_operand" "=r")
5280 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5281 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5282 "TARGET_ARCH64 || TARGET_V8PLUS"
5286 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5291 (define_insn "*muldi3_sp64"
5292 [(set (match_operand:DI 0 "register_operand" "=r")
5293 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5294 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5297 [(set_attr "type" "imul")])
5299 ;; V8plus wide multiply.
5301 (define_insn "muldi3_v8plus"
5302 [(set (match_operand:DI 0 "register_operand" "=r,h")
5303 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5304 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5305 (clobber (match_scratch:SI 3 "=&h,X"))
5306 (clobber (match_scratch:SI 4 "=&h,X"))]
5309 if (sparc_check_64 (operands[1], insn) <= 0)
5310 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5311 if (which_alternative == 1)
5312 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5313 if (GET_CODE (operands[2]) == CONST_INT)
5315 if (which_alternative == 1)
5316 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5318 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";
5320 else if (rtx_equal_p (operands[1], operands[2]))
5322 if (which_alternative == 1)
5323 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5325 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";
5327 if (sparc_check_64 (operands[2], insn) <= 0)
5328 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5329 if (which_alternative == 1)
5330 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";
5332 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";
5334 [(set_attr "type" "multi")
5335 (set_attr "length" "9,8")])
5337 (define_insn "*cmp_mul_set"
5339 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5340 (match_operand:SI 2 "arith_operand" "rI"))
5342 (set (match_operand:SI 0 "register_operand" "=r")
5343 (mult:SI (match_dup 1) (match_dup 2)))]
5344 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5345 "smulcc\t%1, %2, %0"
5346 [(set_attr "type" "imul")])
5348 (define_expand "mulsidi3"
5349 [(set (match_operand:DI 0 "register_operand" "")
5350 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5351 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5354 if (CONSTANT_P (operands[2]))
5357 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5359 else if (TARGET_ARCH32)
5360 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5363 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5369 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5374 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5375 ;; registers can hold 64 bit values in the V8plus environment.
5377 (define_insn "mulsidi3_v8plus"
5378 [(set (match_operand:DI 0 "register_operand" "=h,r")
5379 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5380 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5381 (clobber (match_scratch:SI 3 "=X,&h"))]
5384 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5385 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5386 [(set_attr "type" "multi")
5387 (set_attr "length" "2,3")])
5390 (define_insn "const_mulsidi3_v8plus"
5391 [(set (match_operand:DI 0 "register_operand" "=h,r")
5392 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5393 (match_operand:DI 2 "small_int" "I,I")))
5394 (clobber (match_scratch:SI 3 "=X,&h"))]
5397 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5398 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5399 [(set_attr "type" "multi")
5400 (set_attr "length" "2,3")])
5403 (define_insn "*mulsidi3_sp32"
5404 [(set (match_operand:DI 0 "register_operand" "=r")
5405 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5406 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5409 return TARGET_SPARCLET
5410 ? "smuld\t%1, %2, %L0"
5411 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5414 (if_then_else (eq_attr "isa" "sparclet")
5415 (const_string "imul") (const_string "multi")))
5416 (set (attr "length")
5417 (if_then_else (eq_attr "isa" "sparclet")
5418 (const_int 1) (const_int 2)))])
5420 (define_insn "*mulsidi3_sp64"
5421 [(set (match_operand:DI 0 "register_operand" "=r")
5422 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5423 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5424 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5426 [(set_attr "type" "imul")])
5428 ;; Extra pattern, because sign_extend of a constant isn't valid.
5431 (define_insn "const_mulsidi3_sp32"
5432 [(set (match_operand:DI 0 "register_operand" "=r")
5433 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5434 (match_operand:DI 2 "small_int" "I")))]
5437 return TARGET_SPARCLET
5438 ? "smuld\t%1, %2, %L0"
5439 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5442 (if_then_else (eq_attr "isa" "sparclet")
5443 (const_string "imul") (const_string "multi")))
5444 (set (attr "length")
5445 (if_then_else (eq_attr "isa" "sparclet")
5446 (const_int 1) (const_int 2)))])
5448 (define_insn "const_mulsidi3_sp64"
5449 [(set (match_operand:DI 0 "register_operand" "=r")
5450 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5451 (match_operand:DI 2 "small_int" "I")))]
5452 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5454 [(set_attr "type" "imul")])
5456 (define_expand "smulsi3_highpart"
5457 [(set (match_operand:SI 0 "register_operand" "")
5459 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5460 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5462 "TARGET_HARD_MUL && TARGET_ARCH32"
5464 if (CONSTANT_P (operands[2]))
5468 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5474 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5479 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5480 operands[2], GEN_INT (32)));
5486 (define_insn "smulsi3_highpart_v8plus"
5487 [(set (match_operand:SI 0 "register_operand" "=h,r")
5489 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5490 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5491 (match_operand:SI 3 "const_int_operand" "i,i"))))
5492 (clobber (match_scratch:SI 4 "=X,&h"))]
5495 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5496 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5497 [(set_attr "type" "multi")
5498 (set_attr "length" "2")])
5500 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5503 [(set (match_operand:SI 0 "register_operand" "=h,r")
5506 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5507 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5508 (match_operand:SI 3 "const_int_operand" "i,i"))
5510 (clobber (match_scratch:SI 4 "=X,&h"))]
5513 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5514 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5515 [(set_attr "type" "multi")
5516 (set_attr "length" "2")])
5519 (define_insn "const_smulsi3_highpart_v8plus"
5520 [(set (match_operand:SI 0 "register_operand" "=h,r")
5522 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5523 (match_operand:DI 2 "small_int" "i,i"))
5524 (match_operand:SI 3 "const_int_operand" "i,i"))))
5525 (clobber (match_scratch:SI 4 "=X,&h"))]
5528 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5529 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5530 [(set_attr "type" "multi")
5531 (set_attr "length" "2")])
5534 (define_insn "*smulsi3_highpart_sp32"
5535 [(set (match_operand:SI 0 "register_operand" "=r")
5537 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5538 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5541 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5542 [(set_attr "type" "multi")
5543 (set_attr "length" "2")])
5546 (define_insn "const_smulsi3_highpart"
5547 [(set (match_operand:SI 0 "register_operand" "=r")
5549 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5550 (match_operand:DI 2 "small_int" "i"))
5553 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5554 [(set_attr "type" "multi")
5555 (set_attr "length" "2")])
5557 (define_expand "umulsidi3"
5558 [(set (match_operand:DI 0 "register_operand" "")
5559 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5560 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5563 if (CONSTANT_P (operands[2]))
5566 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5568 else if (TARGET_ARCH32)
5569 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5572 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5578 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5584 (define_insn "umulsidi3_v8plus"
5585 [(set (match_operand:DI 0 "register_operand" "=h,r")
5586 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5587 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5588 (clobber (match_scratch:SI 3 "=X,&h"))]
5591 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5592 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5593 [(set_attr "type" "multi")
5594 (set_attr "length" "2,3")])
5597 (define_insn "*umulsidi3_sp32"
5598 [(set (match_operand:DI 0 "register_operand" "=r")
5599 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5600 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5603 return TARGET_SPARCLET
5604 ? "umuld\t%1, %2, %L0"
5605 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5608 (if_then_else (eq_attr "isa" "sparclet")
5609 (const_string "imul") (const_string "multi")))
5610 (set (attr "length")
5611 (if_then_else (eq_attr "isa" "sparclet")
5612 (const_int 1) (const_int 2)))])
5614 (define_insn "*umulsidi3_sp64"
5615 [(set (match_operand:DI 0 "register_operand" "=r")
5616 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5617 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5618 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5620 [(set_attr "type" "imul")])
5622 ;; Extra pattern, because sign_extend of a constant isn't valid.
5625 (define_insn "const_umulsidi3_sp32"
5626 [(set (match_operand:DI 0 "register_operand" "=r")
5627 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5628 (match_operand:DI 2 "uns_small_int" "")))]
5631 return TARGET_SPARCLET
5632 ? "umuld\t%1, %s2, %L0"
5633 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5636 (if_then_else (eq_attr "isa" "sparclet")
5637 (const_string "imul") (const_string "multi")))
5638 (set (attr "length")
5639 (if_then_else (eq_attr "isa" "sparclet")
5640 (const_int 1) (const_int 2)))])
5642 (define_insn "const_umulsidi3_sp64"
5643 [(set (match_operand:DI 0 "register_operand" "=r")
5644 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5645 (match_operand:DI 2 "uns_small_int" "")))]
5646 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5648 [(set_attr "type" "imul")])
5651 (define_insn "const_umulsidi3_v8plus"
5652 [(set (match_operand:DI 0 "register_operand" "=h,r")
5653 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5654 (match_operand:DI 2 "uns_small_int" "")))
5655 (clobber (match_scratch:SI 3 "=X,h"))]
5658 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5659 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5660 [(set_attr "type" "multi")
5661 (set_attr "length" "2,3")])
5663 (define_expand "umulsi3_highpart"
5664 [(set (match_operand:SI 0 "register_operand" "")
5666 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5667 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5669 "TARGET_HARD_MUL && TARGET_ARCH32"
5671 if (CONSTANT_P (operands[2]))
5675 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5681 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5686 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5687 operands[2], GEN_INT (32)));
5693 (define_insn "umulsi3_highpart_v8plus"
5694 [(set (match_operand:SI 0 "register_operand" "=h,r")
5696 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5697 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5698 (match_operand:SI 3 "const_int_operand" "i,i"))))
5699 (clobber (match_scratch:SI 4 "=X,h"))]
5702 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5703 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5704 [(set_attr "type" "multi")
5705 (set_attr "length" "2")])
5708 (define_insn "const_umulsi3_highpart_v8plus"
5709 [(set (match_operand:SI 0 "register_operand" "=h,r")
5711 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5712 (match_operand:DI 2 "uns_small_int" ""))
5713 (match_operand:SI 3 "const_int_operand" "i,i"))))
5714 (clobber (match_scratch:SI 4 "=X,h"))]
5717 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5718 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5719 [(set_attr "type" "multi")
5720 (set_attr "length" "2")])
5723 (define_insn "*umulsi3_highpart_sp32"
5724 [(set (match_operand:SI 0 "register_operand" "=r")
5726 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5727 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5730 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5731 [(set_attr "type" "multi")
5732 (set_attr "length" "2")])
5735 (define_insn "const_umulsi3_highpart"
5736 [(set (match_operand:SI 0 "register_operand" "=r")
5738 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5739 (match_operand:DI 2 "uns_small_int" ""))
5742 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5743 [(set_attr "type" "multi")
5744 (set_attr "length" "2")])
5746 ;; The v8 architecture specifies that there must be 3 instructions between
5747 ;; a y register write and a use of it for correct results.
5749 (define_expand "divsi3"
5750 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5751 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5752 (match_operand:SI 2 "input_operand" "rI,m")))
5753 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5754 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5758 operands[3] = gen_reg_rtx(SImode);
5759 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5760 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5766 (define_insn "divsi3_sp32"
5767 [(set (match_operand:SI 0 "register_operand" "=r,r")
5768 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5769 (match_operand:SI 2 "input_operand" "rI,m")))
5770 (clobber (match_scratch:SI 3 "=&r,&r"))]
5771 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5774 if (which_alternative == 0)
5776 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5778 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5781 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5783 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";
5785 [(set_attr "type" "multi")
5786 (set (attr "length")
5787 (if_then_else (eq_attr "isa" "v9")
5788 (const_int 4) (const_int 6)))])
5790 (define_insn "divsi3_sp64"
5791 [(set (match_operand:SI 0 "register_operand" "=r")
5792 (div:SI (match_operand:SI 1 "register_operand" "r")
5793 (match_operand:SI 2 "input_operand" "rI")))
5794 (use (match_operand:SI 3 "register_operand" "r"))]
5795 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5796 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5797 [(set_attr "type" "multi")
5798 (set_attr "length" "2")])
5800 (define_insn "divdi3"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5802 (div:DI (match_operand:DI 1 "register_operand" "r")
5803 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5806 [(set_attr "type" "idiv")])
5808 (define_insn "*cmp_sdiv_cc_set"
5810 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5811 (match_operand:SI 2 "arith_operand" "rI"))
5813 (set (match_operand:SI 0 "register_operand" "=r")
5814 (div:SI (match_dup 1) (match_dup 2)))
5815 (clobber (match_scratch:SI 3 "=&r"))]
5816 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5819 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5821 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5823 [(set_attr "type" "multi")
5824 (set (attr "length")
5825 (if_then_else (eq_attr "isa" "v9")
5826 (const_int 3) (const_int 6)))])
5829 (define_expand "udivsi3"
5830 [(set (match_operand:SI 0 "register_operand" "")
5831 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5832 (match_operand:SI 2 "input_operand" "")))]
5833 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5836 (define_insn "udivsi3_sp32"
5837 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5838 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5839 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5841 || TARGET_DEPRECATED_V8_INSNS)
5844 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5845 switch (which_alternative)
5848 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5850 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5852 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5855 [(set_attr "type" "multi")
5856 (set_attr "length" "5")])
5858 (define_insn "udivsi3_sp64"
5859 [(set (match_operand:SI 0 "register_operand" "=r")
5860 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5861 (match_operand:SI 2 "input_operand" "rI")))]
5862 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5863 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5864 [(set_attr "type" "multi")
5865 (set_attr "length" "2")])
5867 (define_insn "udivdi3"
5868 [(set (match_operand:DI 0 "register_operand" "=r")
5869 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5870 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5873 [(set_attr "type" "idiv")])
5875 (define_insn "*cmp_udiv_cc_set"
5877 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5878 (match_operand:SI 2 "arith_operand" "rI"))
5880 (set (match_operand:SI 0 "register_operand" "=r")
5881 (udiv:SI (match_dup 1) (match_dup 2)))]
5883 || TARGET_DEPRECATED_V8_INSNS"
5886 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5888 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5890 [(set_attr "type" "multi")
5891 (set (attr "length")
5892 (if_then_else (eq_attr "isa" "v9")
5893 (const_int 2) (const_int 5)))])
5895 ; sparclet multiply/accumulate insns
5897 (define_insn "*smacsi"
5898 [(set (match_operand:SI 0 "register_operand" "=r")
5899 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5900 (match_operand:SI 2 "arith_operand" "rI"))
5901 (match_operand:SI 3 "register_operand" "0")))]
5904 [(set_attr "type" "imul")])
5906 (define_insn "*smacdi"
5907 [(set (match_operand:DI 0 "register_operand" "=r")
5908 (plus:DI (mult:DI (sign_extend:DI
5909 (match_operand:SI 1 "register_operand" "%r"))
5911 (match_operand:SI 2 "register_operand" "r")))
5912 (match_operand:DI 3 "register_operand" "0")))]
5914 "smacd\t%1, %2, %L0"
5915 [(set_attr "type" "imul")])
5917 (define_insn "*umacdi"
5918 [(set (match_operand:DI 0 "register_operand" "=r")
5919 (plus:DI (mult:DI (zero_extend:DI
5920 (match_operand:SI 1 "register_operand" "%r"))
5922 (match_operand:SI 2 "register_operand" "r")))
5923 (match_operand:DI 3 "register_operand" "0")))]
5925 "umacd\t%1, %2, %L0"
5926 [(set_attr "type" "imul")])
5928 ;;- Boolean instructions
5929 ;; We define DImode `and' so with DImode `not' we can get
5930 ;; DImode `andn'. Other combinations are possible.
5932 (define_expand "anddi3"
5933 [(set (match_operand:DI 0 "register_operand" "")
5934 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5935 (match_operand:DI 2 "arith_double_operand" "")))]
5939 (define_insn "*anddi3_sp32"
5940 [(set (match_operand:DI 0 "register_operand" "=r,b")
5941 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5942 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5947 [(set_attr "type" "*,fga")
5948 (set_attr "length" "2,*")
5949 (set_attr "fptype" "double")])
5951 (define_insn "*anddi3_sp64"
5952 [(set (match_operand:DI 0 "register_operand" "=r,b")
5953 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5954 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5959 [(set_attr "type" "*,fga")
5960 (set_attr "fptype" "double")])
5962 (define_insn "andsi3"
5963 [(set (match_operand:SI 0 "register_operand" "=r,d")
5964 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5965 (match_operand:SI 2 "arith_operand" "rI,d")))]
5970 [(set_attr "type" "*,fga")])
5973 [(set (match_operand:SI 0 "register_operand" "")
5974 (and:SI (match_operand:SI 1 "register_operand" "")
5975 (match_operand:SI 2 "" "")))
5976 (clobber (match_operand:SI 3 "register_operand" ""))]
5977 "GET_CODE (operands[2]) == CONST_INT
5978 && !SMALL_INT32 (operands[2])
5979 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5980 [(set (match_dup 3) (match_dup 4))
5981 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5983 operands[4] = GEN_INT (~INTVAL (operands[2]));
5986 ;; Split DImode logical operations requiring two instructions.
5988 [(set (match_operand:DI 0 "register_operand" "")
5989 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5990 [(match_operand:DI 2 "register_operand" "")
5991 (match_operand:DI 3 "arith_double_operand" "")]))]
5994 && ((GET_CODE (operands[0]) == REG
5995 && REGNO (operands[0]) < 32)
5996 || (GET_CODE (operands[0]) == SUBREG
5997 && GET_CODE (SUBREG_REG (operands[0])) == REG
5998 && REGNO (SUBREG_REG (operands[0])) < 32))"
5999 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6000 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6002 operands[4] = gen_highpart (SImode, operands[0]);
6003 operands[5] = gen_lowpart (SImode, operands[0]);
6004 operands[6] = gen_highpart (SImode, operands[2]);
6005 operands[7] = gen_lowpart (SImode, operands[2]);
6006 #if HOST_BITS_PER_WIDE_INT == 32
6007 if (GET_CODE (operands[3]) == CONST_INT)
6009 if (INTVAL (operands[3]) < 0)
6010 operands[8] = constm1_rtx;
6012 operands[8] = const0_rtx;
6016 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6017 operands[9] = gen_lowpart (SImode, operands[3]);
6020 (define_insn_and_split "*and_not_di_sp32"
6021 [(set (match_operand:DI 0 "register_operand" "=r,b")
6022 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6023 (match_operand:DI 2 "register_operand" "r,b")))]
6027 fandnot1\t%1, %2, %0"
6028 "&& reload_completed
6029 && ((GET_CODE (operands[0]) == REG
6030 && REGNO (operands[0]) < 32)
6031 || (GET_CODE (operands[0]) == SUBREG
6032 && GET_CODE (SUBREG_REG (operands[0])) == REG
6033 && REGNO (SUBREG_REG (operands[0])) < 32))"
6034 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6035 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6036 "operands[3] = gen_highpart (SImode, operands[0]);
6037 operands[4] = gen_highpart (SImode, operands[1]);
6038 operands[5] = gen_highpart (SImode, operands[2]);
6039 operands[6] = gen_lowpart (SImode, operands[0]);
6040 operands[7] = gen_lowpart (SImode, operands[1]);
6041 operands[8] = gen_lowpart (SImode, operands[2]);"
6042 [(set_attr "type" "*,fga")
6043 (set_attr "length" "2,*")
6044 (set_attr "fptype" "double")])
6046 (define_insn "*and_not_di_sp64"
6047 [(set (match_operand:DI 0 "register_operand" "=r,b")
6048 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6049 (match_operand:DI 2 "register_operand" "r,b")))]
6053 fandnot1\t%1, %2, %0"
6054 [(set_attr "type" "*,fga")
6055 (set_attr "fptype" "double")])
6057 (define_insn "*and_not_si"
6058 [(set (match_operand:SI 0 "register_operand" "=r,d")
6059 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6060 (match_operand:SI 2 "register_operand" "r,d")))]
6064 fandnot1s\t%1, %2, %0"
6065 [(set_attr "type" "*,fga")])
6067 (define_expand "iordi3"
6068 [(set (match_operand:DI 0 "register_operand" "")
6069 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6070 (match_operand:DI 2 "arith_double_operand" "")))]
6074 (define_insn "*iordi3_sp32"
6075 [(set (match_operand:DI 0 "register_operand" "=r,b")
6076 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6077 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6082 [(set_attr "type" "*,fga")
6083 (set_attr "length" "2,*")
6084 (set_attr "fptype" "double")])
6086 (define_insn "*iordi3_sp64"
6087 [(set (match_operand:DI 0 "register_operand" "=r,b")
6088 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6089 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6094 [(set_attr "type" "*,fga")
6095 (set_attr "fptype" "double")])
6097 (define_insn "iorsi3"
6098 [(set (match_operand:SI 0 "register_operand" "=r,d")
6099 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6100 (match_operand:SI 2 "arith_operand" "rI,d")))]
6105 [(set_attr "type" "*,fga")])
6108 [(set (match_operand:SI 0 "register_operand" "")
6109 (ior:SI (match_operand:SI 1 "register_operand" "")
6110 (match_operand:SI 2 "" "")))
6111 (clobber (match_operand:SI 3 "register_operand" ""))]
6112 "GET_CODE (operands[2]) == CONST_INT
6113 && !SMALL_INT32 (operands[2])
6114 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6115 [(set (match_dup 3) (match_dup 4))
6116 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6118 operands[4] = GEN_INT (~INTVAL (operands[2]));
6121 (define_insn_and_split "*or_not_di_sp32"
6122 [(set (match_operand:DI 0 "register_operand" "=r,b")
6123 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6124 (match_operand:DI 2 "register_operand" "r,b")))]
6128 fornot1\t%1, %2, %0"
6129 "&& reload_completed
6130 && ((GET_CODE (operands[0]) == REG
6131 && REGNO (operands[0]) < 32)
6132 || (GET_CODE (operands[0]) == SUBREG
6133 && GET_CODE (SUBREG_REG (operands[0])) == REG
6134 && REGNO (SUBREG_REG (operands[0])) < 32))"
6135 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6136 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6137 "operands[3] = gen_highpart (SImode, operands[0]);
6138 operands[4] = gen_highpart (SImode, operands[1]);
6139 operands[5] = gen_highpart (SImode, operands[2]);
6140 operands[6] = gen_lowpart (SImode, operands[0]);
6141 operands[7] = gen_lowpart (SImode, operands[1]);
6142 operands[8] = gen_lowpart (SImode, operands[2]);"
6143 [(set_attr "type" "*,fga")
6144 (set_attr "length" "2,*")
6145 (set_attr "fptype" "double")])
6147 (define_insn "*or_not_di_sp64"
6148 [(set (match_operand:DI 0 "register_operand" "=r,b")
6149 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6150 (match_operand:DI 2 "register_operand" "r,b")))]
6154 fornot1\t%1, %2, %0"
6155 [(set_attr "type" "*,fga")
6156 (set_attr "fptype" "double")])
6158 (define_insn "*or_not_si"
6159 [(set (match_operand:SI 0 "register_operand" "=r,d")
6160 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6161 (match_operand:SI 2 "register_operand" "r,d")))]
6165 fornot1s\t%1, %2, %0"
6166 [(set_attr "type" "*,fga")])
6168 (define_expand "xordi3"
6169 [(set (match_operand:DI 0 "register_operand" "")
6170 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6171 (match_operand:DI 2 "arith_double_operand" "")))]
6175 (define_insn "*xordi3_sp32"
6176 [(set (match_operand:DI 0 "register_operand" "=r,b")
6177 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6178 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6183 [(set_attr "type" "*,fga")
6184 (set_attr "length" "2,*")
6185 (set_attr "fptype" "double")])
6187 (define_insn "*xordi3_sp64"
6188 [(set (match_operand:DI 0 "register_operand" "=r,b")
6189 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6190 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6195 [(set_attr "type" "*,fga")
6196 (set_attr "fptype" "double")])
6198 (define_insn "*xordi3_sp64_dbl"
6199 [(set (match_operand:DI 0 "register_operand" "=r")
6200 (xor:DI (match_operand:DI 1 "register_operand" "r")
6201 (match_operand:DI 2 "const64_operand" "")))]
6203 && HOST_BITS_PER_WIDE_INT != 64)"
6206 (define_insn "xorsi3"
6207 [(set (match_operand:SI 0 "register_operand" "=r,d")
6208 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6209 (match_operand:SI 2 "arith_operand" "rI,d")))]
6214 [(set_attr "type" "*,fga")])
6217 [(set (match_operand:SI 0 "register_operand" "")
6218 (xor:SI (match_operand:SI 1 "register_operand" "")
6219 (match_operand:SI 2 "" "")))
6220 (clobber (match_operand:SI 3 "register_operand" ""))]
6221 "GET_CODE (operands[2]) == CONST_INT
6222 && !SMALL_INT32 (operands[2])
6223 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6224 [(set (match_dup 3) (match_dup 4))
6225 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6227 operands[4] = GEN_INT (~INTVAL (operands[2]));
6231 [(set (match_operand:SI 0 "register_operand" "")
6232 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6233 (match_operand:SI 2 "" ""))))
6234 (clobber (match_operand:SI 3 "register_operand" ""))]
6235 "GET_CODE (operands[2]) == CONST_INT
6236 && !SMALL_INT32 (operands[2])
6237 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6238 [(set (match_dup 3) (match_dup 4))
6239 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6241 operands[4] = GEN_INT (~INTVAL (operands[2]));
6244 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6245 ;; Combine now canonicalizes to the rightmost expression.
6246 (define_insn_and_split "*xor_not_di_sp32"
6247 [(set (match_operand:DI 0 "register_operand" "=r,b")
6248 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6249 (match_operand:DI 2 "register_operand" "r,b"))))]
6254 "&& reload_completed
6255 && ((GET_CODE (operands[0]) == REG
6256 && REGNO (operands[0]) < 32)
6257 || (GET_CODE (operands[0]) == SUBREG
6258 && GET_CODE (SUBREG_REG (operands[0])) == REG
6259 && REGNO (SUBREG_REG (operands[0])) < 32))"
6260 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6261 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6262 "operands[3] = gen_highpart (SImode, operands[0]);
6263 operands[4] = gen_highpart (SImode, operands[1]);
6264 operands[5] = gen_highpart (SImode, operands[2]);
6265 operands[6] = gen_lowpart (SImode, operands[0]);
6266 operands[7] = gen_lowpart (SImode, operands[1]);
6267 operands[8] = gen_lowpart (SImode, operands[2]);"
6268 [(set_attr "type" "*,fga")
6269 (set_attr "length" "2,*")
6270 (set_attr "fptype" "double")])
6272 (define_insn "*xor_not_di_sp64"
6273 [(set (match_operand:DI 0 "register_operand" "=r,b")
6274 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6275 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6280 [(set_attr "type" "*,fga")
6281 (set_attr "fptype" "double")])
6283 (define_insn "*xor_not_si"
6284 [(set (match_operand:SI 0 "register_operand" "=r,d")
6285 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6286 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6291 [(set_attr "type" "*,fga")])
6293 ;; These correspond to the above in the case where we also (or only)
6294 ;; want to set the condition code.
6296 (define_insn "*cmp_cc_arith_op"
6299 (match_operator:SI 2 "cc_arithop"
6300 [(match_operand:SI 0 "arith_operand" "%r")
6301 (match_operand:SI 1 "arith_operand" "rI")])
6304 "%A2cc\t%0, %1, %%g0"
6305 [(set_attr "type" "compare")])
6307 (define_insn "*cmp_ccx_arith_op"
6310 (match_operator:DI 2 "cc_arithop"
6311 [(match_operand:DI 0 "arith_double_operand" "%r")
6312 (match_operand:DI 1 "arith_double_operand" "rHI")])
6315 "%A2cc\t%0, %1, %%g0"
6316 [(set_attr "type" "compare")])
6318 (define_insn "*cmp_cc_arith_op_set"
6321 (match_operator:SI 3 "cc_arithop"
6322 [(match_operand:SI 1 "arith_operand" "%r")
6323 (match_operand:SI 2 "arith_operand" "rI")])
6325 (set (match_operand:SI 0 "register_operand" "=r")
6326 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6327 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6329 [(set_attr "type" "compare")])
6331 (define_insn "*cmp_ccx_arith_op_set"
6334 (match_operator:DI 3 "cc_arithop"
6335 [(match_operand:DI 1 "arith_double_operand" "%r")
6336 (match_operand:DI 2 "arith_double_operand" "rHI")])
6338 (set (match_operand:DI 0 "register_operand" "=r")
6339 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6340 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6342 [(set_attr "type" "compare")])
6344 (define_insn "*cmp_cc_xor_not"
6347 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6348 (match_operand:SI 1 "arith_operand" "rI")))
6351 "xnorcc\t%r0, %1, %%g0"
6352 [(set_attr "type" "compare")])
6354 (define_insn "*cmp_ccx_xor_not"
6357 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6358 (match_operand:DI 1 "arith_double_operand" "rHI")))
6361 "xnorcc\t%r0, %1, %%g0"
6362 [(set_attr "type" "compare")])
6364 (define_insn "*cmp_cc_xor_not_set"
6367 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6368 (match_operand:SI 2 "arith_operand" "rI")))
6370 (set (match_operand:SI 0 "register_operand" "=r")
6371 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6373 "xnorcc\t%r1, %2, %0"
6374 [(set_attr "type" "compare")])
6376 (define_insn "*cmp_ccx_xor_not_set"
6379 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6380 (match_operand:DI 2 "arith_double_operand" "rHI")))
6382 (set (match_operand:DI 0 "register_operand" "=r")
6383 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6385 "xnorcc\t%r1, %2, %0"
6386 [(set_attr "type" "compare")])
6388 (define_insn "*cmp_cc_arith_op_not"
6391 (match_operator:SI 2 "cc_arithopn"
6392 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6393 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6396 "%B2cc\t%r1, %0, %%g0"
6397 [(set_attr "type" "compare")])
6399 (define_insn "*cmp_ccx_arith_op_not"
6402 (match_operator:DI 2 "cc_arithopn"
6403 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6404 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6407 "%B2cc\t%r1, %0, %%g0"
6408 [(set_attr "type" "compare")])
6410 (define_insn "*cmp_cc_arith_op_not_set"
6413 (match_operator:SI 3 "cc_arithopn"
6414 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6415 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6417 (set (match_operand:SI 0 "register_operand" "=r")
6418 (match_operator:SI 4 "cc_arithopn"
6419 [(not:SI (match_dup 1)) (match_dup 2)]))]
6420 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6421 "%B3cc\t%r2, %1, %0"
6422 [(set_attr "type" "compare")])
6424 (define_insn "*cmp_ccx_arith_op_not_set"
6427 (match_operator:DI 3 "cc_arithopn"
6428 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6429 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6431 (set (match_operand:DI 0 "register_operand" "=r")
6432 (match_operator:DI 4 "cc_arithopn"
6433 [(not:DI (match_dup 1)) (match_dup 2)]))]
6434 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6435 "%B3cc\t%r2, %1, %0"
6436 [(set_attr "type" "compare")])
6438 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6439 ;; does not know how to make it work for constants.
6441 (define_expand "negdi2"
6442 [(set (match_operand:DI 0 "register_operand" "=r")
6443 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6446 if (! TARGET_ARCH64)
6448 emit_insn (gen_rtx_PARALLEL
6451 gen_rtx_SET (VOIDmode, operand0,
6452 gen_rtx_NEG (DImode, operand1)),
6453 gen_rtx_CLOBBER (VOIDmode,
6454 gen_rtx_REG (CCmode,
6460 (define_insn_and_split "*negdi2_sp32"
6461 [(set (match_operand:DI 0 "register_operand" "=r")
6462 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6463 (clobber (reg:CC 100))]
6466 "&& reload_completed"
6467 [(parallel [(set (reg:CC_NOOV 100)
6468 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6470 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6471 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6472 (ltu:SI (reg:CC 100) (const_int 0))))]
6473 "operands[2] = gen_highpart (SImode, operands[0]);
6474 operands[3] = gen_highpart (SImode, operands[1]);
6475 operands[4] = gen_lowpart (SImode, operands[0]);
6476 operands[5] = gen_lowpart (SImode, operands[1]);"
6477 [(set_attr "length" "2")])
6479 (define_insn "*negdi2_sp64"
6480 [(set (match_operand:DI 0 "register_operand" "=r")
6481 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6483 "sub\t%%g0, %1, %0")
6485 (define_insn "negsi2"
6486 [(set (match_operand:SI 0 "register_operand" "=r")
6487 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6489 "sub\t%%g0, %1, %0")
6491 (define_insn "*cmp_cc_neg"
6492 [(set (reg:CC_NOOV 100)
6493 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6496 "subcc\t%%g0, %0, %%g0"
6497 [(set_attr "type" "compare")])
6499 (define_insn "*cmp_ccx_neg"
6500 [(set (reg:CCX_NOOV 100)
6501 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6504 "subcc\t%%g0, %0, %%g0"
6505 [(set_attr "type" "compare")])
6507 (define_insn "*cmp_cc_set_neg"
6508 [(set (reg:CC_NOOV 100)
6509 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6511 (set (match_operand:SI 0 "register_operand" "=r")
6512 (neg:SI (match_dup 1)))]
6514 "subcc\t%%g0, %1, %0"
6515 [(set_attr "type" "compare")])
6517 (define_insn "*cmp_ccx_set_neg"
6518 [(set (reg:CCX_NOOV 100)
6519 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6521 (set (match_operand:DI 0 "register_operand" "=r")
6522 (neg:DI (match_dup 1)))]
6524 "subcc\t%%g0, %1, %0"
6525 [(set_attr "type" "compare")])
6527 ;; We cannot use the "not" pseudo insn because the Sun assembler
6528 ;; does not know how to make it work for constants.
6529 (define_expand "one_cmpldi2"
6530 [(set (match_operand:DI 0 "register_operand" "")
6531 (not:DI (match_operand:DI 1 "register_operand" "")))]
6535 (define_insn_and_split "*one_cmpldi2_sp32"
6536 [(set (match_operand:DI 0 "register_operand" "=r,b")
6537 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6542 "&& reload_completed
6543 && ((GET_CODE (operands[0]) == REG
6544 && REGNO (operands[0]) < 32)
6545 || (GET_CODE (operands[0]) == SUBREG
6546 && GET_CODE (SUBREG_REG (operands[0])) == REG
6547 && REGNO (SUBREG_REG (operands[0])) < 32))"
6548 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6549 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6550 "operands[2] = gen_highpart (SImode, operands[0]);
6551 operands[3] = gen_highpart (SImode, operands[1]);
6552 operands[4] = gen_lowpart (SImode, operands[0]);
6553 operands[5] = gen_lowpart (SImode, operands[1]);"
6554 [(set_attr "type" "*,fga")
6555 (set_attr "length" "2,*")
6556 (set_attr "fptype" "double")])
6558 (define_insn "*one_cmpldi2_sp64"
6559 [(set (match_operand:DI 0 "register_operand" "=r,b")
6560 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6565 [(set_attr "type" "*,fga")
6566 (set_attr "fptype" "double")])
6568 (define_insn "one_cmplsi2"
6569 [(set (match_operand:SI 0 "register_operand" "=r,d")
6570 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6575 [(set_attr "type" "*,fga")])
6577 (define_insn "*cmp_cc_not"
6579 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6582 "xnorcc\t%%g0, %0, %%g0"
6583 [(set_attr "type" "compare")])
6585 (define_insn "*cmp_ccx_not"
6587 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6590 "xnorcc\t%%g0, %0, %%g0"
6591 [(set_attr "type" "compare")])
6593 (define_insn "*cmp_cc_set_not"
6595 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6597 (set (match_operand:SI 0 "register_operand" "=r")
6598 (not:SI (match_dup 1)))]
6600 "xnorcc\t%%g0, %1, %0"
6601 [(set_attr "type" "compare")])
6603 (define_insn "*cmp_ccx_set_not"
6605 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6607 (set (match_operand:DI 0 "register_operand" "=r")
6608 (not:DI (match_dup 1)))]
6610 "xnorcc\t%%g0, %1, %0"
6611 [(set_attr "type" "compare")])
6613 (define_insn "*cmp_cc_set"
6614 [(set (match_operand:SI 0 "register_operand" "=r")
6615 (match_operand:SI 1 "register_operand" "r"))
6617 (compare:CC (match_dup 1)
6621 [(set_attr "type" "compare")])
6623 (define_insn "*cmp_ccx_set64"
6624 [(set (match_operand:DI 0 "register_operand" "=r")
6625 (match_operand:DI 1 "register_operand" "r"))
6627 (compare:CCX (match_dup 1)
6631 [(set_attr "type" "compare")])
6633 ;; Floating point arithmetic instructions.
6635 (define_expand "addtf3"
6636 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6637 (plus:TF (match_operand:TF 1 "general_operand" "")
6638 (match_operand:TF 2 "general_operand" "")))]
6639 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6640 "emit_tfmode_binop (PLUS, operands); DONE;")
6642 (define_insn "*addtf3_hq"
6643 [(set (match_operand:TF 0 "register_operand" "=e")
6644 (plus:TF (match_operand:TF 1 "register_operand" "e")
6645 (match_operand:TF 2 "register_operand" "e")))]
6646 "TARGET_FPU && TARGET_HARD_QUAD"
6648 [(set_attr "type" "fp")])
6650 (define_insn "adddf3"
6651 [(set (match_operand:DF 0 "register_operand" "=e")
6652 (plus:DF (match_operand:DF 1 "register_operand" "e")
6653 (match_operand:DF 2 "register_operand" "e")))]
6656 [(set_attr "type" "fp")
6657 (set_attr "fptype" "double")])
6659 (define_insn "addsf3"
6660 [(set (match_operand:SF 0 "register_operand" "=f")
6661 (plus:SF (match_operand:SF 1 "register_operand" "f")
6662 (match_operand:SF 2 "register_operand" "f")))]
6665 [(set_attr "type" "fp")])
6667 (define_expand "subtf3"
6668 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6669 (minus:TF (match_operand:TF 1 "general_operand" "")
6670 (match_operand:TF 2 "general_operand" "")))]
6671 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6672 "emit_tfmode_binop (MINUS, operands); DONE;")
6674 (define_insn "*subtf3_hq"
6675 [(set (match_operand:TF 0 "register_operand" "=e")
6676 (minus:TF (match_operand:TF 1 "register_operand" "e")
6677 (match_operand:TF 2 "register_operand" "e")))]
6678 "TARGET_FPU && TARGET_HARD_QUAD"
6680 [(set_attr "type" "fp")])
6682 (define_insn "subdf3"
6683 [(set (match_operand:DF 0 "register_operand" "=e")
6684 (minus:DF (match_operand:DF 1 "register_operand" "e")
6685 (match_operand:DF 2 "register_operand" "e")))]
6688 [(set_attr "type" "fp")
6689 (set_attr "fptype" "double")])
6691 (define_insn "subsf3"
6692 [(set (match_operand:SF 0 "register_operand" "=f")
6693 (minus:SF (match_operand:SF 1 "register_operand" "f")
6694 (match_operand:SF 2 "register_operand" "f")))]
6697 [(set_attr "type" "fp")])
6699 (define_expand "multf3"
6700 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6701 (mult:TF (match_operand:TF 1 "general_operand" "")
6702 (match_operand:TF 2 "general_operand" "")))]
6703 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6704 "emit_tfmode_binop (MULT, operands); DONE;")
6706 (define_insn "*multf3_hq"
6707 [(set (match_operand:TF 0 "register_operand" "=e")
6708 (mult:TF (match_operand:TF 1 "register_operand" "e")
6709 (match_operand:TF 2 "register_operand" "e")))]
6710 "TARGET_FPU && TARGET_HARD_QUAD"
6712 [(set_attr "type" "fpmul")])
6714 (define_insn "muldf3"
6715 [(set (match_operand:DF 0 "register_operand" "=e")
6716 (mult:DF (match_operand:DF 1 "register_operand" "e")
6717 (match_operand:DF 2 "register_operand" "e")))]
6720 [(set_attr "type" "fpmul")
6721 (set_attr "fptype" "double")])
6723 (define_insn "mulsf3"
6724 [(set (match_operand:SF 0 "register_operand" "=f")
6725 (mult:SF (match_operand:SF 1 "register_operand" "f")
6726 (match_operand:SF 2 "register_operand" "f")))]
6729 [(set_attr "type" "fpmul")])
6731 (define_insn "*muldf3_extend"
6732 [(set (match_operand:DF 0 "register_operand" "=e")
6733 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6734 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6735 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6736 "fsmuld\t%1, %2, %0"
6737 [(set_attr "type" "fpmul")
6738 (set_attr "fptype" "double")])
6740 (define_insn "*multf3_extend"
6741 [(set (match_operand:TF 0 "register_operand" "=e")
6742 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6743 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6744 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6745 "fdmulq\t%1, %2, %0"
6746 [(set_attr "type" "fpmul")])
6748 (define_expand "divtf3"
6749 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6750 (div:TF (match_operand:TF 1 "general_operand" "")
6751 (match_operand:TF 2 "general_operand" "")))]
6752 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6753 "emit_tfmode_binop (DIV, operands); DONE;")
6755 ;; don't have timing for quad-prec. divide.
6756 (define_insn "*divtf3_hq"
6757 [(set (match_operand:TF 0 "register_operand" "=e")
6758 (div:TF (match_operand:TF 1 "register_operand" "e")
6759 (match_operand:TF 2 "register_operand" "e")))]
6760 "TARGET_FPU && TARGET_HARD_QUAD"
6762 [(set_attr "type" "fpdivd")])
6764 (define_insn "divdf3"
6765 [(set (match_operand:DF 0 "register_operand" "=e")
6766 (div:DF (match_operand:DF 1 "register_operand" "e")
6767 (match_operand:DF 2 "register_operand" "e")))]
6770 [(set_attr "type" "fpdivd")
6771 (set_attr "fptype" "double")])
6773 (define_insn "divsf3"
6774 [(set (match_operand:SF 0 "register_operand" "=f")
6775 (div:SF (match_operand:SF 1 "register_operand" "f")
6776 (match_operand:SF 2 "register_operand" "f")))]
6779 [(set_attr "type" "fpdivs")])
6781 (define_expand "negtf2"
6782 [(set (match_operand:TF 0 "register_operand" "=e,e")
6783 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6787 (define_insn_and_split "*negtf2_notv9"
6788 [(set (match_operand:TF 0 "register_operand" "=e,e")
6789 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6790 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6796 "&& reload_completed
6797 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6798 [(set (match_dup 2) (neg:SF (match_dup 3)))
6799 (set (match_dup 4) (match_dup 5))
6800 (set (match_dup 6) (match_dup 7))]
6801 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6802 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6803 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6804 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6805 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6806 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6807 [(set_attr "type" "fpmove,*")
6808 (set_attr "length" "*,2")])
6810 (define_insn_and_split "*negtf2_v9"
6811 [(set (match_operand:TF 0 "register_operand" "=e,e")
6812 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6813 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6814 "TARGET_FPU && TARGET_V9"
6818 "&& reload_completed
6819 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6820 [(set (match_dup 2) (neg:DF (match_dup 3)))
6821 (set (match_dup 4) (match_dup 5))]
6822 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6823 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6824 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6825 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6826 [(set_attr "type" "fpmove,*")
6827 (set_attr "length" "*,2")
6828 (set_attr "fptype" "double")])
6830 (define_expand "negdf2"
6831 [(set (match_operand:DF 0 "register_operand" "")
6832 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6836 (define_insn_and_split "*negdf2_notv9"
6837 [(set (match_operand:DF 0 "register_operand" "=e,e")
6838 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6839 "TARGET_FPU && ! TARGET_V9"
6843 "&& reload_completed
6844 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6845 [(set (match_dup 2) (neg:SF (match_dup 3)))
6846 (set (match_dup 4) (match_dup 5))]
6847 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6848 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6849 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6850 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6851 [(set_attr "type" "fpmove,*")
6852 (set_attr "length" "*,2")])
6854 (define_insn "*negdf2_v9"
6855 [(set (match_operand:DF 0 "register_operand" "=e")
6856 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6857 "TARGET_FPU && TARGET_V9"
6859 [(set_attr "type" "fpmove")
6860 (set_attr "fptype" "double")])
6862 (define_insn "negsf2"
6863 [(set (match_operand:SF 0 "register_operand" "=f")
6864 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6867 [(set_attr "type" "fpmove")])
6869 (define_expand "abstf2"
6870 [(set (match_operand:TF 0 "register_operand" "")
6871 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6875 (define_insn_and_split "*abstf2_notv9"
6876 [(set (match_operand:TF 0 "register_operand" "=e,e")
6877 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6878 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6879 "TARGET_FPU && ! TARGET_V9"
6883 "&& reload_completed
6884 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6885 [(set (match_dup 2) (abs:SF (match_dup 3)))
6886 (set (match_dup 4) (match_dup 5))
6887 (set (match_dup 6) (match_dup 7))]
6888 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6889 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6890 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6891 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6892 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6893 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6894 [(set_attr "type" "fpmove,*")
6895 (set_attr "length" "*,2")])
6897 (define_insn "*abstf2_hq_v9"
6898 [(set (match_operand:TF 0 "register_operand" "=e,e")
6899 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6900 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6904 [(set_attr "type" "fpmove")
6905 (set_attr "fptype" "double,*")])
6907 (define_insn_and_split "*abstf2_v9"
6908 [(set (match_operand:TF 0 "register_operand" "=e,e")
6909 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6910 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6914 "&& reload_completed
6915 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6916 [(set (match_dup 2) (abs:DF (match_dup 3)))
6917 (set (match_dup 4) (match_dup 5))]
6918 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6919 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6920 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6921 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6922 [(set_attr "type" "fpmove,*")
6923 (set_attr "length" "*,2")
6924 (set_attr "fptype" "double,*")])
6926 (define_expand "absdf2"
6927 [(set (match_operand:DF 0 "register_operand" "")
6928 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6932 (define_insn_and_split "*absdf2_notv9"
6933 [(set (match_operand:DF 0 "register_operand" "=e,e")
6934 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6935 "TARGET_FPU && ! TARGET_V9"
6939 "&& reload_completed
6940 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6941 [(set (match_dup 2) (abs:SF (match_dup 3)))
6942 (set (match_dup 4) (match_dup 5))]
6943 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6944 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6945 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6946 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6947 [(set_attr "type" "fpmove,*")
6948 (set_attr "length" "*,2")])
6950 (define_insn "*absdf2_v9"
6951 [(set (match_operand:DF 0 "register_operand" "=e")
6952 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6953 "TARGET_FPU && TARGET_V9"
6955 [(set_attr "type" "fpmove")
6956 (set_attr "fptype" "double")])
6958 (define_insn "abssf2"
6959 [(set (match_operand:SF 0 "register_operand" "=f")
6960 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6963 [(set_attr "type" "fpmove")])
6965 (define_expand "sqrttf2"
6966 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6967 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6968 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6969 "emit_tfmode_unop (SQRT, operands); DONE;")
6971 (define_insn "*sqrttf2_hq"
6972 [(set (match_operand:TF 0 "register_operand" "=e")
6973 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6974 "TARGET_FPU && TARGET_HARD_QUAD"
6976 [(set_attr "type" "fpsqrtd")])
6978 (define_insn "sqrtdf2"
6979 [(set (match_operand:DF 0 "register_operand" "=e")
6980 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6983 [(set_attr "type" "fpsqrtd")
6984 (set_attr "fptype" "double")])
6986 (define_insn "sqrtsf2"
6987 [(set (match_operand:SF 0 "register_operand" "=f")
6988 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6991 [(set_attr "type" "fpsqrts")])
6993 ;;- arithmetic shift instructions
6995 (define_insn "ashlsi3"
6996 [(set (match_operand:SI 0 "register_operand" "=r")
6997 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6998 (match_operand:SI 2 "arith_operand" "rI")))]
7001 if (GET_CODE (operands[2]) == CONST_INT)
7002 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7003 return "sll\t%1, %2, %0";
7006 (if_then_else (match_operand 2 "const1_operand" "")
7007 (const_string "ialu") (const_string "shift")))])
7009 (define_expand "ashldi3"
7010 [(set (match_operand:DI 0 "register_operand" "=r")
7011 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7012 (match_operand:SI 2 "arith_operand" "rI")))]
7013 "TARGET_ARCH64 || TARGET_V8PLUS"
7015 if (! TARGET_ARCH64)
7017 if (GET_CODE (operands[2]) == CONST_INT)
7019 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7024 (define_insn "*ashldi3_sp64"
7025 [(set (match_operand:DI 0 "register_operand" "=r")
7026 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7027 (match_operand:SI 2 "arith_operand" "rI")))]
7030 if (GET_CODE (operands[2]) == CONST_INT)
7031 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7032 return "sllx\t%1, %2, %0";
7035 (if_then_else (match_operand 2 "const1_operand" "")
7036 (const_string "ialu") (const_string "shift")))])
7039 (define_insn "ashldi3_v8plus"
7040 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7041 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7042 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7043 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7045 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7046 [(set_attr "type" "multi")
7047 (set_attr "length" "5,5,6")])
7049 ;; Optimize (1LL<<x)-1
7050 ;; XXX this also needs to be fixed to handle equal subregs
7051 ;; XXX first before we could re-enable it.
7053 ; [(set (match_operand:DI 0 "register_operand" "=h")
7054 ; (plus:DI (ashift:DI (const_int 1)
7055 ; (match_operand:SI 1 "arith_operand" "rI"))
7057 ; "0 && TARGET_V8PLUS"
7059 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7060 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7061 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7063 ; [(set_attr "type" "multi")
7064 ; (set_attr "length" "4")])
7066 (define_insn "*cmp_cc_ashift_1"
7067 [(set (reg:CC_NOOV 100)
7068 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7072 "addcc\t%0, %0, %%g0"
7073 [(set_attr "type" "compare")])
7075 (define_insn "*cmp_cc_set_ashift_1"
7076 [(set (reg:CC_NOOV 100)
7077 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7080 (set (match_operand:SI 0 "register_operand" "=r")
7081 (ashift:SI (match_dup 1) (const_int 1)))]
7084 [(set_attr "type" "compare")])
7086 (define_insn "ashrsi3"
7087 [(set (match_operand:SI 0 "register_operand" "=r")
7088 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7089 (match_operand:SI 2 "arith_operand" "rI")))]
7092 if (GET_CODE (operands[2]) == CONST_INT)
7093 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7094 return "sra\t%1, %2, %0";
7096 [(set_attr "type" "shift")])
7098 (define_insn "*ashrsi3_extend"
7099 [(set (match_operand:DI 0 "register_operand" "=r")
7100 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7101 (match_operand:SI 2 "arith_operand" "r"))))]
7104 [(set_attr "type" "shift")])
7106 ;; This handles the case as above, but with constant shift instead of
7107 ;; register. Combiner "simplifies" it for us a little bit though.
7108 (define_insn "*ashrsi3_extend2"
7109 [(set (match_operand:DI 0 "register_operand" "=r")
7110 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7112 (match_operand:SI 2 "small_int_or_double" "n")))]
7114 && ((GET_CODE (operands[2]) == CONST_INT
7115 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7116 || (GET_CODE (operands[2]) == CONST_DOUBLE
7117 && !CONST_DOUBLE_HIGH (operands[2])
7118 && CONST_DOUBLE_LOW (operands[2]) >= 32
7119 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7121 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7123 return "sra\t%1, %2, %0";
7125 [(set_attr "type" "shift")])
7127 (define_expand "ashrdi3"
7128 [(set (match_operand:DI 0 "register_operand" "=r")
7129 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7130 (match_operand:SI 2 "arith_operand" "rI")))]
7131 "TARGET_ARCH64 || TARGET_V8PLUS"
7133 if (! TARGET_ARCH64)
7135 if (GET_CODE (operands[2]) == CONST_INT)
7136 FAIL; /* prefer generic code in this case */
7137 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7142 (define_insn "*ashrdi3_sp64"
7143 [(set (match_operand:DI 0 "register_operand" "=r")
7144 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7145 (match_operand:SI 2 "arith_operand" "rI")))]
7149 if (GET_CODE (operands[2]) == CONST_INT)
7150 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7151 return "srax\t%1, %2, %0";
7153 [(set_attr "type" "shift")])
7156 (define_insn "ashrdi3_v8plus"
7157 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7158 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7159 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7160 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7162 "* return output_v8plus_shift (operands, insn, \"srax\");"
7163 [(set_attr "type" "multi")
7164 (set_attr "length" "5,5,6")])
7166 (define_insn "lshrsi3"
7167 [(set (match_operand:SI 0 "register_operand" "=r")
7168 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7169 (match_operand:SI 2 "arith_operand" "rI")))]
7172 if (GET_CODE (operands[2]) == CONST_INT)
7173 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7174 return "srl\t%1, %2, %0";
7176 [(set_attr "type" "shift")])
7178 ;; This handles the case where
7179 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7180 ;; but combiner "simplifies" it for us.
7181 (define_insn "*lshrsi3_extend"
7182 [(set (match_operand:DI 0 "register_operand" "=r")
7183 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7184 (match_operand:SI 2 "arith_operand" "r")) 0)
7185 (match_operand 3 "" "")))]
7187 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7188 && CONST_DOUBLE_HIGH (operands[3]) == 0
7189 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7190 || (HOST_BITS_PER_WIDE_INT >= 64
7191 && GET_CODE (operands[3]) == CONST_INT
7192 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7194 [(set_attr "type" "shift")])
7196 ;; This handles the case where
7197 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7198 ;; but combiner "simplifies" it for us.
7199 (define_insn "*lshrsi3_extend2"
7200 [(set (match_operand:DI 0 "register_operand" "=r")
7201 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7202 (match_operand 2 "small_int_or_double" "n")
7205 && ((GET_CODE (operands[2]) == CONST_INT
7206 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7207 || (GET_CODE (operands[2]) == CONST_DOUBLE
7208 && CONST_DOUBLE_HIGH (operands[2]) == 0
7209 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7211 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7213 return "srl\t%1, %2, %0";
7215 [(set_attr "type" "shift")])
7217 (define_expand "lshrdi3"
7218 [(set (match_operand:DI 0 "register_operand" "=r")
7219 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7220 (match_operand:SI 2 "arith_operand" "rI")))]
7221 "TARGET_ARCH64 || TARGET_V8PLUS"
7223 if (! TARGET_ARCH64)
7225 if (GET_CODE (operands[2]) == CONST_INT)
7227 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7232 (define_insn "*lshrdi3_sp64"
7233 [(set (match_operand:DI 0 "register_operand" "=r")
7234 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7235 (match_operand:SI 2 "arith_operand" "rI")))]
7238 if (GET_CODE (operands[2]) == CONST_INT)
7239 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7240 return "srlx\t%1, %2, %0";
7242 [(set_attr "type" "shift")])
7245 (define_insn "lshrdi3_v8plus"
7246 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7247 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7248 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7249 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7251 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7252 [(set_attr "type" "multi")
7253 (set_attr "length" "5,5,6")])
7256 [(set (match_operand:SI 0 "register_operand" "=r")
7257 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7259 (match_operand:SI 2 "small_int_or_double" "n")))]
7261 && ((GET_CODE (operands[2]) == CONST_INT
7262 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7263 || (GET_CODE (operands[2]) == CONST_DOUBLE
7264 && !CONST_DOUBLE_HIGH (operands[2])
7265 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7267 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7269 return "srax\t%1, %2, %0";
7271 [(set_attr "type" "shift")])
7274 [(set (match_operand:SI 0 "register_operand" "=r")
7275 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7277 (match_operand:SI 2 "small_int_or_double" "n")))]
7279 && ((GET_CODE (operands[2]) == CONST_INT
7280 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7281 || (GET_CODE (operands[2]) == CONST_DOUBLE
7282 && !CONST_DOUBLE_HIGH (operands[2])
7283 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7285 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7287 return "srlx\t%1, %2, %0";
7289 [(set_attr "type" "shift")])
7292 [(set (match_operand:SI 0 "register_operand" "=r")
7293 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7294 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7295 (match_operand:SI 3 "small_int_or_double" "n")))]
7297 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7298 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7299 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7300 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7302 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7304 return "srax\t%1, %2, %0";
7306 [(set_attr "type" "shift")])
7309 [(set (match_operand:SI 0 "register_operand" "=r")
7310 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7311 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7312 (match_operand:SI 3 "small_int_or_double" "n")))]
7314 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7315 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7316 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7317 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7319 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7321 return "srlx\t%1, %2, %0";
7323 [(set_attr "type" "shift")])
7325 ;; Unconditional and other jump instructions
7327 [(set (pc) (label_ref (match_operand 0 "" "")))]
7329 "* return output_ubranch (operands[0], 0, insn);"
7330 [(set_attr "type" "uncond_branch")])
7332 (define_expand "tablejump"
7333 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7334 (use (label_ref (match_operand 1 "" "")))])]
7337 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7340 /* In pic mode, our address differences are against the base of the
7341 table. Add that base value back in; CSE ought to be able to combine
7342 the two address loads. */
7346 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7348 if (CASE_VECTOR_MODE != Pmode)
7349 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7350 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7351 operands[0] = memory_address (Pmode, tmp);
7355 (define_insn "*tablejump_sp32"
7356 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7357 (use (label_ref (match_operand 1 "" "")))]
7360 [(set_attr "type" "uncond_branch")])
7362 (define_insn "*tablejump_sp64"
7363 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7364 (use (label_ref (match_operand 1 "" "")))]
7367 [(set_attr "type" "uncond_branch")])
7369 ;;- jump to subroutine
7370 (define_expand "call"
7371 ;; Note that this expression is not used for generating RTL.
7372 ;; All the RTL is generated explicitly below.
7373 [(call (match_operand 0 "call_operand" "")
7374 (match_operand 3 "" "i"))]
7375 ;; operands[2] is next_arg_register
7376 ;; operands[3] is struct_value_size_rtx.
7381 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7384 if (GET_CODE (operands[3]) != CONST_INT)
7387 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7389 /* This is really a PIC sequence. We want to represent
7390 it as a funny jump so its delay slots can be filled.
7392 ??? But if this really *is* a CALL, will not it clobber the
7393 call-clobbered registers? We lose this if it is a JUMP_INSN.
7394 Why cannot we have delay slots filled if it were a CALL? */
7396 /* We accept negative sizes for untyped calls. */
7397 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7402 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7404 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7410 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7411 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7415 fn_rtx = operands[0];
7417 /* We accept negative sizes for untyped calls. */
7418 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7422 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7424 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7429 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7430 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7437 ;; We can't use the same pattern for these two insns, because then registers
7438 ;; in the address may not be properly reloaded.
7440 (define_insn "*call_address_sp32"
7441 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7442 (match_operand 1 "" ""))
7443 (clobber (reg:SI 15))]
7444 ;;- Do not use operand 1 for most machines.
7447 [(set_attr "type" "call")])
7449 (define_insn "*call_symbolic_sp32"
7450 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7451 (match_operand 1 "" ""))
7452 (clobber (reg:SI 15))]
7453 ;;- Do not use operand 1 for most machines.
7456 [(set_attr "type" "call")])
7458 (define_insn "*call_address_sp64"
7459 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7460 (match_operand 1 "" ""))
7461 (clobber (reg:DI 15))]
7462 ;;- Do not use operand 1 for most machines.
7465 [(set_attr "type" "call")])
7467 (define_insn "*call_symbolic_sp64"
7468 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7469 (match_operand 1 "" ""))
7470 (clobber (reg:DI 15))]
7471 ;;- Do not use operand 1 for most machines.
7474 [(set_attr "type" "call")])
7476 ;; This is a call that wants a structure value.
7477 ;; There is no such critter for v9 (??? we may need one anyway).
7478 (define_insn "*call_address_struct_value_sp32"
7479 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7480 (match_operand 1 "" ""))
7481 (match_operand 2 "immediate_operand" "")
7482 (clobber (reg:SI 15))]
7483 ;;- Do not use operand 1 for most machines.
7484 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7486 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7487 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7489 [(set_attr "type" "call_no_delay_slot")
7490 (set_attr "length" "3")])
7492 ;; This is a call that wants a structure value.
7493 ;; There is no such critter for v9 (??? we may need one anyway).
7494 (define_insn "*call_symbolic_struct_value_sp32"
7495 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7496 (match_operand 1 "" ""))
7497 (match_operand 2 "immediate_operand" "")
7498 (clobber (reg:SI 15))]
7499 ;;- Do not use operand 1 for most machines.
7500 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7502 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7503 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7505 [(set_attr "type" "call_no_delay_slot")
7506 (set_attr "length" "3")])
7508 ;; This is a call that may want a structure value. This is used for
7510 (define_insn "*call_address_untyped_struct_value_sp32"
7511 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7512 (match_operand 1 "" ""))
7513 (match_operand 2 "immediate_operand" "")
7514 (clobber (reg:SI 15))]
7515 ;;- Do not use operand 1 for most machines.
7516 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7517 "call\t%a0, %1\n\t nop\n\tnop"
7518 [(set_attr "type" "call_no_delay_slot")
7519 (set_attr "length" "3")])
7521 ;; This is a call that may want a structure value. This is used for
7523 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7524 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7525 (match_operand 1 "" ""))
7526 (match_operand 2 "immediate_operand" "")
7527 (clobber (reg:SI 15))]
7528 ;;- Do not use operand 1 for most machines.
7529 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7530 "call\t%a0, %1\n\t nop\n\tnop"
7531 [(set_attr "type" "call_no_delay_slot")
7532 (set_attr "length" "3")])
7534 (define_expand "call_value"
7535 ;; Note that this expression is not used for generating RTL.
7536 ;; All the RTL is generated explicitly below.
7537 [(set (match_operand 0 "register_operand" "=rf")
7538 (call (match_operand 1 "" "")
7539 (match_operand 4 "" "")))]
7540 ;; operand 2 is stack_size_rtx
7541 ;; operand 3 is next_arg_register
7547 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7550 fn_rtx = operands[1];
7553 gen_rtx_SET (VOIDmode, operands[0],
7554 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7555 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7557 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7562 (define_insn "*call_value_address_sp32"
7563 [(set (match_operand 0 "" "=rf")
7564 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7565 (match_operand 2 "" "")))
7566 (clobber (reg:SI 15))]
7567 ;;- Do not use operand 2 for most machines.
7570 [(set_attr "type" "call")])
7572 (define_insn "*call_value_symbolic_sp32"
7573 [(set (match_operand 0 "" "=rf")
7574 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7575 (match_operand 2 "" "")))
7576 (clobber (reg:SI 15))]
7577 ;;- Do not use operand 2 for most machines.
7580 [(set_attr "type" "call")])
7582 (define_insn "*call_value_address_sp64"
7583 [(set (match_operand 0 "" "")
7584 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7585 (match_operand 2 "" "")))
7586 (clobber (reg:DI 15))]
7587 ;;- Do not use operand 2 for most machines.
7590 [(set_attr "type" "call")])
7592 (define_insn "*call_value_symbolic_sp64"
7593 [(set (match_operand 0 "" "")
7594 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7595 (match_operand 2 "" "")))
7596 (clobber (reg:DI 15))]
7597 ;;- Do not use operand 2 for most machines.
7600 [(set_attr "type" "call")])
7602 (define_expand "untyped_call"
7603 [(parallel [(call (match_operand 0 "" "")
7605 (match_operand 1 "" "")
7606 (match_operand 2 "" "")])]
7611 /* Pass constm1 to indicate that it may expect a structure value, but
7612 we don't know what size it is. */
7613 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7615 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7617 rtx set = XVECEXP (operands[2], 0, i);
7618 emit_move_insn (SET_DEST (set), SET_SRC (set));
7621 /* The optimizer does not know that the call sets the function value
7622 registers we stored in the result block. We avoid problems by
7623 claiming that all hard registers are used and clobbered at this
7625 emit_insn (gen_blockage ());
7631 (define_expand "sibcall"
7632 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7637 (define_insn "*sibcall_symbolic_sp32"
7638 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7639 (match_operand 1 "" ""))
7642 "* return output_sibcall(insn, operands[0]);"
7643 [(set_attr "type" "sibcall")])
7645 (define_insn "*sibcall_symbolic_sp64"
7646 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7647 (match_operand 1 "" ""))
7650 "* return output_sibcall(insn, operands[0]);"
7651 [(set_attr "type" "sibcall")])
7653 (define_expand "sibcall_value"
7654 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7655 (call (match_operand 1 "" "") (const_int 0)))
7660 (define_insn "*sibcall_value_symbolic_sp32"
7661 [(set (match_operand 0 "" "=rf")
7662 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7663 (match_operand 2 "" "")))
7666 "* return output_sibcall(insn, operands[1]);"
7667 [(set_attr "type" "sibcall")])
7669 (define_insn "*sibcall_value_symbolic_sp64"
7670 [(set (match_operand 0 "" "")
7671 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7672 (match_operand 2 "" "")))
7675 "* return output_sibcall(insn, operands[1]);"
7676 [(set_attr "type" "sibcall")])
7678 (define_expand "sibcall_epilogue"
7682 sparc_expand_epilogue ();
7686 (define_expand "prologue"
7690 sparc_expand_prologue ();
7694 (define_expand "save_register_window"
7695 [(use (match_operand 0 "arith_operand" ""))]
7701 gen_rtx_SET (VOIDmode,
7703 gen_rtx_PLUS (Pmode,
7704 hard_frame_pointer_rtx,
7706 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7707 gen_rtvec (1, const0_rtx),
7710 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7714 (define_insn "*save_register_windowsi"
7715 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7716 (match_operand:SI 0 "arith_operand" "rI")))
7717 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7719 "save\t%%sp, %0, %%sp"
7720 [(set_attr "type" "savew")])
7722 (define_insn "*save_register_windowdi"
7723 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7724 (match_operand:DI 0 "arith_operand" "rI")))
7725 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7727 "save\t%%sp, %0, %%sp"
7728 [(set_attr "type" "savew")])
7730 (define_expand "epilogue"
7734 sparc_expand_epilogue ();
7737 (define_expand "return"
7739 "sparc_can_use_return_insn_p ()"
7742 (define_insn "*return_internal"
7745 "* return output_return (insn);"
7746 [(set_attr "type" "return")
7747 (set (attr "length")
7748 (cond [(eq_attr "leaf_function" "true")
7749 (if_then_else (eq_attr "empty_delay_slot" "true")
7752 (eq_attr "calls_eh_return" "true")
7753 (if_then_else (eq_attr "delayed_branch" "true")
7754 (if_then_else (eq_attr "isa" "v9")
7757 (if_then_else (eq_attr "isa" "v9")
7760 (eq_attr "empty_delay_slot" "true")
7761 (if_then_else (eq_attr "delayed_branch" "true")
7766 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7767 ;; all of memory. This blocks insns from being moved across this point.
7769 (define_insn "blockage"
7770 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7773 [(set_attr "length" "0")])
7775 ;; Prepare to return any type including a structure value.
7777 (define_expand "untyped_return"
7778 [(match_operand:BLK 0 "memory_operand" "")
7779 (match_operand 1 "" "")]
7782 rtx valreg1 = gen_rtx_REG (DImode, 24);
7783 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7784 rtx result = operands[0];
7786 if (! TARGET_ARCH64)
7788 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7790 rtx value = gen_reg_rtx (SImode);
7792 /* Fetch the instruction where we will return to and see if it's an unimp
7793 instruction (the most significant 10 bits will be zero). If so,
7794 update the return address to skip the unimp instruction. */
7795 emit_move_insn (value,
7796 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7797 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7798 emit_insn (gen_update_return (rtnreg, value));
7801 /* Reload the function value registers. */
7802 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7803 emit_move_insn (valreg2,
7804 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7806 /* Put USE insns before the return. */
7807 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7808 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7810 /* Construct the return. */
7811 expand_naked_return ();
7816 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7817 ;; and parts of the compiler don't want to believe that the add is needed.
7819 (define_insn "update_return"
7820 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7821 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7824 if (flag_delayed_branch)
7825 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7827 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7829 [(set (attr "type") (const_string "multi"))
7830 (set (attr "length")
7831 (if_then_else (eq_attr "delayed_branch" "true")
7840 (define_expand "indirect_jump"
7841 [(set (pc) (match_operand 0 "address_operand" "p"))]
7845 (define_insn "*branch_sp32"
7846 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7849 [(set_attr "type" "uncond_branch")])
7851 (define_insn "*branch_sp64"
7852 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7855 [(set_attr "type" "uncond_branch")])
7857 (define_expand "nonlocal_goto"
7858 [(match_operand:SI 0 "general_operand" "")
7859 (match_operand:SI 1 "general_operand" "")
7860 (match_operand:SI 2 "general_operand" "")
7861 (match_operand:SI 3 "" "")]
7864 rtx lab = operands[1];
7865 rtx stack = operands[2];
7866 rtx fp = operands[3];
7869 /* Trap instruction to flush all the register windows. */
7870 emit_insn (gen_flush_register_windows ());
7872 /* Load the fp value for the containing fn into %fp. This is needed
7873 because STACK refers to %fp. Note that virtual register instantiation
7874 fails if the virtual %fp isn't set from a register. */
7875 if (GET_CODE (fp) != REG)
7876 fp = force_reg (Pmode, fp);
7877 emit_move_insn (virtual_stack_vars_rtx, fp);
7879 /* Find the containing function's current nonlocal goto handler,
7880 which will do any cleanups and then jump to the label. */
7881 labreg = gen_rtx_REG (Pmode, 8);
7882 emit_move_insn (labreg, lab);
7884 /* Restore %fp from stack pointer value for containing function.
7885 The restore insn that follows will move this to %sp,
7886 and reload the appropriate value into %fp. */
7887 emit_move_insn (hard_frame_pointer_rtx, stack);
7889 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7890 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7892 /* ??? The V9-specific version was disabled in rev 1.65. */
7893 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7898 ;; Special trap insn to flush register windows.
7899 (define_insn "flush_register_windows"
7900 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7902 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7903 [(set_attr "type" "flushw")])
7905 (define_insn "goto_handler_and_restore"
7906 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7907 "GET_MODE (operands[0]) == Pmode"
7909 if (flag_delayed_branch)
7910 return "jmp\t%0\n\t restore";
7912 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7914 [(set (attr "type") (const_string "multi"))
7915 (set (attr "length")
7916 (if_then_else (eq_attr "delayed_branch" "true")
7920 ;; For __builtin_setjmp we need to flush register windows iff the function
7921 ;; calls alloca as well, because otherwise the register window might be
7922 ;; saved after %sp adjustment and thus setjmp would crash
7923 (define_expand "builtin_setjmp_setup"
7924 [(match_operand 0 "register_operand" "r")]
7927 emit_insn (gen_do_builtin_setjmp_setup ());
7931 (define_insn "do_builtin_setjmp_setup"
7932 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7935 if (! current_function_calls_alloca)
7939 fputs ("\tflushw\n", asm_out_file);
7941 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7942 TARGET_ARCH64 ? 'x' : 'w',
7943 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7944 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7945 TARGET_ARCH64 ? 'x' : 'w',
7946 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7947 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7948 TARGET_ARCH64 ? 'x' : 'w',
7949 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7952 [(set_attr "type" "multi")
7953 (set (attr "length")
7954 (cond [(eq_attr "calls_alloca" "false")
7956 (eq_attr "isa" "!v9")
7958 (eq_attr "pic" "true")
7959 (const_int 4)] (const_int 3)))])
7961 ;; Pattern for use after a setjmp to store FP and the return register
7962 ;; into the stack area.
7964 (define_expand "setjmp"
7969 emit_insn (gen_setjmp_64 ());
7971 emit_insn (gen_setjmp_32 ());
7975 (define_expand "setjmp_32"
7976 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7977 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7979 { operands[0] = frame_pointer_rtx; })
7981 (define_expand "setjmp_64"
7982 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7983 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7985 { operands[0] = frame_pointer_rtx; })
7987 ;; Special pattern for the FLUSH instruction.
7989 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7990 ; of the define_insn otherwise missing a mode. We make "flush", aka
7991 ; gen_flush, the default one since sparc_initialize_trampoline uses
7992 ; it on SImode mem values.
7994 (define_insn "flush"
7995 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7997 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7998 [(set_attr "type" "iflush")])
8000 (define_insn "flushdi"
8001 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8003 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8004 [(set_attr "type" "iflush")])
8009 ;; The scan instruction searches from the most significant bit while ffs
8010 ;; searches from the least significant bit. The bit index and treatment of
8011 ;; zero also differ. It takes at least 7 instructions to get the proper
8012 ;; result. Here is an obvious 8 instruction sequence.
8015 (define_insn "ffssi2"
8016 [(set (match_operand:SI 0 "register_operand" "=&r")
8017 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8018 (clobber (match_scratch:SI 2 "=&r"))]
8019 "TARGET_SPARCLITE || TARGET_SPARCLET"
8021 return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
8023 [(set_attr "type" "multi")
8024 (set_attr "length" "8")])
8026 ;; ??? This should be a define expand, so that the extra instruction have
8027 ;; a chance of being optimized away.
8029 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
8030 ;; does, but no one uses that and we don't have a switch for it.
8032 ;(define_insn "ffsdi2"
8033 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8034 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8035 ; (clobber (match_scratch:DI 2 "=&r"))]
8037 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8038 ; [(set_attr "type" "multi")
8039 ; (set_attr "length" "4")])
8043 ;; Peepholes go at the end.
8045 ;; Optimize consecutive loads or stores into ldd and std when possible.
8046 ;; The conditions in which we do this are very restricted and are
8047 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8050 [(set (match_operand:SI 0 "memory_operand" "")
8052 (set (match_operand:SI 1 "memory_operand" "")
8055 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8058 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8061 [(set (match_operand:SI 0 "memory_operand" "")
8063 (set (match_operand:SI 1 "memory_operand" "")
8066 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8069 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8072 [(set (match_operand:SI 0 "register_operand" "")
8073 (match_operand:SI 1 "memory_operand" ""))
8074 (set (match_operand:SI 2 "register_operand" "")
8075 (match_operand:SI 3 "memory_operand" ""))]
8076 "registers_ok_for_ldd_peep (operands[0], operands[2])
8077 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8080 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8081 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8084 [(set (match_operand:SI 0 "memory_operand" "")
8085 (match_operand:SI 1 "register_operand" ""))
8086 (set (match_operand:SI 2 "memory_operand" "")
8087 (match_operand:SI 3 "register_operand" ""))]
8088 "registers_ok_for_ldd_peep (operands[1], operands[3])
8089 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8092 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8093 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8096 [(set (match_operand:SF 0 "register_operand" "")
8097 (match_operand:SF 1 "memory_operand" ""))
8098 (set (match_operand:SF 2 "register_operand" "")
8099 (match_operand:SF 3 "memory_operand" ""))]
8100 "registers_ok_for_ldd_peep (operands[0], operands[2])
8101 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8104 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8105 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8108 [(set (match_operand:SF 0 "memory_operand" "")
8109 (match_operand:SF 1 "register_operand" ""))
8110 (set (match_operand:SF 2 "memory_operand" "")
8111 (match_operand:SF 3 "register_operand" ""))]
8112 "registers_ok_for_ldd_peep (operands[1], operands[3])
8113 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8116 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8117 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8120 [(set (match_operand:SI 0 "register_operand" "")
8121 (match_operand:SI 1 "memory_operand" ""))
8122 (set (match_operand:SI 2 "register_operand" "")
8123 (match_operand:SI 3 "memory_operand" ""))]
8124 "registers_ok_for_ldd_peep (operands[2], operands[0])
8125 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8128 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8129 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8132 [(set (match_operand:SI 0 "memory_operand" "")
8133 (match_operand:SI 1 "register_operand" ""))
8134 (set (match_operand:SI 2 "memory_operand" "")
8135 (match_operand:SI 3 "register_operand" ""))]
8136 "registers_ok_for_ldd_peep (operands[3], operands[1])
8137 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8140 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8141 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8145 [(set (match_operand:SF 0 "register_operand" "")
8146 (match_operand:SF 1 "memory_operand" ""))
8147 (set (match_operand:SF 2 "register_operand" "")
8148 (match_operand:SF 3 "memory_operand" ""))]
8149 "registers_ok_for_ldd_peep (operands[2], operands[0])
8150 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8153 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8154 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8157 [(set (match_operand:SF 0 "memory_operand" "")
8158 (match_operand:SF 1 "register_operand" ""))
8159 (set (match_operand:SF 2 "memory_operand" "")
8160 (match_operand:SF 3 "register_operand" ""))]
8161 "registers_ok_for_ldd_peep (operands[3], operands[1])
8162 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8165 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8166 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8168 ;; Optimize the case of following a reg-reg move with a test
8169 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8170 ;; This can result from a float to fix conversion.
8173 [(set (match_operand:SI 0 "register_operand" "")
8174 (match_operand:SI 1 "register_operand" ""))
8176 (compare:CC (match_operand:SI 2 "register_operand" "")
8178 "(rtx_equal_p (operands[2], operands[0])
8179 || rtx_equal_p (operands[2], operands[1]))
8180 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8181 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8182 [(parallel [(set (match_dup 0) (match_dup 1))
8184 (compare:CC (match_dup 1) (const_int 0)))])]
8188 [(set (match_operand:DI 0 "register_operand" "")
8189 (match_operand:DI 1 "register_operand" ""))
8191 (compare:CCX (match_operand:DI 2 "register_operand" "")
8194 && (rtx_equal_p (operands[2], operands[0])
8195 || rtx_equal_p (operands[2], operands[1]))
8196 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8197 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8198 [(parallel [(set (match_dup 0) (match_dup 1))
8200 (compare:CCX (match_dup 1) (const_int 0)))])]
8203 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8204 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8205 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8207 (define_expand "prefetch"
8208 [(match_operand 0 "address_operand" "")
8209 (match_operand 1 "const_int_operand" "")
8210 (match_operand 2 "const_int_operand" "")]
8214 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8216 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8220 (define_insn "prefetch_64"
8221 [(prefetch (match_operand:DI 0 "address_operand" "p")
8222 (match_operand:DI 1 "const_int_operand" "n")
8223 (match_operand:DI 2 "const_int_operand" "n"))]
8226 static const char * const prefetch_instr[2][2] = {
8228 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8229 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8232 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8233 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8236 int read_or_write = INTVAL (operands[1]);
8237 int locality = INTVAL (operands[2]);
8239 if (read_or_write != 0 && read_or_write != 1)
8241 if (locality < 0 || locality > 3)
8243 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8245 [(set_attr "type" "load")])
8247 (define_insn "prefetch_32"
8248 [(prefetch (match_operand:SI 0 "address_operand" "p")
8249 (match_operand:SI 1 "const_int_operand" "n")
8250 (match_operand:SI 2 "const_int_operand" "n"))]
8253 static const char * const prefetch_instr[2][2] = {
8255 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8256 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8259 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8260 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8263 int read_or_write = INTVAL (operands[1]);
8264 int locality = INTVAL (operands[2]);
8266 if (read_or_write != 0 && read_or_write != 1)
8268 if (locality < 0 || locality > 3)
8270 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8272 [(set_attr "type" "load")])
8275 [(trap_if (const_int 1) (const_int 5))]
8278 [(set_attr "type" "trap")])
8280 (define_expand "conditional_trap"
8281 [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8282 (match_operand:SI 1 "arith_operand" ""))]
8284 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8285 sparc_compare_op0, sparc_compare_op1);
8286 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8288 operands[3] = const0_rtx;")
8291 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8292 (match_operand:SI 1 "arith_operand" "rM"))]
8296 return "t%C0\t%%icc, %1";
8300 [(set_attr "type" "trap")])
8303 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8304 (match_operand:SI 1 "arith_operand" "rM"))]
8307 [(set_attr "type" "trap")])
8310 (define_insn "tgd_hi22"
8311 [(set (match_operand:SI 0 "register_operand" "=r")
8312 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8315 "sethi\\t%%tgd_hi22(%a1), %0")
8317 (define_insn "tgd_lo10"
8318 [(set (match_operand:SI 0 "register_operand" "=r")
8319 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8320 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8323 "add\\t%1, %%tgd_lo10(%a2), %0")
8325 (define_insn "tgd_add32"
8326 [(set (match_operand:SI 0 "register_operand" "=r")
8327 (plus:SI (match_operand:SI 1 "register_operand" "r")
8328 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8329 (match_operand 3 "tgd_symbolic_operand" "")]
8331 "TARGET_TLS && TARGET_ARCH32"
8332 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8334 (define_insn "tgd_add64"
8335 [(set (match_operand:DI 0 "register_operand" "=r")
8336 (plus:DI (match_operand:DI 1 "register_operand" "r")
8337 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8338 (match_operand 3 "tgd_symbolic_operand" "")]
8340 "TARGET_TLS && TARGET_ARCH64"
8341 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8343 (define_insn "tgd_call32"
8344 [(set (match_operand 0 "register_operand" "=r")
8345 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8346 (match_operand 2 "tgd_symbolic_operand" "")]
8348 (match_operand 3 "" "")))
8349 (clobber (reg:SI 15))]
8350 "TARGET_TLS && TARGET_ARCH32"
8351 "call\t%a1, %%tgd_call(%a2)%#"
8352 [(set_attr "type" "call")])
8354 (define_insn "tgd_call64"
8355 [(set (match_operand 0 "register_operand" "=r")
8356 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8357 (match_operand 2 "tgd_symbolic_operand" "")]
8359 (match_operand 3 "" "")))
8360 (clobber (reg:DI 15))]
8361 "TARGET_TLS && TARGET_ARCH64"
8362 "call\t%a1, %%tgd_call(%a2)%#"
8363 [(set_attr "type" "call")])
8365 (define_insn "tldm_hi22"
8366 [(set (match_operand:SI 0 "register_operand" "=r")
8367 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8369 "sethi\\t%%tldm_hi22(%&), %0")
8371 (define_insn "tldm_lo10"
8372 [(set (match_operand:SI 0 "register_operand" "=r")
8373 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8374 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8376 "add\\t%1, %%tldm_lo10(%&), %0")
8378 (define_insn "tldm_add32"
8379 [(set (match_operand:SI 0 "register_operand" "=r")
8380 (plus:SI (match_operand:SI 1 "register_operand" "r")
8381 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8383 "TARGET_TLS && TARGET_ARCH32"
8384 "add\\t%1, %2, %0, %%tldm_add(%&)")
8386 (define_insn "tldm_add64"
8387 [(set (match_operand:DI 0 "register_operand" "=r")
8388 (plus:DI (match_operand:DI 1 "register_operand" "r")
8389 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8391 "TARGET_TLS && TARGET_ARCH64"
8392 "add\\t%1, %2, %0, %%tldm_add(%&)")
8394 (define_insn "tldm_call32"
8395 [(set (match_operand 0 "register_operand" "=r")
8396 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8398 (match_operand 2 "" "")))
8399 (clobber (reg:SI 15))]
8400 "TARGET_TLS && TARGET_ARCH32"
8401 "call\t%a1, %%tldm_call(%&)%#"
8402 [(set_attr "type" "call")])
8404 (define_insn "tldm_call64"
8405 [(set (match_operand 0 "register_operand" "=r")
8406 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8408 (match_operand 2 "" "")))
8409 (clobber (reg:DI 15))]
8410 "TARGET_TLS && TARGET_ARCH64"
8411 "call\t%a1, %%tldm_call(%&)%#"
8412 [(set_attr "type" "call")])
8414 (define_insn "tldo_hix22"
8415 [(set (match_operand:SI 0 "register_operand" "=r")
8416 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8419 "sethi\\t%%tldo_hix22(%a1), %0")
8421 (define_insn "tldo_lox10"
8422 [(set (match_operand:SI 0 "register_operand" "=r")
8423 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8424 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8427 "xor\\t%1, %%tldo_lox10(%a2), %0")
8429 (define_insn "tldo_add32"
8430 [(set (match_operand:SI 0 "register_operand" "=r")
8431 (plus:SI (match_operand:SI 1 "register_operand" "r")
8432 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8433 (match_operand 3 "tld_symbolic_operand" "")]
8435 "TARGET_TLS && TARGET_ARCH32"
8436 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8438 (define_insn "tldo_add64"
8439 [(set (match_operand:DI 0 "register_operand" "=r")
8440 (plus:DI (match_operand:DI 1 "register_operand" "r")
8441 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8442 (match_operand 3 "tld_symbolic_operand" "")]
8444 "TARGET_TLS && TARGET_ARCH64"
8445 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8447 (define_insn "tie_hi22"
8448 [(set (match_operand:SI 0 "register_operand" "=r")
8449 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8452 "sethi\\t%%tie_hi22(%a1), %0")
8454 (define_insn "tie_lo10"
8455 [(set (match_operand:SI 0 "register_operand" "=r")
8456 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8457 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8460 "add\\t%1, %%tie_lo10(%a2), %0")
8462 (define_insn "tie_ld32"
8463 [(set (match_operand:SI 0 "register_operand" "=r")
8464 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8465 (match_operand:SI 2 "register_operand" "r")
8466 (match_operand 3 "tie_symbolic_operand" "")]
8468 "TARGET_TLS && TARGET_ARCH32"
8469 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8470 [(set_attr "type" "load")])
8472 (define_insn "tie_ld64"
8473 [(set (match_operand:DI 0 "register_operand" "=r")
8474 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8475 (match_operand:SI 2 "register_operand" "r")
8476 (match_operand 3 "tie_symbolic_operand" "")]
8478 "TARGET_TLS && TARGET_ARCH64"
8479 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8480 [(set_attr "type" "load")])
8482 (define_insn "tie_add32"
8483 [(set (match_operand:SI 0 "register_operand" "=r")
8484 (plus:SI (match_operand:SI 1 "register_operand" "r")
8485 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8486 (match_operand 3 "tie_symbolic_operand" "")]
8488 "TARGET_SUN_TLS && TARGET_ARCH32"
8489 "add\\t%1, %2, %0, %%tie_add(%a3)")
8491 (define_insn "tie_add64"
8492 [(set (match_operand:DI 0 "register_operand" "=r")
8493 (plus:DI (match_operand:DI 1 "register_operand" "r")
8494 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8495 (match_operand 3 "tie_symbolic_operand" "")]
8497 "TARGET_SUN_TLS && TARGET_ARCH64"
8498 "add\\t%1, %2, %0, %%tie_add(%a3)")
8500 (define_insn "tle_hix22_sp32"
8501 [(set (match_operand:SI 0 "register_operand" "=r")
8502 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8504 "TARGET_TLS && TARGET_ARCH32"
8505 "sethi\\t%%tle_hix22(%a1), %0")
8507 (define_insn "tle_lox10_sp32"
8508 [(set (match_operand:SI 0 "register_operand" "=r")
8509 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8510 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8512 "TARGET_TLS && TARGET_ARCH32"
8513 "xor\\t%1, %%tle_lox10(%a2), %0")
8515 (define_insn "tle_hix22_sp64"
8516 [(set (match_operand:DI 0 "register_operand" "=r")
8517 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8519 "TARGET_TLS && TARGET_ARCH64"
8520 "sethi\\t%%tle_hix22(%a1), %0")
8522 (define_insn "tle_lox10_sp64"
8523 [(set (match_operand:DI 0 "register_operand" "=r")
8524 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8525 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8527 "TARGET_TLS && TARGET_ARCH64"
8528 "xor\\t%1, %%tle_lox10(%a2), %0")
8530 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8531 (define_insn "*tldo_ldub_sp32"
8532 [(set (match_operand:QI 0 "register_operand" "=r")
8533 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8534 (match_operand 3 "tld_symbolic_operand" "")]
8536 (match_operand:SI 1 "register_operand" "r"))))]
8537 "TARGET_TLS && TARGET_ARCH32"
8538 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8539 [(set_attr "type" "load")
8540 (set_attr "us3load_type" "3cycle")])
8542 (define_insn "*tldo_ldub1_sp32"
8543 [(set (match_operand:HI 0 "register_operand" "=r")
8544 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8545 (match_operand 3 "tld_symbolic_operand" "")]
8547 (match_operand:SI 1 "register_operand" "r")))))]
8548 "TARGET_TLS && TARGET_ARCH32"
8549 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8550 [(set_attr "type" "load")
8551 (set_attr "us3load_type" "3cycle")])
8553 (define_insn "*tldo_ldub2_sp32"
8554 [(set (match_operand:SI 0 "register_operand" "=r")
8555 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8556 (match_operand 3 "tld_symbolic_operand" "")]
8558 (match_operand:SI 1 "register_operand" "r")))))]
8559 "TARGET_TLS && TARGET_ARCH32"
8560 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8561 [(set_attr "type" "load")
8562 (set_attr "us3load_type" "3cycle")])
8564 (define_insn "*tldo_ldsb1_sp32"
8565 [(set (match_operand:HI 0 "register_operand" "=r")
8566 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8567 (match_operand 3 "tld_symbolic_operand" "")]
8569 (match_operand:SI 1 "register_operand" "r")))))]
8570 "TARGET_TLS && TARGET_ARCH32"
8571 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8572 [(set_attr "type" "sload")
8573 (set_attr "us3load_type" "3cycle")])
8575 (define_insn "*tldo_ldsb2_sp32"
8576 [(set (match_operand:SI 0 "register_operand" "=r")
8577 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8578 (match_operand 3 "tld_symbolic_operand" "")]
8580 (match_operand:SI 1 "register_operand" "r")))))]
8581 "TARGET_TLS && TARGET_ARCH32"
8582 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8583 [(set_attr "type" "sload")
8584 (set_attr "us3load_type" "3cycle")])
8586 (define_insn "*tldo_ldub_sp64"
8587 [(set (match_operand:QI 0 "register_operand" "=r")
8588 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8589 (match_operand 3 "tld_symbolic_operand" "")]
8591 (match_operand:DI 1 "register_operand" "r"))))]
8592 "TARGET_TLS && TARGET_ARCH64"
8593 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8594 [(set_attr "type" "load")
8595 (set_attr "us3load_type" "3cycle")])
8597 (define_insn "*tldo_ldub1_sp64"
8598 [(set (match_operand:HI 0 "register_operand" "=r")
8599 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8600 (match_operand 3 "tld_symbolic_operand" "")]
8602 (match_operand:DI 1 "register_operand" "r")))))]
8603 "TARGET_TLS && TARGET_ARCH64"
8604 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8605 [(set_attr "type" "load")
8606 (set_attr "us3load_type" "3cycle")])
8608 (define_insn "*tldo_ldub2_sp64"
8609 [(set (match_operand:SI 0 "register_operand" "=r")
8610 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8611 (match_operand 3 "tld_symbolic_operand" "")]
8613 (match_operand:DI 1 "register_operand" "r")))))]
8614 "TARGET_TLS && TARGET_ARCH64"
8615 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8616 [(set_attr "type" "load")
8617 (set_attr "us3load_type" "3cycle")])
8619 (define_insn "*tldo_ldub3_sp64"
8620 [(set (match_operand:DI 0 "register_operand" "=r")
8621 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8622 (match_operand 3 "tld_symbolic_operand" "")]
8624 (match_operand:DI 1 "register_operand" "r")))))]
8625 "TARGET_TLS && TARGET_ARCH64"
8626 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8627 [(set_attr "type" "load")
8628 (set_attr "us3load_type" "3cycle")])
8630 (define_insn "*tldo_ldsb1_sp64"
8631 [(set (match_operand:HI 0 "register_operand" "=r")
8632 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8633 (match_operand 3 "tld_symbolic_operand" "")]
8635 (match_operand:DI 1 "register_operand" "r")))))]
8636 "TARGET_TLS && TARGET_ARCH64"
8637 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8638 [(set_attr "type" "sload")
8639 (set_attr "us3load_type" "3cycle")])
8641 (define_insn "*tldo_ldsb2_sp64"
8642 [(set (match_operand:SI 0 "register_operand" "=r")
8643 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8644 (match_operand 3 "tld_symbolic_operand" "")]
8646 (match_operand:DI 1 "register_operand" "r")))))]
8647 "TARGET_TLS && TARGET_ARCH64"
8648 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8649 [(set_attr "type" "sload")
8650 (set_attr "us3load_type" "3cycle")])
8652 (define_insn "*tldo_ldsb3_sp64"
8653 [(set (match_operand:DI 0 "register_operand" "=r")
8654 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8655 (match_operand 3 "tld_symbolic_operand" "")]
8657 (match_operand:DI 1 "register_operand" "r")))))]
8658 "TARGET_TLS && TARGET_ARCH64"
8659 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8660 [(set_attr "type" "sload")
8661 (set_attr "us3load_type" "3cycle")])
8663 (define_insn "*tldo_lduh_sp32"
8664 [(set (match_operand:HI 0 "register_operand" "=r")
8665 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8666 (match_operand 3 "tld_symbolic_operand" "")]
8668 (match_operand:SI 1 "register_operand" "r"))))]
8669 "TARGET_TLS && TARGET_ARCH32"
8670 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8671 [(set_attr "type" "load")
8672 (set_attr "us3load_type" "3cycle")])
8674 (define_insn "*tldo_lduh1_sp32"
8675 [(set (match_operand:SI 0 "register_operand" "=r")
8676 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8677 (match_operand 3 "tld_symbolic_operand" "")]
8679 (match_operand:SI 1 "register_operand" "r")))))]
8680 "TARGET_TLS && TARGET_ARCH32"
8681 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8682 [(set_attr "type" "load")
8683 (set_attr "us3load_type" "3cycle")])
8685 (define_insn "*tldo_ldsh1_sp32"
8686 [(set (match_operand:SI 0 "register_operand" "=r")
8687 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8688 (match_operand 3 "tld_symbolic_operand" "")]
8690 (match_operand:SI 1 "register_operand" "r")))))]
8691 "TARGET_TLS && TARGET_ARCH32"
8692 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8693 [(set_attr "type" "sload")
8694 (set_attr "us3load_type" "3cycle")])
8696 (define_insn "*tldo_lduh_sp64"
8697 [(set (match_operand:HI 0 "register_operand" "=r")
8698 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8699 (match_operand 3 "tld_symbolic_operand" "")]
8701 (match_operand:DI 1 "register_operand" "r"))))]
8702 "TARGET_TLS && TARGET_ARCH64"
8703 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8704 [(set_attr "type" "load")
8705 (set_attr "us3load_type" "3cycle")])
8707 (define_insn "*tldo_lduh1_sp64"
8708 [(set (match_operand:SI 0 "register_operand" "=r")
8709 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8710 (match_operand 3 "tld_symbolic_operand" "")]
8712 (match_operand:DI 1 "register_operand" "r")))))]
8713 "TARGET_TLS && TARGET_ARCH64"
8714 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8715 [(set_attr "type" "load")
8716 (set_attr "us3load_type" "3cycle")])
8718 (define_insn "*tldo_lduh2_sp64"
8719 [(set (match_operand:DI 0 "register_operand" "=r")
8720 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8721 (match_operand 3 "tld_symbolic_operand" "")]
8723 (match_operand:DI 1 "register_operand" "r")))))]
8724 "TARGET_TLS && TARGET_ARCH64"
8725 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8726 [(set_attr "type" "load")
8727 (set_attr "us3load_type" "3cycle")])
8729 (define_insn "*tldo_ldsh1_sp64"
8730 [(set (match_operand:SI 0 "register_operand" "=r")
8731 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8732 (match_operand 3 "tld_symbolic_operand" "")]
8734 (match_operand:DI 1 "register_operand" "r")))))]
8735 "TARGET_TLS && TARGET_ARCH64"
8736 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8737 [(set_attr "type" "sload")
8738 (set_attr "us3load_type" "3cycle")])
8740 (define_insn "*tldo_ldsh2_sp64"
8741 [(set (match_operand:DI 0 "register_operand" "=r")
8742 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8743 (match_operand 3 "tld_symbolic_operand" "")]
8745 (match_operand:DI 1 "register_operand" "r")))))]
8746 "TARGET_TLS && TARGET_ARCH64"
8747 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8748 [(set_attr "type" "sload")
8749 (set_attr "us3load_type" "3cycle")])
8751 (define_insn "*tldo_lduw_sp32"
8752 [(set (match_operand:SI 0 "register_operand" "=r")
8753 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8754 (match_operand 3 "tld_symbolic_operand" "")]
8756 (match_operand:SI 1 "register_operand" "r"))))]
8757 "TARGET_TLS && TARGET_ARCH32"
8758 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8759 [(set_attr "type" "load")])
8761 (define_insn "*tldo_lduw_sp64"
8762 [(set (match_operand:SI 0 "register_operand" "=r")
8763 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8764 (match_operand 3 "tld_symbolic_operand" "")]
8766 (match_operand:DI 1 "register_operand" "r"))))]
8767 "TARGET_TLS && TARGET_ARCH64"
8768 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8769 [(set_attr "type" "load")])
8771 (define_insn "*tldo_lduw1_sp64"
8772 [(set (match_operand:DI 0 "register_operand" "=r")
8773 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8774 (match_operand 3 "tld_symbolic_operand" "")]
8776 (match_operand:DI 1 "register_operand" "r")))))]
8777 "TARGET_TLS && TARGET_ARCH64"
8778 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8779 [(set_attr "type" "load")])
8781 (define_insn "*tldo_ldsw1_sp64"
8782 [(set (match_operand:DI 0 "register_operand" "=r")
8783 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8784 (match_operand 3 "tld_symbolic_operand" "")]
8786 (match_operand:DI 1 "register_operand" "r")))))]
8787 "TARGET_TLS && TARGET_ARCH64"
8788 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8789 [(set_attr "type" "sload")
8790 (set_attr "us3load_type" "3cycle")])
8792 (define_insn "*tldo_ldx_sp64"
8793 [(set (match_operand:DI 0 "register_operand" "=r")
8794 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8795 (match_operand 3 "tld_symbolic_operand" "")]
8797 (match_operand:DI 1 "register_operand" "r"))))]
8798 "TARGET_TLS && TARGET_ARCH64"
8799 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8800 [(set_attr "type" "load")])
8802 (define_insn "*tldo_stb_sp32"
8803 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8804 (match_operand 3 "tld_symbolic_operand" "")]
8806 (match_operand:SI 1 "register_operand" "r")))
8807 (match_operand:QI 0 "register_operand" "=r"))]
8808 "TARGET_TLS && TARGET_ARCH32"
8809 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8810 [(set_attr "type" "store")])
8812 (define_insn "*tldo_stb_sp64"
8813 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8814 (match_operand 3 "tld_symbolic_operand" "")]
8816 (match_operand:DI 1 "register_operand" "r")))
8817 (match_operand:QI 0 "register_operand" "=r"))]
8818 "TARGET_TLS && TARGET_ARCH64"
8819 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8820 [(set_attr "type" "store")])
8822 (define_insn "*tldo_sth_sp32"
8823 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8824 (match_operand 3 "tld_symbolic_operand" "")]
8826 (match_operand:SI 1 "register_operand" "r")))
8827 (match_operand:HI 0 "register_operand" "=r"))]
8828 "TARGET_TLS && TARGET_ARCH32"
8829 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8830 [(set_attr "type" "store")])
8832 (define_insn "*tldo_sth_sp64"
8833 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8834 (match_operand 3 "tld_symbolic_operand" "")]
8836 (match_operand:DI 1 "register_operand" "r")))
8837 (match_operand:HI 0 "register_operand" "=r"))]
8838 "TARGET_TLS && TARGET_ARCH64"
8839 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8840 [(set_attr "type" "store")])
8842 (define_insn "*tldo_stw_sp32"
8843 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8844 (match_operand 3 "tld_symbolic_operand" "")]
8846 (match_operand:SI 1 "register_operand" "r")))
8847 (match_operand:SI 0 "register_operand" "=r"))]
8848 "TARGET_TLS && TARGET_ARCH32"
8849 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8850 [(set_attr "type" "store")])
8852 (define_insn "*tldo_stw_sp64"
8853 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8854 (match_operand 3 "tld_symbolic_operand" "")]
8856 (match_operand:DI 1 "register_operand" "r")))
8857 (match_operand:SI 0 "register_operand" "=r"))]
8858 "TARGET_TLS && TARGET_ARCH64"
8859 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8860 [(set_attr "type" "store")])
8862 (define_insn "*tldo_stx_sp64"
8863 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8864 (match_operand 3 "tld_symbolic_operand" "")]
8866 (match_operand:DI 1 "register_operand" "r")))
8867 (match_operand:DI 0 "register_operand" "=r"))]
8868 "TARGET_TLS && TARGET_ARCH64"
8869 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8870 [(set_attr "type" "store")])
8872 ;; Vector instructions.
8874 (define_insn "addv2si3"
8875 [(set (match_operand:V2SI 0 "register_operand" "=e")
8876 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%e")
8877 (match_operand:V2SI 2 "register_operand" "e")))]
8879 "fpadd32\t%1, %2, %0"
8880 [(set_attr "type" "fga")
8881 (set_attr "fptype" "double")])
8883 (define_insn "addv4hi3"
8884 [(set (match_operand:V4HI 0 "register_operand" "=e")
8885 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%e")
8886 (match_operand:V4HI 2 "register_operand" "e")))]
8888 "fpadd16\t%1, %2, %0"
8889 [(set_attr "type" "fga")
8890 (set_attr "fptype" "double")])
8892 ;; fpadd32s is emitted by the addsi3 pattern.
8894 (define_insn "addv2hi3"
8895 [(set (match_operand:V2HI 0 "register_operand" "=f")
8896 (plus:V2HI (match_operand:V2HI 1 "register_operand" "%f")
8897 (match_operand:V2HI 2 "register_operand" "f")))]
8899 "fpadd16s\t%1, %2, %0"
8900 [(set_attr "type" "fga")
8901 (set_attr "fptype" "single")])
8903 (define_insn "subv2si3"
8904 [(set (match_operand:V2SI 0 "register_operand" "=e")
8905 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8906 (match_operand:V2SI 2 "register_operand" "e")))]
8908 "fpsub32\t%1, %2, %0"
8909 [(set_attr "type" "fga")
8910 (set_attr "fptype" "double")])
8912 (define_insn "subv4hi3"
8913 [(set (match_operand:V4HI 0 "register_operand" "=e")
8914 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8915 (match_operand:V4HI 2 "register_operand" "e")))]
8917 "fpsub16\t%1, %2, %0"
8918 [(set_attr "type" "fga")
8919 (set_attr "fptype" "double")])
8921 ;; fpsub32s is emitted by the subsi3 pattern.
8923 (define_insn "subv2hi3"
8924 [(set (match_operand:V2HI 0 "register_operand" "=f")
8925 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8926 (match_operand:V2HI 2 "register_operand" "f")))]
8928 "fpsub16s\t%1, %2, %0"
8929 [(set_attr "type" "fga")
8930 (set_attr "fptype" "single")])