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")])
5067 (define_insn "*cmp_cc_plus"
5068 [(set (reg:CC_NOOV 100)
5069 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5070 (match_operand:SI 1 "arith_operand" "rI"))
5073 "addcc\t%0, %1, %%g0"
5074 [(set_attr "type" "compare")])
5076 (define_insn "*cmp_ccx_plus"
5077 [(set (reg:CCX_NOOV 100)
5078 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5079 (match_operand:DI 1 "arith_double_operand" "rHI"))
5082 "addcc\t%0, %1, %%g0"
5083 [(set_attr "type" "compare")])
5085 (define_insn "*cmp_cc_plus_set"
5086 [(set (reg:CC_NOOV 100)
5087 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5088 (match_operand:SI 2 "arith_operand" "rI"))
5090 (set (match_operand:SI 0 "register_operand" "=r")
5091 (plus:SI (match_dup 1) (match_dup 2)))]
5094 [(set_attr "type" "compare")])
5096 (define_insn "*cmp_ccx_plus_set"
5097 [(set (reg:CCX_NOOV 100)
5098 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5099 (match_operand:DI 2 "arith_double_operand" "rHI"))
5101 (set (match_operand:DI 0 "register_operand" "=r")
5102 (plus:DI (match_dup 1) (match_dup 2)))]
5105 [(set_attr "type" "compare")])
5107 (define_expand "subdi3"
5108 [(set (match_operand:DI 0 "register_operand" "")
5109 (minus:DI (match_operand:DI 1 "register_operand" "")
5110 (match_operand:DI 2 "arith_double_add_operand" "")))]
5113 if (! TARGET_ARCH64)
5115 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5116 gen_rtx_SET (VOIDmode, operands[0],
5117 gen_rtx_MINUS (DImode, operands[1],
5119 gen_rtx_CLOBBER (VOIDmode,
5120 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5125 (define_insn_and_split "*subdi3_sp32"
5126 [(set (match_operand:DI 0 "register_operand" "=r")
5127 (minus:DI (match_operand:DI 1 "register_operand" "r")
5128 (match_operand:DI 2 "arith_double_operand" "rHI")))
5129 (clobber (reg:CC 100))]
5132 "&& reload_completed
5133 && (GET_CODE (operands[2]) == CONST_INT
5134 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5135 [(clobber (const_int 0))]
5139 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5140 lowp = gen_lowpart (SImode, operands[2]);
5141 if ((lowp == const0_rtx)
5142 && (operands[0] == operands[1]))
5144 emit_insn (gen_rtx_SET (VOIDmode,
5145 gen_highpart (SImode, operands[0]),
5146 gen_rtx_MINUS (SImode,
5147 gen_highpart_mode (SImode, DImode,
5153 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5154 gen_lowpart (SImode, operands[1]),
5156 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5157 gen_highpart_mode (SImode, DImode, operands[1]),
5162 [(set_attr "length" "2")])
5165 [(set (match_operand:DI 0 "register_operand" "")
5166 (minus:DI (match_operand:DI 1 "register_operand" "")
5167 (match_operand:DI 2 "register_operand" "")))
5168 (clobber (reg:CC 100))]
5170 && reload_completed"
5171 [(clobber (const_int 0))]
5173 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5174 gen_lowpart (SImode, operands[1]),
5175 gen_lowpart (SImode, operands[2])));
5176 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5177 gen_highpart (SImode, operands[1]),
5178 gen_highpart (SImode, operands[2])));
5182 (define_insn_and_split ""
5183 [(set (match_operand:DI 0 "register_operand" "=r")
5184 (minus:DI (match_operand:DI 1 "register_operand" "r")
5185 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5186 (clobber (reg:CC 100))]
5189 "&& reload_completed"
5190 [(parallel [(set (reg:CC_NOOV 100)
5191 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5193 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5195 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5196 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5197 "operands[3] = gen_lowpart (SImode, operands[1]);
5198 operands[4] = gen_highpart (SImode, operands[1]);
5199 operands[5] = gen_lowpart (SImode, operands[0]);
5200 operands[6] = gen_highpart (SImode, operands[0]);"
5201 [(set_attr "length" "2")])
5203 (define_insn "*subdi3_sp64"
5204 [(set (match_operand:DI 0 "register_operand" "=r,r")
5205 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5206 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5212 (define_insn "subsi3"
5213 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5214 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5215 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5220 fpsub32s\t%1, %2, %0"
5221 [(set_attr "type" "*,*,fga")])
5223 (define_insn "*cmp_minus_cc"
5224 [(set (reg:CC_NOOV 100)
5225 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5226 (match_operand:SI 1 "arith_operand" "rI"))
5229 "subcc\t%r0, %1, %%g0"
5230 [(set_attr "type" "compare")])
5232 (define_insn "*cmp_minus_ccx"
5233 [(set (reg:CCX_NOOV 100)
5234 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5235 (match_operand:DI 1 "arith_double_operand" "rHI"))
5238 "subcc\t%0, %1, %%g0"
5239 [(set_attr "type" "compare")])
5241 (define_insn "cmp_minus_cc_set"
5242 [(set (reg:CC_NOOV 100)
5243 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5244 (match_operand:SI 2 "arith_operand" "rI"))
5246 (set (match_operand:SI 0 "register_operand" "=r")
5247 (minus:SI (match_dup 1) (match_dup 2)))]
5249 "subcc\t%r1, %2, %0"
5250 [(set_attr "type" "compare")])
5252 (define_insn "*cmp_minus_ccx_set"
5253 [(set (reg:CCX_NOOV 100)
5254 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5255 (match_operand:DI 2 "arith_double_operand" "rHI"))
5257 (set (match_operand:DI 0 "register_operand" "=r")
5258 (minus:DI (match_dup 1) (match_dup 2)))]
5261 [(set_attr "type" "compare")])
5263 ;; Integer Multiply/Divide.
5265 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5266 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5268 (define_insn "mulsi3"
5269 [(set (match_operand:SI 0 "register_operand" "=r")
5270 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5271 (match_operand:SI 2 "arith_operand" "rI")))]
5274 [(set_attr "type" "imul")])
5276 (define_expand "muldi3"
5277 [(set (match_operand:DI 0 "register_operand" "=r")
5278 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5279 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5280 "TARGET_ARCH64 || TARGET_V8PLUS"
5284 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5289 (define_insn "*muldi3_sp64"
5290 [(set (match_operand:DI 0 "register_operand" "=r")
5291 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5292 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5295 [(set_attr "type" "imul")])
5297 ;; V8plus wide multiply.
5299 (define_insn "muldi3_v8plus"
5300 [(set (match_operand:DI 0 "register_operand" "=r,h")
5301 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5302 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5303 (clobber (match_scratch:SI 3 "=&h,X"))
5304 (clobber (match_scratch:SI 4 "=&h,X"))]
5307 if (sparc_check_64 (operands[1], insn) <= 0)
5308 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5309 if (which_alternative == 1)
5310 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5311 if (GET_CODE (operands[2]) == CONST_INT)
5313 if (which_alternative == 1)
5314 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5316 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";
5318 else if (rtx_equal_p (operands[1], operands[2]))
5320 if (which_alternative == 1)
5321 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5323 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";
5325 if (sparc_check_64 (operands[2], insn) <= 0)
5326 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5327 if (which_alternative == 1)
5328 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";
5330 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";
5332 [(set_attr "type" "multi")
5333 (set_attr "length" "9,8")])
5335 (define_insn "*cmp_mul_set"
5337 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5338 (match_operand:SI 2 "arith_operand" "rI"))
5340 (set (match_operand:SI 0 "register_operand" "=r")
5341 (mult:SI (match_dup 1) (match_dup 2)))]
5342 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5343 "smulcc\t%1, %2, %0"
5344 [(set_attr "type" "imul")])
5346 (define_expand "mulsidi3"
5347 [(set (match_operand:DI 0 "register_operand" "")
5348 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5349 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5352 if (CONSTANT_P (operands[2]))
5355 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5357 else if (TARGET_ARCH32)
5358 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5361 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5367 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5372 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5373 ;; registers can hold 64 bit values in the V8plus environment.
5375 (define_insn "mulsidi3_v8plus"
5376 [(set (match_operand:DI 0 "register_operand" "=h,r")
5377 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5378 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5379 (clobber (match_scratch:SI 3 "=X,&h"))]
5382 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5383 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5384 [(set_attr "type" "multi")
5385 (set_attr "length" "2,3")])
5388 (define_insn "const_mulsidi3_v8plus"
5389 [(set (match_operand:DI 0 "register_operand" "=h,r")
5390 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5391 (match_operand:DI 2 "small_int" "I,I")))
5392 (clobber (match_scratch:SI 3 "=X,&h"))]
5395 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5396 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5397 [(set_attr "type" "multi")
5398 (set_attr "length" "2,3")])
5401 (define_insn "*mulsidi3_sp32"
5402 [(set (match_operand:DI 0 "register_operand" "=r")
5403 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5404 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5407 return TARGET_SPARCLET
5408 ? "smuld\t%1, %2, %L0"
5409 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5412 (if_then_else (eq_attr "isa" "sparclet")
5413 (const_string "imul") (const_string "multi")))
5414 (set (attr "length")
5415 (if_then_else (eq_attr "isa" "sparclet")
5416 (const_int 1) (const_int 2)))])
5418 (define_insn "*mulsidi3_sp64"
5419 [(set (match_operand:DI 0 "register_operand" "=r")
5420 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5421 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5422 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5424 [(set_attr "type" "imul")])
5426 ;; Extra pattern, because sign_extend of a constant isn't valid.
5429 (define_insn "const_mulsidi3_sp32"
5430 [(set (match_operand:DI 0 "register_operand" "=r")
5431 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5432 (match_operand:DI 2 "small_int" "I")))]
5435 return TARGET_SPARCLET
5436 ? "smuld\t%1, %2, %L0"
5437 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5440 (if_then_else (eq_attr "isa" "sparclet")
5441 (const_string "imul") (const_string "multi")))
5442 (set (attr "length")
5443 (if_then_else (eq_attr "isa" "sparclet")
5444 (const_int 1) (const_int 2)))])
5446 (define_insn "const_mulsidi3_sp64"
5447 [(set (match_operand:DI 0 "register_operand" "=r")
5448 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5449 (match_operand:DI 2 "small_int" "I")))]
5450 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5452 [(set_attr "type" "imul")])
5454 (define_expand "smulsi3_highpart"
5455 [(set (match_operand:SI 0 "register_operand" "")
5457 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5458 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5460 "TARGET_HARD_MUL && TARGET_ARCH32"
5462 if (CONSTANT_P (operands[2]))
5466 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5472 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5477 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5478 operands[2], GEN_INT (32)));
5484 (define_insn "smulsi3_highpart_v8plus"
5485 [(set (match_operand:SI 0 "register_operand" "=h,r")
5487 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5488 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5489 (match_operand:SI 3 "const_int_operand" "i,i"))))
5490 (clobber (match_scratch:SI 4 "=X,&h"))]
5493 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5494 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5495 [(set_attr "type" "multi")
5496 (set_attr "length" "2")])
5498 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5501 [(set (match_operand:SI 0 "register_operand" "=h,r")
5504 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5505 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5506 (match_operand:SI 3 "const_int_operand" "i,i"))
5508 (clobber (match_scratch:SI 4 "=X,&h"))]
5511 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5512 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5513 [(set_attr "type" "multi")
5514 (set_attr "length" "2")])
5517 (define_insn "const_smulsi3_highpart_v8plus"
5518 [(set (match_operand:SI 0 "register_operand" "=h,r")
5520 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5521 (match_operand:DI 2 "small_int" "i,i"))
5522 (match_operand:SI 3 "const_int_operand" "i,i"))))
5523 (clobber (match_scratch:SI 4 "=X,&h"))]
5526 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5527 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5528 [(set_attr "type" "multi")
5529 (set_attr "length" "2")])
5532 (define_insn "*smulsi3_highpart_sp32"
5533 [(set (match_operand:SI 0 "register_operand" "=r")
5535 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5536 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5539 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5540 [(set_attr "type" "multi")
5541 (set_attr "length" "2")])
5544 (define_insn "const_smulsi3_highpart"
5545 [(set (match_operand:SI 0 "register_operand" "=r")
5547 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5548 (match_operand:DI 2 "small_int" "i"))
5551 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5552 [(set_attr "type" "multi")
5553 (set_attr "length" "2")])
5555 (define_expand "umulsidi3"
5556 [(set (match_operand:DI 0 "register_operand" "")
5557 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5558 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5561 if (CONSTANT_P (operands[2]))
5564 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5566 else if (TARGET_ARCH32)
5567 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5570 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5576 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5582 (define_insn "umulsidi3_v8plus"
5583 [(set (match_operand:DI 0 "register_operand" "=h,r")
5584 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5585 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5586 (clobber (match_scratch:SI 3 "=X,&h"))]
5589 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5590 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5591 [(set_attr "type" "multi")
5592 (set_attr "length" "2,3")])
5595 (define_insn "*umulsidi3_sp32"
5596 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5598 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5601 return TARGET_SPARCLET
5602 ? "umuld\t%1, %2, %L0"
5603 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5606 (if_then_else (eq_attr "isa" "sparclet")
5607 (const_string "imul") (const_string "multi")))
5608 (set (attr "length")
5609 (if_then_else (eq_attr "isa" "sparclet")
5610 (const_int 1) (const_int 2)))])
5612 (define_insn "*umulsidi3_sp64"
5613 [(set (match_operand:DI 0 "register_operand" "=r")
5614 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5615 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5616 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5618 [(set_attr "type" "imul")])
5620 ;; Extra pattern, because sign_extend of a constant isn't valid.
5623 (define_insn "const_umulsidi3_sp32"
5624 [(set (match_operand:DI 0 "register_operand" "=r")
5625 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5626 (match_operand:DI 2 "uns_small_int" "")))]
5629 return TARGET_SPARCLET
5630 ? "umuld\t%1, %s2, %L0"
5631 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5634 (if_then_else (eq_attr "isa" "sparclet")
5635 (const_string "imul") (const_string "multi")))
5636 (set (attr "length")
5637 (if_then_else (eq_attr "isa" "sparclet")
5638 (const_int 1) (const_int 2)))])
5640 (define_insn "const_umulsidi3_sp64"
5641 [(set (match_operand:DI 0 "register_operand" "=r")
5642 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5643 (match_operand:DI 2 "uns_small_int" "")))]
5644 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5646 [(set_attr "type" "imul")])
5649 (define_insn "const_umulsidi3_v8plus"
5650 [(set (match_operand:DI 0 "register_operand" "=h,r")
5651 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5652 (match_operand:DI 2 "uns_small_int" "")))
5653 (clobber (match_scratch:SI 3 "=X,h"))]
5656 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5657 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5658 [(set_attr "type" "multi")
5659 (set_attr "length" "2,3")])
5661 (define_expand "umulsi3_highpart"
5662 [(set (match_operand:SI 0 "register_operand" "")
5664 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5665 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5667 "TARGET_HARD_MUL && TARGET_ARCH32"
5669 if (CONSTANT_P (operands[2]))
5673 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5679 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5684 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5685 operands[2], GEN_INT (32)));
5691 (define_insn "umulsi3_highpart_v8plus"
5692 [(set (match_operand:SI 0 "register_operand" "=h,r")
5694 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5695 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5696 (match_operand:SI 3 "const_int_operand" "i,i"))))
5697 (clobber (match_scratch:SI 4 "=X,h"))]
5700 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5701 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5702 [(set_attr "type" "multi")
5703 (set_attr "length" "2")])
5706 (define_insn "const_umulsi3_highpart_v8plus"
5707 [(set (match_operand:SI 0 "register_operand" "=h,r")
5709 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5710 (match_operand:DI 2 "uns_small_int" ""))
5711 (match_operand:SI 3 "const_int_operand" "i,i"))))
5712 (clobber (match_scratch:SI 4 "=X,h"))]
5715 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5716 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5717 [(set_attr "type" "multi")
5718 (set_attr "length" "2")])
5721 (define_insn "*umulsi3_highpart_sp32"
5722 [(set (match_operand:SI 0 "register_operand" "=r")
5724 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5725 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5728 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5729 [(set_attr "type" "multi")
5730 (set_attr "length" "2")])
5733 (define_insn "const_umulsi3_highpart"
5734 [(set (match_operand:SI 0 "register_operand" "=r")
5736 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5737 (match_operand:DI 2 "uns_small_int" ""))
5740 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5741 [(set_attr "type" "multi")
5742 (set_attr "length" "2")])
5744 ;; The v8 architecture specifies that there must be 3 instructions between
5745 ;; a y register write and a use of it for correct results.
5747 (define_expand "divsi3"
5748 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5749 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5750 (match_operand:SI 2 "input_operand" "rI,m")))
5751 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5752 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5756 operands[3] = gen_reg_rtx(SImode);
5757 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5758 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5764 (define_insn "divsi3_sp32"
5765 [(set (match_operand:SI 0 "register_operand" "=r,r")
5766 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5767 (match_operand:SI 2 "input_operand" "rI,m")))
5768 (clobber (match_scratch:SI 3 "=&r,&r"))]
5769 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5772 if (which_alternative == 0)
5774 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5776 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5779 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5781 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";
5783 [(set_attr "type" "multi")
5784 (set (attr "length")
5785 (if_then_else (eq_attr "isa" "v9")
5786 (const_int 4) (const_int 6)))])
5788 (define_insn "divsi3_sp64"
5789 [(set (match_operand:SI 0 "register_operand" "=r")
5790 (div:SI (match_operand:SI 1 "register_operand" "r")
5791 (match_operand:SI 2 "input_operand" "rI")))
5792 (use (match_operand:SI 3 "register_operand" "r"))]
5793 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5794 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5795 [(set_attr "type" "multi")
5796 (set_attr "length" "2")])
5798 (define_insn "divdi3"
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (div:DI (match_operand:DI 1 "register_operand" "r")
5801 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5804 [(set_attr "type" "idiv")])
5806 (define_insn "*cmp_sdiv_cc_set"
5808 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5809 (match_operand:SI 2 "arith_operand" "rI"))
5811 (set (match_operand:SI 0 "register_operand" "=r")
5812 (div:SI (match_dup 1) (match_dup 2)))
5813 (clobber (match_scratch:SI 3 "=&r"))]
5814 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5817 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5819 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5821 [(set_attr "type" "multi")
5822 (set (attr "length")
5823 (if_then_else (eq_attr "isa" "v9")
5824 (const_int 3) (const_int 6)))])
5827 (define_expand "udivsi3"
5828 [(set (match_operand:SI 0 "register_operand" "")
5829 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5830 (match_operand:SI 2 "input_operand" "")))]
5831 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5834 (define_insn "udivsi3_sp32"
5835 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5836 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5837 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5839 || TARGET_DEPRECATED_V8_INSNS)
5842 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5843 switch (which_alternative)
5846 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5848 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5850 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5853 [(set_attr "type" "multi")
5854 (set_attr "length" "5")])
5856 (define_insn "udivsi3_sp64"
5857 [(set (match_operand:SI 0 "register_operand" "=r")
5858 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5859 (match_operand:SI 2 "input_operand" "rI")))]
5860 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5861 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5862 [(set_attr "type" "multi")
5863 (set_attr "length" "2")])
5865 (define_insn "udivdi3"
5866 [(set (match_operand:DI 0 "register_operand" "=r")
5867 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5868 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5871 [(set_attr "type" "idiv")])
5873 (define_insn "*cmp_udiv_cc_set"
5875 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5876 (match_operand:SI 2 "arith_operand" "rI"))
5878 (set (match_operand:SI 0 "register_operand" "=r")
5879 (udiv:SI (match_dup 1) (match_dup 2)))]
5881 || TARGET_DEPRECATED_V8_INSNS"
5884 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5886 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5888 [(set_attr "type" "multi")
5889 (set (attr "length")
5890 (if_then_else (eq_attr "isa" "v9")
5891 (const_int 2) (const_int 5)))])
5893 ; sparclet multiply/accumulate insns
5895 (define_insn "*smacsi"
5896 [(set (match_operand:SI 0 "register_operand" "=r")
5897 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5898 (match_operand:SI 2 "arith_operand" "rI"))
5899 (match_operand:SI 3 "register_operand" "0")))]
5902 [(set_attr "type" "imul")])
5904 (define_insn "*smacdi"
5905 [(set (match_operand:DI 0 "register_operand" "=r")
5906 (plus:DI (mult:DI (sign_extend:DI
5907 (match_operand:SI 1 "register_operand" "%r"))
5909 (match_operand:SI 2 "register_operand" "r")))
5910 (match_operand:DI 3 "register_operand" "0")))]
5912 "smacd\t%1, %2, %L0"
5913 [(set_attr "type" "imul")])
5915 (define_insn "*umacdi"
5916 [(set (match_operand:DI 0 "register_operand" "=r")
5917 (plus:DI (mult:DI (zero_extend:DI
5918 (match_operand:SI 1 "register_operand" "%r"))
5920 (match_operand:SI 2 "register_operand" "r")))
5921 (match_operand:DI 3 "register_operand" "0")))]
5923 "umacd\t%1, %2, %L0"
5924 [(set_attr "type" "imul")])
5926 ;;- Boolean instructions
5927 ;; We define DImode `and' so with DImode `not' we can get
5928 ;; DImode `andn'. Other combinations are possible.
5930 (define_expand "anddi3"
5931 [(set (match_operand:DI 0 "register_operand" "")
5932 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5933 (match_operand:DI 2 "arith_double_operand" "")))]
5937 (define_insn "*anddi3_sp32"
5938 [(set (match_operand:DI 0 "register_operand" "=r,b")
5939 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5940 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5945 [(set_attr "type" "*,fga")
5946 (set_attr "length" "2,*")
5947 (set_attr "fptype" "double")])
5949 (define_insn "*anddi3_sp64"
5950 [(set (match_operand:DI 0 "register_operand" "=r,b")
5951 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5952 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5957 [(set_attr "type" "*,fga")
5958 (set_attr "fptype" "double")])
5960 (define_insn "andsi3"
5961 [(set (match_operand:SI 0 "register_operand" "=r,d")
5962 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5963 (match_operand:SI 2 "arith_operand" "rI,d")))]
5968 [(set_attr "type" "*,fga")])
5971 [(set (match_operand:SI 0 "register_operand" "")
5972 (and:SI (match_operand:SI 1 "register_operand" "")
5973 (match_operand:SI 2 "" "")))
5974 (clobber (match_operand:SI 3 "register_operand" ""))]
5975 "GET_CODE (operands[2]) == CONST_INT
5976 && !SMALL_INT32 (operands[2])
5977 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5978 [(set (match_dup 3) (match_dup 4))
5979 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5981 operands[4] = GEN_INT (~INTVAL (operands[2]));
5984 ;; Split DImode logical operations requiring two instructions.
5986 [(set (match_operand:DI 0 "register_operand" "")
5987 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5988 [(match_operand:DI 2 "register_operand" "")
5989 (match_operand:DI 3 "arith_double_operand" "")]))]
5992 && ((GET_CODE (operands[0]) == REG
5993 && REGNO (operands[0]) < 32)
5994 || (GET_CODE (operands[0]) == SUBREG
5995 && GET_CODE (SUBREG_REG (operands[0])) == REG
5996 && REGNO (SUBREG_REG (operands[0])) < 32))"
5997 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5998 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6000 operands[4] = gen_highpart (SImode, operands[0]);
6001 operands[5] = gen_lowpart (SImode, operands[0]);
6002 operands[6] = gen_highpart (SImode, operands[2]);
6003 operands[7] = gen_lowpart (SImode, operands[2]);
6004 #if HOST_BITS_PER_WIDE_INT == 32
6005 if (GET_CODE (operands[3]) == CONST_INT)
6007 if (INTVAL (operands[3]) < 0)
6008 operands[8] = constm1_rtx;
6010 operands[8] = const0_rtx;
6014 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6015 operands[9] = gen_lowpart (SImode, operands[3]);
6018 (define_insn_and_split "*and_not_di_sp32"
6019 [(set (match_operand:DI 0 "register_operand" "=r,b")
6020 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6021 (match_operand:DI 2 "register_operand" "r,b")))]
6025 fandnot1\t%1, %2, %0"
6026 "&& reload_completed
6027 && ((GET_CODE (operands[0]) == REG
6028 && REGNO (operands[0]) < 32)
6029 || (GET_CODE (operands[0]) == SUBREG
6030 && GET_CODE (SUBREG_REG (operands[0])) == REG
6031 && REGNO (SUBREG_REG (operands[0])) < 32))"
6032 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6033 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6034 "operands[3] = gen_highpart (SImode, operands[0]);
6035 operands[4] = gen_highpart (SImode, operands[1]);
6036 operands[5] = gen_highpart (SImode, operands[2]);
6037 operands[6] = gen_lowpart (SImode, operands[0]);
6038 operands[7] = gen_lowpart (SImode, operands[1]);
6039 operands[8] = gen_lowpart (SImode, operands[2]);"
6040 [(set_attr "type" "*,fga")
6041 (set_attr "length" "2,*")
6042 (set_attr "fptype" "double")])
6044 (define_insn "*and_not_di_sp64"
6045 [(set (match_operand:DI 0 "register_operand" "=r,b")
6046 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6047 (match_operand:DI 2 "register_operand" "r,b")))]
6051 fandnot1\t%1, %2, %0"
6052 [(set_attr "type" "*,fga")
6053 (set_attr "fptype" "double")])
6055 (define_insn "*and_not_si"
6056 [(set (match_operand:SI 0 "register_operand" "=r,d")
6057 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6058 (match_operand:SI 2 "register_operand" "r,d")))]
6062 fandnot1s\t%1, %2, %0"
6063 [(set_attr "type" "*,fga")])
6065 (define_expand "iordi3"
6066 [(set (match_operand:DI 0 "register_operand" "")
6067 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6068 (match_operand:DI 2 "arith_double_operand" "")))]
6072 (define_insn "*iordi3_sp32"
6073 [(set (match_operand:DI 0 "register_operand" "=r,b")
6074 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6075 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6080 [(set_attr "type" "*,fga")
6081 (set_attr "length" "2,*")
6082 (set_attr "fptype" "double")])
6084 (define_insn "*iordi3_sp64"
6085 [(set (match_operand:DI 0 "register_operand" "=r,b")
6086 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6087 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6092 [(set_attr "type" "*,fga")
6093 (set_attr "fptype" "double")])
6095 (define_insn "iorsi3"
6096 [(set (match_operand:SI 0 "register_operand" "=r,d")
6097 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6098 (match_operand:SI 2 "arith_operand" "rI,d")))]
6103 [(set_attr "type" "*,fga")])
6106 [(set (match_operand:SI 0 "register_operand" "")
6107 (ior:SI (match_operand:SI 1 "register_operand" "")
6108 (match_operand:SI 2 "" "")))
6109 (clobber (match_operand:SI 3 "register_operand" ""))]
6110 "GET_CODE (operands[2]) == CONST_INT
6111 && !SMALL_INT32 (operands[2])
6112 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6113 [(set (match_dup 3) (match_dup 4))
6114 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6116 operands[4] = GEN_INT (~INTVAL (operands[2]));
6119 (define_insn_and_split "*or_not_di_sp32"
6120 [(set (match_operand:DI 0 "register_operand" "=r,b")
6121 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6122 (match_operand:DI 2 "register_operand" "r,b")))]
6126 fornot1\t%1, %2, %0"
6127 "&& reload_completed
6128 && ((GET_CODE (operands[0]) == REG
6129 && REGNO (operands[0]) < 32)
6130 || (GET_CODE (operands[0]) == SUBREG
6131 && GET_CODE (SUBREG_REG (operands[0])) == REG
6132 && REGNO (SUBREG_REG (operands[0])) < 32))"
6133 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6134 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6135 "operands[3] = gen_highpart (SImode, operands[0]);
6136 operands[4] = gen_highpart (SImode, operands[1]);
6137 operands[5] = gen_highpart (SImode, operands[2]);
6138 operands[6] = gen_lowpart (SImode, operands[0]);
6139 operands[7] = gen_lowpart (SImode, operands[1]);
6140 operands[8] = gen_lowpart (SImode, operands[2]);"
6141 [(set_attr "type" "*,fga")
6142 (set_attr "length" "2,*")
6143 (set_attr "fptype" "double")])
6145 (define_insn "*or_not_di_sp64"
6146 [(set (match_operand:DI 0 "register_operand" "=r,b")
6147 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6148 (match_operand:DI 2 "register_operand" "r,b")))]
6152 fornot1\t%1, %2, %0"
6153 [(set_attr "type" "*,fga")
6154 (set_attr "fptype" "double")])
6156 (define_insn "*or_not_si"
6157 [(set (match_operand:SI 0 "register_operand" "=r,d")
6158 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6159 (match_operand:SI 2 "register_operand" "r,d")))]
6163 fornot1s\t%1, %2, %0"
6164 [(set_attr "type" "*,fga")])
6166 (define_expand "xordi3"
6167 [(set (match_operand:DI 0 "register_operand" "")
6168 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6169 (match_operand:DI 2 "arith_double_operand" "")))]
6173 (define_insn "*xordi3_sp32"
6174 [(set (match_operand:DI 0 "register_operand" "=r,b")
6175 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6176 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6181 [(set_attr "type" "*,fga")
6182 (set_attr "length" "2,*")
6183 (set_attr "fptype" "double")])
6185 (define_insn "*xordi3_sp64"
6186 [(set (match_operand:DI 0 "register_operand" "=r,b")
6187 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6188 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6193 [(set_attr "type" "*,fga")
6194 (set_attr "fptype" "double")])
6196 (define_insn "*xordi3_sp64_dbl"
6197 [(set (match_operand:DI 0 "register_operand" "=r")
6198 (xor:DI (match_operand:DI 1 "register_operand" "r")
6199 (match_operand:DI 2 "const64_operand" "")))]
6201 && HOST_BITS_PER_WIDE_INT != 64)"
6204 (define_insn "xorsi3"
6205 [(set (match_operand:SI 0 "register_operand" "=r,d")
6206 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6207 (match_operand:SI 2 "arith_operand" "rI,d")))]
6212 [(set_attr "type" "*,fga")])
6215 [(set (match_operand:SI 0 "register_operand" "")
6216 (xor:SI (match_operand:SI 1 "register_operand" "")
6217 (match_operand:SI 2 "" "")))
6218 (clobber (match_operand:SI 3 "register_operand" ""))]
6219 "GET_CODE (operands[2]) == CONST_INT
6220 && !SMALL_INT32 (operands[2])
6221 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6222 [(set (match_dup 3) (match_dup 4))
6223 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6225 operands[4] = GEN_INT (~INTVAL (operands[2]));
6229 [(set (match_operand:SI 0 "register_operand" "")
6230 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6231 (match_operand:SI 2 "" ""))))
6232 (clobber (match_operand:SI 3 "register_operand" ""))]
6233 "GET_CODE (operands[2]) == CONST_INT
6234 && !SMALL_INT32 (operands[2])
6235 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6236 [(set (match_dup 3) (match_dup 4))
6237 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6239 operands[4] = GEN_INT (~INTVAL (operands[2]));
6242 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6243 ;; Combine now canonicalizes to the rightmost expression.
6244 (define_insn_and_split "*xor_not_di_sp32"
6245 [(set (match_operand:DI 0 "register_operand" "=r,b")
6246 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6247 (match_operand:DI 2 "register_operand" "r,b"))))]
6252 "&& reload_completed
6253 && ((GET_CODE (operands[0]) == REG
6254 && REGNO (operands[0]) < 32)
6255 || (GET_CODE (operands[0]) == SUBREG
6256 && GET_CODE (SUBREG_REG (operands[0])) == REG
6257 && REGNO (SUBREG_REG (operands[0])) < 32))"
6258 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6259 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6260 "operands[3] = gen_highpart (SImode, operands[0]);
6261 operands[4] = gen_highpart (SImode, operands[1]);
6262 operands[5] = gen_highpart (SImode, operands[2]);
6263 operands[6] = gen_lowpart (SImode, operands[0]);
6264 operands[7] = gen_lowpart (SImode, operands[1]);
6265 operands[8] = gen_lowpart (SImode, operands[2]);"
6266 [(set_attr "type" "*,fga")
6267 (set_attr "length" "2,*")
6268 (set_attr "fptype" "double")])
6270 (define_insn "*xor_not_di_sp64"
6271 [(set (match_operand:DI 0 "register_operand" "=r,b")
6272 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6273 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6278 [(set_attr "type" "*,fga")
6279 (set_attr "fptype" "double")])
6281 (define_insn "*xor_not_si"
6282 [(set (match_operand:SI 0 "register_operand" "=r,d")
6283 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6284 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6289 [(set_attr "type" "*,fga")])
6291 ;; These correspond to the above in the case where we also (or only)
6292 ;; want to set the condition code.
6294 (define_insn "*cmp_cc_arith_op"
6297 (match_operator:SI 2 "cc_arithop"
6298 [(match_operand:SI 0 "arith_operand" "%r")
6299 (match_operand:SI 1 "arith_operand" "rI")])
6302 "%A2cc\t%0, %1, %%g0"
6303 [(set_attr "type" "compare")])
6305 (define_insn "*cmp_ccx_arith_op"
6308 (match_operator:DI 2 "cc_arithop"
6309 [(match_operand:DI 0 "arith_double_operand" "%r")
6310 (match_operand:DI 1 "arith_double_operand" "rHI")])
6313 "%A2cc\t%0, %1, %%g0"
6314 [(set_attr "type" "compare")])
6316 (define_insn "*cmp_cc_arith_op_set"
6319 (match_operator:SI 3 "cc_arithop"
6320 [(match_operand:SI 1 "arith_operand" "%r")
6321 (match_operand:SI 2 "arith_operand" "rI")])
6323 (set (match_operand:SI 0 "register_operand" "=r")
6324 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6325 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6327 [(set_attr "type" "compare")])
6329 (define_insn "*cmp_ccx_arith_op_set"
6332 (match_operator:DI 3 "cc_arithop"
6333 [(match_operand:DI 1 "arith_double_operand" "%r")
6334 (match_operand:DI 2 "arith_double_operand" "rHI")])
6336 (set (match_operand:DI 0 "register_operand" "=r")
6337 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6338 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6340 [(set_attr "type" "compare")])
6342 (define_insn "*cmp_cc_xor_not"
6345 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6346 (match_operand:SI 1 "arith_operand" "rI")))
6349 "xnorcc\t%r0, %1, %%g0"
6350 [(set_attr "type" "compare")])
6352 (define_insn "*cmp_ccx_xor_not"
6355 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6356 (match_operand:DI 1 "arith_double_operand" "rHI")))
6359 "xnorcc\t%r0, %1, %%g0"
6360 [(set_attr "type" "compare")])
6362 (define_insn "*cmp_cc_xor_not_set"
6365 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6366 (match_operand:SI 2 "arith_operand" "rI")))
6368 (set (match_operand:SI 0 "register_operand" "=r")
6369 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6371 "xnorcc\t%r1, %2, %0"
6372 [(set_attr "type" "compare")])
6374 (define_insn "*cmp_ccx_xor_not_set"
6377 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6378 (match_operand:DI 2 "arith_double_operand" "rHI")))
6380 (set (match_operand:DI 0 "register_operand" "=r")
6381 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6383 "xnorcc\t%r1, %2, %0"
6384 [(set_attr "type" "compare")])
6386 (define_insn "*cmp_cc_arith_op_not"
6389 (match_operator:SI 2 "cc_arithopn"
6390 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6391 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6394 "%B2cc\t%r1, %0, %%g0"
6395 [(set_attr "type" "compare")])
6397 (define_insn "*cmp_ccx_arith_op_not"
6400 (match_operator:DI 2 "cc_arithopn"
6401 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6402 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6405 "%B2cc\t%r1, %0, %%g0"
6406 [(set_attr "type" "compare")])
6408 (define_insn "*cmp_cc_arith_op_not_set"
6411 (match_operator:SI 3 "cc_arithopn"
6412 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6413 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6415 (set (match_operand:SI 0 "register_operand" "=r")
6416 (match_operator:SI 4 "cc_arithopn"
6417 [(not:SI (match_dup 1)) (match_dup 2)]))]
6418 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6419 "%B3cc\t%r2, %1, %0"
6420 [(set_attr "type" "compare")])
6422 (define_insn "*cmp_ccx_arith_op_not_set"
6425 (match_operator:DI 3 "cc_arithopn"
6426 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6427 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6429 (set (match_operand:DI 0 "register_operand" "=r")
6430 (match_operator:DI 4 "cc_arithopn"
6431 [(not:DI (match_dup 1)) (match_dup 2)]))]
6432 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6433 "%B3cc\t%r2, %1, %0"
6434 [(set_attr "type" "compare")])
6436 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6437 ;; does not know how to make it work for constants.
6439 (define_expand "negdi2"
6440 [(set (match_operand:DI 0 "register_operand" "=r")
6441 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6444 if (! TARGET_ARCH64)
6446 emit_insn (gen_rtx_PARALLEL
6449 gen_rtx_SET (VOIDmode, operand0,
6450 gen_rtx_NEG (DImode, operand1)),
6451 gen_rtx_CLOBBER (VOIDmode,
6452 gen_rtx_REG (CCmode,
6458 (define_insn_and_split "*negdi2_sp32"
6459 [(set (match_operand:DI 0 "register_operand" "=r")
6460 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6461 (clobber (reg:CC 100))]
6464 "&& reload_completed"
6465 [(parallel [(set (reg:CC_NOOV 100)
6466 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6468 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6469 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6470 (ltu:SI (reg:CC 100) (const_int 0))))]
6471 "operands[2] = gen_highpart (SImode, operands[0]);
6472 operands[3] = gen_highpart (SImode, operands[1]);
6473 operands[4] = gen_lowpart (SImode, operands[0]);
6474 operands[5] = gen_lowpart (SImode, operands[1]);"
6475 [(set_attr "length" "2")])
6477 (define_insn "*negdi2_sp64"
6478 [(set (match_operand:DI 0 "register_operand" "=r")
6479 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6481 "sub\t%%g0, %1, %0")
6483 (define_insn "negsi2"
6484 [(set (match_operand:SI 0 "register_operand" "=r")
6485 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6487 "sub\t%%g0, %1, %0")
6489 (define_insn "*cmp_cc_neg"
6490 [(set (reg:CC_NOOV 100)
6491 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6494 "subcc\t%%g0, %0, %%g0"
6495 [(set_attr "type" "compare")])
6497 (define_insn "*cmp_ccx_neg"
6498 [(set (reg:CCX_NOOV 100)
6499 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6502 "subcc\t%%g0, %0, %%g0"
6503 [(set_attr "type" "compare")])
6505 (define_insn "*cmp_cc_set_neg"
6506 [(set (reg:CC_NOOV 100)
6507 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6509 (set (match_operand:SI 0 "register_operand" "=r")
6510 (neg:SI (match_dup 1)))]
6512 "subcc\t%%g0, %1, %0"
6513 [(set_attr "type" "compare")])
6515 (define_insn "*cmp_ccx_set_neg"
6516 [(set (reg:CCX_NOOV 100)
6517 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6519 (set (match_operand:DI 0 "register_operand" "=r")
6520 (neg:DI (match_dup 1)))]
6522 "subcc\t%%g0, %1, %0"
6523 [(set_attr "type" "compare")])
6525 ;; We cannot use the "not" pseudo insn because the Sun assembler
6526 ;; does not know how to make it work for constants.
6527 (define_expand "one_cmpldi2"
6528 [(set (match_operand:DI 0 "register_operand" "")
6529 (not:DI (match_operand:DI 1 "register_operand" "")))]
6533 (define_insn_and_split "*one_cmpldi2_sp32"
6534 [(set (match_operand:DI 0 "register_operand" "=r,b")
6535 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6540 "&& reload_completed
6541 && ((GET_CODE (operands[0]) == REG
6542 && REGNO (operands[0]) < 32)
6543 || (GET_CODE (operands[0]) == SUBREG
6544 && GET_CODE (SUBREG_REG (operands[0])) == REG
6545 && REGNO (SUBREG_REG (operands[0])) < 32))"
6546 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6547 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6548 "operands[2] = gen_highpart (SImode, operands[0]);
6549 operands[3] = gen_highpart (SImode, operands[1]);
6550 operands[4] = gen_lowpart (SImode, operands[0]);
6551 operands[5] = gen_lowpart (SImode, operands[1]);"
6552 [(set_attr "type" "*,fga")
6553 (set_attr "length" "2,*")
6554 (set_attr "fptype" "double")])
6556 (define_insn "*one_cmpldi2_sp64"
6557 [(set (match_operand:DI 0 "register_operand" "=r,b")
6558 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6563 [(set_attr "type" "*,fga")
6564 (set_attr "fptype" "double")])
6566 (define_insn "one_cmplsi2"
6567 [(set (match_operand:SI 0 "register_operand" "=r,d")
6568 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6573 [(set_attr "type" "*,fga")])
6575 (define_insn "*cmp_cc_not"
6577 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6580 "xnorcc\t%%g0, %0, %%g0"
6581 [(set_attr "type" "compare")])
6583 (define_insn "*cmp_ccx_not"
6585 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6588 "xnorcc\t%%g0, %0, %%g0"
6589 [(set_attr "type" "compare")])
6591 (define_insn "*cmp_cc_set_not"
6593 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6595 (set (match_operand:SI 0 "register_operand" "=r")
6596 (not:SI (match_dup 1)))]
6598 "xnorcc\t%%g0, %1, %0"
6599 [(set_attr "type" "compare")])
6601 (define_insn "*cmp_ccx_set_not"
6603 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6605 (set (match_operand:DI 0 "register_operand" "=r")
6606 (not:DI (match_dup 1)))]
6608 "xnorcc\t%%g0, %1, %0"
6609 [(set_attr "type" "compare")])
6611 (define_insn "*cmp_cc_set"
6612 [(set (match_operand:SI 0 "register_operand" "=r")
6613 (match_operand:SI 1 "register_operand" "r"))
6615 (compare:CC (match_dup 1)
6619 [(set_attr "type" "compare")])
6621 (define_insn "*cmp_ccx_set64"
6622 [(set (match_operand:DI 0 "register_operand" "=r")
6623 (match_operand:DI 1 "register_operand" "r"))
6625 (compare:CCX (match_dup 1)
6629 [(set_attr "type" "compare")])
6631 ;; Floating point arithmetic instructions.
6633 (define_expand "addtf3"
6634 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6635 (plus:TF (match_operand:TF 1 "general_operand" "")
6636 (match_operand:TF 2 "general_operand" "")))]
6637 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6638 "emit_tfmode_binop (PLUS, operands); DONE;")
6640 (define_insn "*addtf3_hq"
6641 [(set (match_operand:TF 0 "register_operand" "=e")
6642 (plus:TF (match_operand:TF 1 "register_operand" "e")
6643 (match_operand:TF 2 "register_operand" "e")))]
6644 "TARGET_FPU && TARGET_HARD_QUAD"
6646 [(set_attr "type" "fp")])
6648 (define_insn "adddf3"
6649 [(set (match_operand:DF 0 "register_operand" "=e")
6650 (plus:DF (match_operand:DF 1 "register_operand" "e")
6651 (match_operand:DF 2 "register_operand" "e")))]
6654 [(set_attr "type" "fp")
6655 (set_attr "fptype" "double")])
6657 (define_insn "addsf3"
6658 [(set (match_operand:SF 0 "register_operand" "=f")
6659 (plus:SF (match_operand:SF 1 "register_operand" "f")
6660 (match_operand:SF 2 "register_operand" "f")))]
6663 [(set_attr "type" "fp")])
6665 (define_expand "subtf3"
6666 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6667 (minus:TF (match_operand:TF 1 "general_operand" "")
6668 (match_operand:TF 2 "general_operand" "")))]
6669 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6670 "emit_tfmode_binop (MINUS, operands); DONE;")
6672 (define_insn "*subtf3_hq"
6673 [(set (match_operand:TF 0 "register_operand" "=e")
6674 (minus:TF (match_operand:TF 1 "register_operand" "e")
6675 (match_operand:TF 2 "register_operand" "e")))]
6676 "TARGET_FPU && TARGET_HARD_QUAD"
6678 [(set_attr "type" "fp")])
6680 (define_insn "subdf3"
6681 [(set (match_operand:DF 0 "register_operand" "=e")
6682 (minus:DF (match_operand:DF 1 "register_operand" "e")
6683 (match_operand:DF 2 "register_operand" "e")))]
6686 [(set_attr "type" "fp")
6687 (set_attr "fptype" "double")])
6689 (define_insn "subsf3"
6690 [(set (match_operand:SF 0 "register_operand" "=f")
6691 (minus:SF (match_operand:SF 1 "register_operand" "f")
6692 (match_operand:SF 2 "register_operand" "f")))]
6695 [(set_attr "type" "fp")])
6697 (define_expand "multf3"
6698 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6699 (mult:TF (match_operand:TF 1 "general_operand" "")
6700 (match_operand:TF 2 "general_operand" "")))]
6701 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6702 "emit_tfmode_binop (MULT, operands); DONE;")
6704 (define_insn "*multf3_hq"
6705 [(set (match_operand:TF 0 "register_operand" "=e")
6706 (mult:TF (match_operand:TF 1 "register_operand" "e")
6707 (match_operand:TF 2 "register_operand" "e")))]
6708 "TARGET_FPU && TARGET_HARD_QUAD"
6710 [(set_attr "type" "fpmul")])
6712 (define_insn "muldf3"
6713 [(set (match_operand:DF 0 "register_operand" "=e")
6714 (mult:DF (match_operand:DF 1 "register_operand" "e")
6715 (match_operand:DF 2 "register_operand" "e")))]
6718 [(set_attr "type" "fpmul")
6719 (set_attr "fptype" "double")])
6721 (define_insn "mulsf3"
6722 [(set (match_operand:SF 0 "register_operand" "=f")
6723 (mult:SF (match_operand:SF 1 "register_operand" "f")
6724 (match_operand:SF 2 "register_operand" "f")))]
6727 [(set_attr "type" "fpmul")])
6729 (define_insn "*muldf3_extend"
6730 [(set (match_operand:DF 0 "register_operand" "=e")
6731 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6732 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6733 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6734 "fsmuld\t%1, %2, %0"
6735 [(set_attr "type" "fpmul")
6736 (set_attr "fptype" "double")])
6738 (define_insn "*multf3_extend"
6739 [(set (match_operand:TF 0 "register_operand" "=e")
6740 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6741 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6742 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6743 "fdmulq\t%1, %2, %0"
6744 [(set_attr "type" "fpmul")])
6746 (define_expand "divtf3"
6747 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6748 (div:TF (match_operand:TF 1 "general_operand" "")
6749 (match_operand:TF 2 "general_operand" "")))]
6750 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6751 "emit_tfmode_binop (DIV, operands); DONE;")
6753 ;; don't have timing for quad-prec. divide.
6754 (define_insn "*divtf3_hq"
6755 [(set (match_operand:TF 0 "register_operand" "=e")
6756 (div:TF (match_operand:TF 1 "register_operand" "e")
6757 (match_operand:TF 2 "register_operand" "e")))]
6758 "TARGET_FPU && TARGET_HARD_QUAD"
6760 [(set_attr "type" "fpdivd")])
6762 (define_insn "divdf3"
6763 [(set (match_operand:DF 0 "register_operand" "=e")
6764 (div:DF (match_operand:DF 1 "register_operand" "e")
6765 (match_operand:DF 2 "register_operand" "e")))]
6768 [(set_attr "type" "fpdivd")
6769 (set_attr "fptype" "double")])
6771 (define_insn "divsf3"
6772 [(set (match_operand:SF 0 "register_operand" "=f")
6773 (div:SF (match_operand:SF 1 "register_operand" "f")
6774 (match_operand:SF 2 "register_operand" "f")))]
6777 [(set_attr "type" "fpdivs")])
6779 (define_expand "negtf2"
6780 [(set (match_operand:TF 0 "register_operand" "=e,e")
6781 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6785 (define_insn_and_split "*negtf2_notv9"
6786 [(set (match_operand:TF 0 "register_operand" "=e,e")
6787 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6788 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6794 "&& reload_completed
6795 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6796 [(set (match_dup 2) (neg:SF (match_dup 3)))
6797 (set (match_dup 4) (match_dup 5))
6798 (set (match_dup 6) (match_dup 7))]
6799 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6800 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6801 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6802 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6803 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6804 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6805 [(set_attr "type" "fpmove,*")
6806 (set_attr "length" "*,2")])
6808 (define_insn_and_split "*negtf2_v9"
6809 [(set (match_operand:TF 0 "register_operand" "=e,e")
6810 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6811 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6812 "TARGET_FPU && TARGET_V9"
6816 "&& reload_completed
6817 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6818 [(set (match_dup 2) (neg:DF (match_dup 3)))
6819 (set (match_dup 4) (match_dup 5))]
6820 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6821 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6822 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6823 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6824 [(set_attr "type" "fpmove,*")
6825 (set_attr "length" "*,2")
6826 (set_attr "fptype" "double")])
6828 (define_expand "negdf2"
6829 [(set (match_operand:DF 0 "register_operand" "")
6830 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6834 (define_insn_and_split "*negdf2_notv9"
6835 [(set (match_operand:DF 0 "register_operand" "=e,e")
6836 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6837 "TARGET_FPU && ! TARGET_V9"
6841 "&& reload_completed
6842 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6843 [(set (match_dup 2) (neg:SF (match_dup 3)))
6844 (set (match_dup 4) (match_dup 5))]
6845 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6846 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6847 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6848 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6849 [(set_attr "type" "fpmove,*")
6850 (set_attr "length" "*,2")])
6852 (define_insn "*negdf2_v9"
6853 [(set (match_operand:DF 0 "register_operand" "=e")
6854 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6855 "TARGET_FPU && TARGET_V9"
6857 [(set_attr "type" "fpmove")
6858 (set_attr "fptype" "double")])
6860 (define_insn "negsf2"
6861 [(set (match_operand:SF 0 "register_operand" "=f")
6862 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6865 [(set_attr "type" "fpmove")])
6867 (define_expand "abstf2"
6868 [(set (match_operand:TF 0 "register_operand" "")
6869 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6873 (define_insn_and_split "*abstf2_notv9"
6874 [(set (match_operand:TF 0 "register_operand" "=e,e")
6875 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6876 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6877 "TARGET_FPU && ! TARGET_V9"
6881 "&& reload_completed
6882 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6883 [(set (match_dup 2) (abs:SF (match_dup 3)))
6884 (set (match_dup 4) (match_dup 5))
6885 (set (match_dup 6) (match_dup 7))]
6886 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6887 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6888 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6889 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6890 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6891 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6892 [(set_attr "type" "fpmove,*")
6893 (set_attr "length" "*,2")])
6895 (define_insn "*abstf2_hq_v9"
6896 [(set (match_operand:TF 0 "register_operand" "=e,e")
6897 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6898 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6902 [(set_attr "type" "fpmove")
6903 (set_attr "fptype" "double,*")])
6905 (define_insn_and_split "*abstf2_v9"
6906 [(set (match_operand:TF 0 "register_operand" "=e,e")
6907 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6908 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6912 "&& reload_completed
6913 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6914 [(set (match_dup 2) (abs:DF (match_dup 3)))
6915 (set (match_dup 4) (match_dup 5))]
6916 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6917 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6918 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6919 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6920 [(set_attr "type" "fpmove,*")
6921 (set_attr "length" "*,2")
6922 (set_attr "fptype" "double,*")])
6924 (define_expand "absdf2"
6925 [(set (match_operand:DF 0 "register_operand" "")
6926 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6930 (define_insn_and_split "*absdf2_notv9"
6931 [(set (match_operand:DF 0 "register_operand" "=e,e")
6932 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6933 "TARGET_FPU && ! TARGET_V9"
6937 "&& reload_completed
6938 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6939 [(set (match_dup 2) (abs:SF (match_dup 3)))
6940 (set (match_dup 4) (match_dup 5))]
6941 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6942 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6943 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6944 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6945 [(set_attr "type" "fpmove,*")
6946 (set_attr "length" "*,2")])
6948 (define_insn "*absdf2_v9"
6949 [(set (match_operand:DF 0 "register_operand" "=e")
6950 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6951 "TARGET_FPU && TARGET_V9"
6953 [(set_attr "type" "fpmove")
6954 (set_attr "fptype" "double")])
6956 (define_insn "abssf2"
6957 [(set (match_operand:SF 0 "register_operand" "=f")
6958 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6961 [(set_attr "type" "fpmove")])
6963 (define_expand "sqrttf2"
6964 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6965 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6966 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6967 "emit_tfmode_unop (SQRT, operands); DONE;")
6969 (define_insn "*sqrttf2_hq"
6970 [(set (match_operand:TF 0 "register_operand" "=e")
6971 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6972 "TARGET_FPU && TARGET_HARD_QUAD"
6974 [(set_attr "type" "fpsqrtd")])
6976 (define_insn "sqrtdf2"
6977 [(set (match_operand:DF 0 "register_operand" "=e")
6978 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6981 [(set_attr "type" "fpsqrtd")
6982 (set_attr "fptype" "double")])
6984 (define_insn "sqrtsf2"
6985 [(set (match_operand:SF 0 "register_operand" "=f")
6986 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6989 [(set_attr "type" "fpsqrts")])
6991 ;;- arithmetic shift instructions
6993 (define_insn "ashlsi3"
6994 [(set (match_operand:SI 0 "register_operand" "=r")
6995 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6996 (match_operand:SI 2 "arith_operand" "rI")))]
6999 if (GET_CODE (operands[2]) == CONST_INT)
7000 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7001 return "sll\t%1, %2, %0";
7004 (if_then_else (match_operand 2 "const1_operand" "")
7005 (const_string "ialu") (const_string "shift")))])
7007 (define_expand "ashldi3"
7008 [(set (match_operand:DI 0 "register_operand" "=r")
7009 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7010 (match_operand:SI 2 "arith_operand" "rI")))]
7011 "TARGET_ARCH64 || TARGET_V8PLUS"
7013 if (! TARGET_ARCH64)
7015 if (GET_CODE (operands[2]) == CONST_INT)
7017 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7022 (define_insn "*ashldi3_sp64"
7023 [(set (match_operand:DI 0 "register_operand" "=r")
7024 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7025 (match_operand:SI 2 "arith_operand" "rI")))]
7028 if (GET_CODE (operands[2]) == CONST_INT)
7029 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7030 return "sllx\t%1, %2, %0";
7033 (if_then_else (match_operand 2 "const1_operand" "")
7034 (const_string "ialu") (const_string "shift")))])
7037 (define_insn "ashldi3_v8plus"
7038 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7039 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7040 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7041 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7043 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7044 [(set_attr "type" "multi")
7045 (set_attr "length" "5,5,6")])
7047 ;; Optimize (1LL<<x)-1
7048 ;; XXX this also needs to be fixed to handle equal subregs
7049 ;; XXX first before we could re-enable it.
7051 ; [(set (match_operand:DI 0 "register_operand" "=h")
7052 ; (plus:DI (ashift:DI (const_int 1)
7053 ; (match_operand:SI 1 "arith_operand" "rI"))
7055 ; "0 && TARGET_V8PLUS"
7057 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7058 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7059 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7061 ; [(set_attr "type" "multi")
7062 ; (set_attr "length" "4")])
7064 (define_insn "*cmp_cc_ashift_1"
7065 [(set (reg:CC_NOOV 100)
7066 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7070 "addcc\t%0, %0, %%g0"
7071 [(set_attr "type" "compare")])
7073 (define_insn "*cmp_cc_set_ashift_1"
7074 [(set (reg:CC_NOOV 100)
7075 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7078 (set (match_operand:SI 0 "register_operand" "=r")
7079 (ashift:SI (match_dup 1) (const_int 1)))]
7082 [(set_attr "type" "compare")])
7084 (define_insn "ashrsi3"
7085 [(set (match_operand:SI 0 "register_operand" "=r")
7086 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7087 (match_operand:SI 2 "arith_operand" "rI")))]
7090 if (GET_CODE (operands[2]) == CONST_INT)
7091 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7092 return "sra\t%1, %2, %0";
7094 [(set_attr "type" "shift")])
7096 (define_insn "*ashrsi3_extend"
7097 [(set (match_operand:DI 0 "register_operand" "=r")
7098 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7099 (match_operand:SI 2 "arith_operand" "r"))))]
7102 [(set_attr "type" "shift")])
7104 ;; This handles the case as above, but with constant shift instead of
7105 ;; register. Combiner "simplifies" it for us a little bit though.
7106 (define_insn "*ashrsi3_extend2"
7107 [(set (match_operand:DI 0 "register_operand" "=r")
7108 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7110 (match_operand:SI 2 "small_int_or_double" "n")))]
7112 && ((GET_CODE (operands[2]) == CONST_INT
7113 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7114 || (GET_CODE (operands[2]) == CONST_DOUBLE
7115 && !CONST_DOUBLE_HIGH (operands[2])
7116 && CONST_DOUBLE_LOW (operands[2]) >= 32
7117 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7119 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7121 return "sra\t%1, %2, %0";
7123 [(set_attr "type" "shift")])
7125 (define_expand "ashrdi3"
7126 [(set (match_operand:DI 0 "register_operand" "=r")
7127 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7128 (match_operand:SI 2 "arith_operand" "rI")))]
7129 "TARGET_ARCH64 || TARGET_V8PLUS"
7131 if (! TARGET_ARCH64)
7133 if (GET_CODE (operands[2]) == CONST_INT)
7134 FAIL; /* prefer generic code in this case */
7135 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7140 (define_insn "*ashrdi3_sp64"
7141 [(set (match_operand:DI 0 "register_operand" "=r")
7142 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7143 (match_operand:SI 2 "arith_operand" "rI")))]
7147 if (GET_CODE (operands[2]) == CONST_INT)
7148 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7149 return "srax\t%1, %2, %0";
7151 [(set_attr "type" "shift")])
7154 (define_insn "ashrdi3_v8plus"
7155 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7156 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7157 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7158 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7160 "* return output_v8plus_shift (operands, insn, \"srax\");"
7161 [(set_attr "type" "multi")
7162 (set_attr "length" "5,5,6")])
7164 (define_insn "lshrsi3"
7165 [(set (match_operand:SI 0 "register_operand" "=r")
7166 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7167 (match_operand:SI 2 "arith_operand" "rI")))]
7170 if (GET_CODE (operands[2]) == CONST_INT)
7171 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7172 return "srl\t%1, %2, %0";
7174 [(set_attr "type" "shift")])
7176 ;; This handles the case where
7177 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7178 ;; but combiner "simplifies" it for us.
7179 (define_insn "*lshrsi3_extend"
7180 [(set (match_operand:DI 0 "register_operand" "=r")
7181 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7182 (match_operand:SI 2 "arith_operand" "r")) 0)
7183 (match_operand 3 "" "")))]
7185 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7186 && CONST_DOUBLE_HIGH (operands[3]) == 0
7187 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7188 || (HOST_BITS_PER_WIDE_INT >= 64
7189 && GET_CODE (operands[3]) == CONST_INT
7190 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7192 [(set_attr "type" "shift")])
7194 ;; This handles the case where
7195 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7196 ;; but combiner "simplifies" it for us.
7197 (define_insn "*lshrsi3_extend2"
7198 [(set (match_operand:DI 0 "register_operand" "=r")
7199 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7200 (match_operand 2 "small_int_or_double" "n")
7203 && ((GET_CODE (operands[2]) == CONST_INT
7204 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7205 || (GET_CODE (operands[2]) == CONST_DOUBLE
7206 && CONST_DOUBLE_HIGH (operands[2]) == 0
7207 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7209 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7211 return "srl\t%1, %2, %0";
7213 [(set_attr "type" "shift")])
7215 (define_expand "lshrdi3"
7216 [(set (match_operand:DI 0 "register_operand" "=r")
7217 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7218 (match_operand:SI 2 "arith_operand" "rI")))]
7219 "TARGET_ARCH64 || TARGET_V8PLUS"
7221 if (! TARGET_ARCH64)
7223 if (GET_CODE (operands[2]) == CONST_INT)
7225 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7230 (define_insn "*lshrdi3_sp64"
7231 [(set (match_operand:DI 0 "register_operand" "=r")
7232 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7233 (match_operand:SI 2 "arith_operand" "rI")))]
7236 if (GET_CODE (operands[2]) == CONST_INT)
7237 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7238 return "srlx\t%1, %2, %0";
7240 [(set_attr "type" "shift")])
7243 (define_insn "lshrdi3_v8plus"
7244 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7245 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7246 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7247 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7249 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7250 [(set_attr "type" "multi")
7251 (set_attr "length" "5,5,6")])
7254 [(set (match_operand:SI 0 "register_operand" "=r")
7255 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7257 (match_operand:SI 2 "small_int_or_double" "n")))]
7259 && ((GET_CODE (operands[2]) == CONST_INT
7260 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7261 || (GET_CODE (operands[2]) == CONST_DOUBLE
7262 && !CONST_DOUBLE_HIGH (operands[2])
7263 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7265 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7267 return "srax\t%1, %2, %0";
7269 [(set_attr "type" "shift")])
7272 [(set (match_operand:SI 0 "register_operand" "=r")
7273 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7275 (match_operand:SI 2 "small_int_or_double" "n")))]
7277 && ((GET_CODE (operands[2]) == CONST_INT
7278 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7279 || (GET_CODE (operands[2]) == CONST_DOUBLE
7280 && !CONST_DOUBLE_HIGH (operands[2])
7281 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7283 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7285 return "srlx\t%1, %2, %0";
7287 [(set_attr "type" "shift")])
7290 [(set (match_operand:SI 0 "register_operand" "=r")
7291 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7292 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7293 (match_operand:SI 3 "small_int_or_double" "n")))]
7295 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7296 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7297 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7298 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7300 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7302 return "srax\t%1, %2, %0";
7304 [(set_attr "type" "shift")])
7307 [(set (match_operand:SI 0 "register_operand" "=r")
7308 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7309 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7310 (match_operand:SI 3 "small_int_or_double" "n")))]
7312 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7313 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7314 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7315 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7317 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7319 return "srlx\t%1, %2, %0";
7321 [(set_attr "type" "shift")])
7323 ;; Unconditional and other jump instructions
7325 [(set (pc) (label_ref (match_operand 0 "" "")))]
7327 "* return output_ubranch (operands[0], 0, insn);"
7328 [(set_attr "type" "uncond_branch")])
7330 (define_expand "tablejump"
7331 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7332 (use (label_ref (match_operand 1 "" "")))])]
7335 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7338 /* In pic mode, our address differences are against the base of the
7339 table. Add that base value back in; CSE ought to be able to combine
7340 the two address loads. */
7344 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7346 if (CASE_VECTOR_MODE != Pmode)
7347 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7348 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7349 operands[0] = memory_address (Pmode, tmp);
7353 (define_insn "*tablejump_sp32"
7354 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7355 (use (label_ref (match_operand 1 "" "")))]
7358 [(set_attr "type" "uncond_branch")])
7360 (define_insn "*tablejump_sp64"
7361 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7362 (use (label_ref (match_operand 1 "" "")))]
7365 [(set_attr "type" "uncond_branch")])
7367 ;;- jump to subroutine
7368 (define_expand "call"
7369 ;; Note that this expression is not used for generating RTL.
7370 ;; All the RTL is generated explicitly below.
7371 [(call (match_operand 0 "call_operand" "")
7372 (match_operand 3 "" "i"))]
7373 ;; operands[2] is next_arg_register
7374 ;; operands[3] is struct_value_size_rtx.
7379 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7382 if (GET_CODE (operands[3]) != CONST_INT)
7385 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7387 /* This is really a PIC sequence. We want to represent
7388 it as a funny jump so its delay slots can be filled.
7390 ??? But if this really *is* a CALL, will not it clobber the
7391 call-clobbered registers? We lose this if it is a JUMP_INSN.
7392 Why cannot we have delay slots filled if it were a CALL? */
7394 /* We accept negative sizes for untyped calls. */
7395 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7400 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7402 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7408 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7409 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7413 fn_rtx = operands[0];
7415 /* We accept negative sizes for untyped calls. */
7416 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7420 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7422 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7427 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7428 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7435 ;; We can't use the same pattern for these two insns, because then registers
7436 ;; in the address may not be properly reloaded.
7438 (define_insn "*call_address_sp32"
7439 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7440 (match_operand 1 "" ""))
7441 (clobber (reg:SI 15))]
7442 ;;- Do not use operand 1 for most machines.
7445 [(set_attr "type" "call")])
7447 (define_insn "*call_symbolic_sp32"
7448 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7449 (match_operand 1 "" ""))
7450 (clobber (reg:SI 15))]
7451 ;;- Do not use operand 1 for most machines.
7454 [(set_attr "type" "call")])
7456 (define_insn "*call_address_sp64"
7457 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7458 (match_operand 1 "" ""))
7459 (clobber (reg:DI 15))]
7460 ;;- Do not use operand 1 for most machines.
7463 [(set_attr "type" "call")])
7465 (define_insn "*call_symbolic_sp64"
7466 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7467 (match_operand 1 "" ""))
7468 (clobber (reg:DI 15))]
7469 ;;- Do not use operand 1 for most machines.
7472 [(set_attr "type" "call")])
7474 ;; This is a call that wants a structure value.
7475 ;; There is no such critter for v9 (??? we may need one anyway).
7476 (define_insn "*call_address_struct_value_sp32"
7477 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7478 (match_operand 1 "" ""))
7479 (match_operand 2 "immediate_operand" "")
7480 (clobber (reg:SI 15))]
7481 ;;- Do not use operand 1 for most machines.
7482 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7484 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7485 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7487 [(set_attr "type" "call_no_delay_slot")
7488 (set_attr "length" "3")])
7490 ;; This is a call that wants a structure value.
7491 ;; There is no such critter for v9 (??? we may need one anyway).
7492 (define_insn "*call_symbolic_struct_value_sp32"
7493 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7494 (match_operand 1 "" ""))
7495 (match_operand 2 "immediate_operand" "")
7496 (clobber (reg:SI 15))]
7497 ;;- Do not use operand 1 for most machines.
7498 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7500 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7501 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7503 [(set_attr "type" "call_no_delay_slot")
7504 (set_attr "length" "3")])
7506 ;; This is a call that may want a structure value. This is used for
7508 (define_insn "*call_address_untyped_struct_value_sp32"
7509 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7510 (match_operand 1 "" ""))
7511 (match_operand 2 "immediate_operand" "")
7512 (clobber (reg:SI 15))]
7513 ;;- Do not use operand 1 for most machines.
7514 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7515 "call\t%a0, %1\n\t nop\n\tnop"
7516 [(set_attr "type" "call_no_delay_slot")
7517 (set_attr "length" "3")])
7519 ;; This is a call that may want a structure value. This is used for
7521 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7522 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7523 (match_operand 1 "" ""))
7524 (match_operand 2 "immediate_operand" "")
7525 (clobber (reg:SI 15))]
7526 ;;- Do not use operand 1 for most machines.
7527 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7528 "call\t%a0, %1\n\t nop\n\tnop"
7529 [(set_attr "type" "call_no_delay_slot")
7530 (set_attr "length" "3")])
7532 (define_expand "call_value"
7533 ;; Note that this expression is not used for generating RTL.
7534 ;; All the RTL is generated explicitly below.
7535 [(set (match_operand 0 "register_operand" "=rf")
7536 (call (match_operand 1 "" "")
7537 (match_operand 4 "" "")))]
7538 ;; operand 2 is stack_size_rtx
7539 ;; operand 3 is next_arg_register
7545 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7548 fn_rtx = operands[1];
7551 gen_rtx_SET (VOIDmode, operands[0],
7552 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7553 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7555 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7560 (define_insn "*call_value_address_sp32"
7561 [(set (match_operand 0 "" "=rf")
7562 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7563 (match_operand 2 "" "")))
7564 (clobber (reg:SI 15))]
7565 ;;- Do not use operand 2 for most machines.
7568 [(set_attr "type" "call")])
7570 (define_insn "*call_value_symbolic_sp32"
7571 [(set (match_operand 0 "" "=rf")
7572 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7573 (match_operand 2 "" "")))
7574 (clobber (reg:SI 15))]
7575 ;;- Do not use operand 2 for most machines.
7578 [(set_attr "type" "call")])
7580 (define_insn "*call_value_address_sp64"
7581 [(set (match_operand 0 "" "")
7582 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7583 (match_operand 2 "" "")))
7584 (clobber (reg:DI 15))]
7585 ;;- Do not use operand 2 for most machines.
7588 [(set_attr "type" "call")])
7590 (define_insn "*call_value_symbolic_sp64"
7591 [(set (match_operand 0 "" "")
7592 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7593 (match_operand 2 "" "")))
7594 (clobber (reg:DI 15))]
7595 ;;- Do not use operand 2 for most machines.
7598 [(set_attr "type" "call")])
7600 (define_expand "untyped_call"
7601 [(parallel [(call (match_operand 0 "" "")
7603 (match_operand 1 "" "")
7604 (match_operand 2 "" "")])]
7609 /* Pass constm1 to indicate that it may expect a structure value, but
7610 we don't know what size it is. */
7611 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7613 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7615 rtx set = XVECEXP (operands[2], 0, i);
7616 emit_move_insn (SET_DEST (set), SET_SRC (set));
7619 /* The optimizer does not know that the call sets the function value
7620 registers we stored in the result block. We avoid problems by
7621 claiming that all hard registers are used and clobbered at this
7623 emit_insn (gen_blockage ());
7629 (define_expand "sibcall"
7630 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7635 (define_insn "*sibcall_symbolic_sp32"
7636 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7637 (match_operand 1 "" ""))
7640 "* return output_sibcall(insn, operands[0]);"
7641 [(set_attr "type" "sibcall")])
7643 (define_insn "*sibcall_symbolic_sp64"
7644 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7645 (match_operand 1 "" ""))
7648 "* return output_sibcall(insn, operands[0]);"
7649 [(set_attr "type" "sibcall")])
7651 (define_expand "sibcall_value"
7652 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7653 (call (match_operand 1 "" "") (const_int 0)))
7658 (define_insn "*sibcall_value_symbolic_sp32"
7659 [(set (match_operand 0 "" "=rf")
7660 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7661 (match_operand 2 "" "")))
7664 "* return output_sibcall(insn, operands[1]);"
7665 [(set_attr "type" "sibcall")])
7667 (define_insn "*sibcall_value_symbolic_sp64"
7668 [(set (match_operand 0 "" "")
7669 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7670 (match_operand 2 "" "")))
7673 "* return output_sibcall(insn, operands[1]);"
7674 [(set_attr "type" "sibcall")])
7676 (define_expand "sibcall_epilogue"
7680 sparc_expand_epilogue ();
7684 (define_expand "prologue"
7688 sparc_expand_prologue ();
7692 (define_expand "save_register_window"
7693 [(use (match_operand 0 "arith_operand" ""))]
7699 gen_rtx_SET (VOIDmode,
7701 gen_rtx_PLUS (Pmode,
7702 hard_frame_pointer_rtx,
7704 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7705 gen_rtvec (1, const0_rtx),
7708 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7712 (define_insn "*save_register_windowsi"
7713 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7714 (match_operand:SI 0 "arith_operand" "rI")))
7715 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7717 "save\t%%sp, %0, %%sp"
7718 [(set_attr "type" "savew")])
7720 (define_insn "*save_register_windowdi"
7721 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7722 (match_operand:DI 0 "arith_operand" "rI")))
7723 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7725 "save\t%%sp, %0, %%sp"
7726 [(set_attr "type" "savew")])
7728 (define_expand "epilogue"
7732 sparc_expand_epilogue ();
7735 (define_expand "return"
7737 "sparc_can_use_return_insn_p ()"
7740 (define_insn "*return_internal"
7743 "* return output_return (insn);"
7744 [(set_attr "type" "return")
7745 (set (attr "length")
7746 (cond [(eq_attr "leaf_function" "true")
7747 (if_then_else (eq_attr "empty_delay_slot" "true")
7750 (eq_attr "calls_eh_return" "true")
7751 (if_then_else (eq_attr "delayed_branch" "true")
7752 (if_then_else (eq_attr "isa" "v9")
7755 (if_then_else (eq_attr "isa" "v9")
7758 (eq_attr "empty_delay_slot" "true")
7759 (if_then_else (eq_attr "delayed_branch" "true")
7764 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7765 ;; all of memory. This blocks insns from being moved across this point.
7767 (define_insn "blockage"
7768 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7771 [(set_attr "length" "0")])
7773 ;; Prepare to return any type including a structure value.
7775 (define_expand "untyped_return"
7776 [(match_operand:BLK 0 "memory_operand" "")
7777 (match_operand 1 "" "")]
7780 rtx valreg1 = gen_rtx_REG (DImode, 24);
7781 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7782 rtx result = operands[0];
7784 if (! TARGET_ARCH64)
7786 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7788 rtx value = gen_reg_rtx (SImode);
7790 /* Fetch the instruction where we will return to and see if it's an unimp
7791 instruction (the most significant 10 bits will be zero). If so,
7792 update the return address to skip the unimp instruction. */
7793 emit_move_insn (value,
7794 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7795 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7796 emit_insn (gen_update_return (rtnreg, value));
7799 /* Reload the function value registers. */
7800 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7801 emit_move_insn (valreg2,
7802 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7804 /* Put USE insns before the return. */
7805 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7806 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7808 /* Construct the return. */
7809 expand_naked_return ();
7814 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7815 ;; and parts of the compiler don't want to believe that the add is needed.
7817 (define_insn "update_return"
7818 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7819 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7822 if (flag_delayed_branch)
7823 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7825 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7827 [(set (attr "type") (const_string "multi"))
7828 (set (attr "length")
7829 (if_then_else (eq_attr "delayed_branch" "true")
7838 (define_expand "indirect_jump"
7839 [(set (pc) (match_operand 0 "address_operand" "p"))]
7843 (define_insn "*branch_sp32"
7844 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7847 [(set_attr "type" "uncond_branch")])
7849 (define_insn "*branch_sp64"
7850 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7853 [(set_attr "type" "uncond_branch")])
7855 (define_expand "nonlocal_goto"
7856 [(match_operand:SI 0 "general_operand" "")
7857 (match_operand:SI 1 "general_operand" "")
7858 (match_operand:SI 2 "general_operand" "")
7859 (match_operand:SI 3 "" "")]
7862 rtx lab = operands[1];
7863 rtx stack = operands[2];
7864 rtx fp = operands[3];
7867 /* Trap instruction to flush all the register windows. */
7868 emit_insn (gen_flush_register_windows ());
7870 /* Load the fp value for the containing fn into %fp. This is needed
7871 because STACK refers to %fp. Note that virtual register instantiation
7872 fails if the virtual %fp isn't set from a register. */
7873 if (GET_CODE (fp) != REG)
7874 fp = force_reg (Pmode, fp);
7875 emit_move_insn (virtual_stack_vars_rtx, fp);
7877 /* Find the containing function's current nonlocal goto handler,
7878 which will do any cleanups and then jump to the label. */
7879 labreg = gen_rtx_REG (Pmode, 8);
7880 emit_move_insn (labreg, lab);
7882 /* Restore %fp from stack pointer value for containing function.
7883 The restore insn that follows will move this to %sp,
7884 and reload the appropriate value into %fp. */
7885 emit_move_insn (hard_frame_pointer_rtx, stack);
7887 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7888 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7890 /* ??? The V9-specific version was disabled in rev 1.65. */
7891 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7896 ;; Special trap insn to flush register windows.
7897 (define_insn "flush_register_windows"
7898 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7900 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7901 [(set_attr "type" "flushw")])
7903 (define_insn "goto_handler_and_restore"
7904 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7905 "GET_MODE (operands[0]) == Pmode"
7907 if (flag_delayed_branch)
7908 return "jmp\t%0\n\t restore";
7910 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7912 [(set (attr "type") (const_string "multi"))
7913 (set (attr "length")
7914 (if_then_else (eq_attr "delayed_branch" "true")
7918 ;; For __builtin_setjmp we need to flush register windows iff the function
7919 ;; calls alloca as well, because otherwise the register window might be
7920 ;; saved after %sp adjustment and thus setjmp would crash
7921 (define_expand "builtin_setjmp_setup"
7922 [(match_operand 0 "register_operand" "r")]
7925 emit_insn (gen_do_builtin_setjmp_setup ());
7929 (define_insn "do_builtin_setjmp_setup"
7930 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7933 if (! current_function_calls_alloca)
7937 fputs ("\tflushw\n", asm_out_file);
7939 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7940 TARGET_ARCH64 ? 'x' : 'w',
7941 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7942 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7943 TARGET_ARCH64 ? 'x' : 'w',
7944 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7945 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7946 TARGET_ARCH64 ? 'x' : 'w',
7947 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7950 [(set_attr "type" "multi")
7951 (set (attr "length")
7952 (cond [(eq_attr "calls_alloca" "false")
7954 (eq_attr "isa" "!v9")
7956 (eq_attr "pic" "true")
7957 (const_int 4)] (const_int 3)))])
7959 ;; Pattern for use after a setjmp to store FP and the return register
7960 ;; into the stack area.
7962 (define_expand "setjmp"
7967 emit_insn (gen_setjmp_64 ());
7969 emit_insn (gen_setjmp_32 ());
7973 (define_expand "setjmp_32"
7974 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7975 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7977 { operands[0] = frame_pointer_rtx; })
7979 (define_expand "setjmp_64"
7980 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7981 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7983 { operands[0] = frame_pointer_rtx; })
7985 ;; Special pattern for the FLUSH instruction.
7987 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7988 ; of the define_insn otherwise missing a mode. We make "flush", aka
7989 ; gen_flush, the default one since sparc_initialize_trampoline uses
7990 ; it on SImode mem values.
7992 (define_insn "flush"
7993 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7995 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7996 [(set_attr "type" "iflush")])
7998 (define_insn "flushdi"
7999 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8001 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8002 [(set_attr "type" "iflush")])
8007 ;; The scan instruction searches from the most significant bit while ffs
8008 ;; searches from the least significant bit. The bit index and treatment of
8009 ;; zero also differ. It takes at least 7 instructions to get the proper
8010 ;; result. Here is an obvious 8 instruction sequence.
8013 (define_insn "ffssi2"
8014 [(set (match_operand:SI 0 "register_operand" "=&r")
8015 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8016 (clobber (match_scratch:SI 2 "=&r"))]
8017 "TARGET_SPARCLITE || TARGET_SPARCLET"
8019 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";
8021 [(set_attr "type" "multi")
8022 (set_attr "length" "8")])
8024 ;; ??? This should be a define expand, so that the extra instruction have
8025 ;; a chance of being optimized away.
8027 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
8028 ;; does, but no one uses that and we don't have a switch for it.
8030 ;(define_insn "ffsdi2"
8031 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8032 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8033 ; (clobber (match_scratch:DI 2 "=&r"))]
8035 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8036 ; [(set_attr "type" "multi")
8037 ; (set_attr "length" "4")])
8041 ;; Peepholes go at the end.
8043 ;; Optimize consecutive loads or stores into ldd and std when possible.
8044 ;; The conditions in which we do this are very restricted and are
8045 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8048 [(set (match_operand:SI 0 "memory_operand" "")
8050 (set (match_operand:SI 1 "memory_operand" "")
8053 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8056 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8059 [(set (match_operand:SI 0 "memory_operand" "")
8061 (set (match_operand:SI 1 "memory_operand" "")
8064 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8067 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8070 [(set (match_operand:SI 0 "register_operand" "")
8071 (match_operand:SI 1 "memory_operand" ""))
8072 (set (match_operand:SI 2 "register_operand" "")
8073 (match_operand:SI 3 "memory_operand" ""))]
8074 "registers_ok_for_ldd_peep (operands[0], operands[2])
8075 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8078 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8079 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8082 [(set (match_operand:SI 0 "memory_operand" "")
8083 (match_operand:SI 1 "register_operand" ""))
8084 (set (match_operand:SI 2 "memory_operand" "")
8085 (match_operand:SI 3 "register_operand" ""))]
8086 "registers_ok_for_ldd_peep (operands[1], operands[3])
8087 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8090 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8091 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8094 [(set (match_operand:SF 0 "register_operand" "")
8095 (match_operand:SF 1 "memory_operand" ""))
8096 (set (match_operand:SF 2 "register_operand" "")
8097 (match_operand:SF 3 "memory_operand" ""))]
8098 "registers_ok_for_ldd_peep (operands[0], operands[2])
8099 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8102 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8103 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8106 [(set (match_operand:SF 0 "memory_operand" "")
8107 (match_operand:SF 1 "register_operand" ""))
8108 (set (match_operand:SF 2 "memory_operand" "")
8109 (match_operand:SF 3 "register_operand" ""))]
8110 "registers_ok_for_ldd_peep (operands[1], operands[3])
8111 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8114 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8115 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8118 [(set (match_operand:SI 0 "register_operand" "")
8119 (match_operand:SI 1 "memory_operand" ""))
8120 (set (match_operand:SI 2 "register_operand" "")
8121 (match_operand:SI 3 "memory_operand" ""))]
8122 "registers_ok_for_ldd_peep (operands[2], operands[0])
8123 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8126 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8127 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8130 [(set (match_operand:SI 0 "memory_operand" "")
8131 (match_operand:SI 1 "register_operand" ""))
8132 (set (match_operand:SI 2 "memory_operand" "")
8133 (match_operand:SI 3 "register_operand" ""))]
8134 "registers_ok_for_ldd_peep (operands[3], operands[1])
8135 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8138 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8139 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8143 [(set (match_operand:SF 0 "register_operand" "")
8144 (match_operand:SF 1 "memory_operand" ""))
8145 (set (match_operand:SF 2 "register_operand" "")
8146 (match_operand:SF 3 "memory_operand" ""))]
8147 "registers_ok_for_ldd_peep (operands[2], operands[0])
8148 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8151 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8152 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8155 [(set (match_operand:SF 0 "memory_operand" "")
8156 (match_operand:SF 1 "register_operand" ""))
8157 (set (match_operand:SF 2 "memory_operand" "")
8158 (match_operand:SF 3 "register_operand" ""))]
8159 "registers_ok_for_ldd_peep (operands[3], operands[1])
8160 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8163 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8164 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8166 ;; Optimize the case of following a reg-reg move with a test
8167 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8168 ;; This can result from a float to fix conversion.
8171 [(set (match_operand:SI 0 "register_operand" "")
8172 (match_operand:SI 1 "register_operand" ""))
8174 (compare:CC (match_operand:SI 2 "register_operand" "")
8176 "(rtx_equal_p (operands[2], operands[0])
8177 || rtx_equal_p (operands[2], operands[1]))
8178 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8179 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8180 [(parallel [(set (match_dup 0) (match_dup 1))
8182 (compare:CC (match_dup 1) (const_int 0)))])]
8186 [(set (match_operand:DI 0 "register_operand" "")
8187 (match_operand:DI 1 "register_operand" ""))
8189 (compare:CCX (match_operand:DI 2 "register_operand" "")
8192 && (rtx_equal_p (operands[2], operands[0])
8193 || rtx_equal_p (operands[2], operands[1]))
8194 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8195 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8196 [(parallel [(set (match_dup 0) (match_dup 1))
8198 (compare:CCX (match_dup 1) (const_int 0)))])]
8201 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8202 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8203 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8205 (define_expand "prefetch"
8206 [(match_operand 0 "address_operand" "")
8207 (match_operand 1 "const_int_operand" "")
8208 (match_operand 2 "const_int_operand" "")]
8212 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8214 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8218 (define_insn "prefetch_64"
8219 [(prefetch (match_operand:DI 0 "address_operand" "p")
8220 (match_operand:DI 1 "const_int_operand" "n")
8221 (match_operand:DI 2 "const_int_operand" "n"))]
8224 static const char * const prefetch_instr[2][2] = {
8226 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8227 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8230 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8231 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8234 int read_or_write = INTVAL (operands[1]);
8235 int locality = INTVAL (operands[2]);
8237 if (read_or_write != 0 && read_or_write != 1)
8239 if (locality < 0 || locality > 3)
8241 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8243 [(set_attr "type" "load")])
8245 (define_insn "prefetch_32"
8246 [(prefetch (match_operand:SI 0 "address_operand" "p")
8247 (match_operand:SI 1 "const_int_operand" "n")
8248 (match_operand:SI 2 "const_int_operand" "n"))]
8251 static const char * const prefetch_instr[2][2] = {
8253 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8254 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8257 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8258 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8261 int read_or_write = INTVAL (operands[1]);
8262 int locality = INTVAL (operands[2]);
8264 if (read_or_write != 0 && read_or_write != 1)
8266 if (locality < 0 || locality > 3)
8268 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8270 [(set_attr "type" "load")])
8273 [(trap_if (const_int 1) (const_int 5))]
8276 [(set_attr "type" "trap")])
8278 (define_expand "conditional_trap"
8279 [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8280 (match_operand:SI 1 "arith_operand" ""))]
8282 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8283 sparc_compare_op0, sparc_compare_op1);
8284 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8286 operands[3] = const0_rtx;")
8289 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8290 (match_operand:SI 1 "arith_operand" "rM"))]
8294 return "t%C0\t%%icc, %1";
8298 [(set_attr "type" "trap")])
8301 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8302 (match_operand:SI 1 "arith_operand" "rM"))]
8305 [(set_attr "type" "trap")])
8308 (define_insn "tgd_hi22"
8309 [(set (match_operand:SI 0 "register_operand" "=r")
8310 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8313 "sethi\\t%%tgd_hi22(%a1), %0")
8315 (define_insn "tgd_lo10"
8316 [(set (match_operand:SI 0 "register_operand" "=r")
8317 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8318 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8321 "add\\t%1, %%tgd_lo10(%a2), %0")
8323 (define_insn "tgd_add32"
8324 [(set (match_operand:SI 0 "register_operand" "=r")
8325 (plus:SI (match_operand:SI 1 "register_operand" "r")
8326 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8327 (match_operand 3 "tgd_symbolic_operand" "")]
8329 "TARGET_TLS && TARGET_ARCH32"
8330 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8332 (define_insn "tgd_add64"
8333 [(set (match_operand:DI 0 "register_operand" "=r")
8334 (plus:DI (match_operand:DI 1 "register_operand" "r")
8335 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8336 (match_operand 3 "tgd_symbolic_operand" "")]
8338 "TARGET_TLS && TARGET_ARCH64"
8339 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8341 (define_insn "tgd_call32"
8342 [(set (match_operand 0 "register_operand" "=r")
8343 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8344 (match_operand 2 "tgd_symbolic_operand" "")]
8346 (match_operand 3 "" "")))
8347 (clobber (reg:SI 15))]
8348 "TARGET_TLS && TARGET_ARCH32"
8349 "call\t%a1, %%tgd_call(%a2)%#"
8350 [(set_attr "type" "call")])
8352 (define_insn "tgd_call64"
8353 [(set (match_operand 0 "register_operand" "=r")
8354 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8355 (match_operand 2 "tgd_symbolic_operand" "")]
8357 (match_operand 3 "" "")))
8358 (clobber (reg:DI 15))]
8359 "TARGET_TLS && TARGET_ARCH64"
8360 "call\t%a1, %%tgd_call(%a2)%#"
8361 [(set_attr "type" "call")])
8363 (define_insn "tldm_hi22"
8364 [(set (match_operand:SI 0 "register_operand" "=r")
8365 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8367 "sethi\\t%%tldm_hi22(%&), %0")
8369 (define_insn "tldm_lo10"
8370 [(set (match_operand:SI 0 "register_operand" "=r")
8371 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8372 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8374 "add\\t%1, %%tldm_lo10(%&), %0")
8376 (define_insn "tldm_add32"
8377 [(set (match_operand:SI 0 "register_operand" "=r")
8378 (plus:SI (match_operand:SI 1 "register_operand" "r")
8379 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8381 "TARGET_TLS && TARGET_ARCH32"
8382 "add\\t%1, %2, %0, %%tldm_add(%&)")
8384 (define_insn "tldm_add64"
8385 [(set (match_operand:DI 0 "register_operand" "=r")
8386 (plus:DI (match_operand:DI 1 "register_operand" "r")
8387 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8389 "TARGET_TLS && TARGET_ARCH64"
8390 "add\\t%1, %2, %0, %%tldm_add(%&)")
8392 (define_insn "tldm_call32"
8393 [(set (match_operand 0 "register_operand" "=r")
8394 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8396 (match_operand 2 "" "")))
8397 (clobber (reg:SI 15))]
8398 "TARGET_TLS && TARGET_ARCH32"
8399 "call\t%a1, %%tldm_call(%&)%#"
8400 [(set_attr "type" "call")])
8402 (define_insn "tldm_call64"
8403 [(set (match_operand 0 "register_operand" "=r")
8404 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8406 (match_operand 2 "" "")))
8407 (clobber (reg:DI 15))]
8408 "TARGET_TLS && TARGET_ARCH64"
8409 "call\t%a1, %%tldm_call(%&)%#"
8410 [(set_attr "type" "call")])
8412 (define_insn "tldo_hix22"
8413 [(set (match_operand:SI 0 "register_operand" "=r")
8414 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8417 "sethi\\t%%tldo_hix22(%a1), %0")
8419 (define_insn "tldo_lox10"
8420 [(set (match_operand:SI 0 "register_operand" "=r")
8421 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8422 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8425 "xor\\t%1, %%tldo_lox10(%a2), %0")
8427 (define_insn "tldo_add32"
8428 [(set (match_operand:SI 0 "register_operand" "=r")
8429 (plus:SI (match_operand:SI 1 "register_operand" "r")
8430 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8431 (match_operand 3 "tld_symbolic_operand" "")]
8433 "TARGET_TLS && TARGET_ARCH32"
8434 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8436 (define_insn "tldo_add64"
8437 [(set (match_operand:DI 0 "register_operand" "=r")
8438 (plus:DI (match_operand:DI 1 "register_operand" "r")
8439 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8440 (match_operand 3 "tld_symbolic_operand" "")]
8442 "TARGET_TLS && TARGET_ARCH64"
8443 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8445 (define_insn "tie_hi22"
8446 [(set (match_operand:SI 0 "register_operand" "=r")
8447 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8450 "sethi\\t%%tie_hi22(%a1), %0")
8452 (define_insn "tie_lo10"
8453 [(set (match_operand:SI 0 "register_operand" "=r")
8454 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8455 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8458 "add\\t%1, %%tie_lo10(%a2), %0")
8460 (define_insn "tie_ld32"
8461 [(set (match_operand:SI 0 "register_operand" "=r")
8462 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8463 (match_operand:SI 2 "register_operand" "r")
8464 (match_operand 3 "tie_symbolic_operand" "")]
8466 "TARGET_TLS && TARGET_ARCH32"
8467 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8468 [(set_attr "type" "load")])
8470 (define_insn "tie_ld64"
8471 [(set (match_operand:DI 0 "register_operand" "=r")
8472 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8473 (match_operand:SI 2 "register_operand" "r")
8474 (match_operand 3 "tie_symbolic_operand" "")]
8476 "TARGET_TLS && TARGET_ARCH64"
8477 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8478 [(set_attr "type" "load")])
8480 (define_insn "tie_add32"
8481 [(set (match_operand:SI 0 "register_operand" "=r")
8482 (plus:SI (match_operand:SI 1 "register_operand" "r")
8483 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8484 (match_operand 3 "tie_symbolic_operand" "")]
8486 "TARGET_SUN_TLS && TARGET_ARCH32"
8487 "add\\t%1, %2, %0, %%tie_add(%a3)")
8489 (define_insn "tie_add64"
8490 [(set (match_operand:DI 0 "register_operand" "=r")
8491 (plus:DI (match_operand:DI 1 "register_operand" "r")
8492 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8493 (match_operand 3 "tie_symbolic_operand" "")]
8495 "TARGET_SUN_TLS && TARGET_ARCH64"
8496 "add\\t%1, %2, %0, %%tie_add(%a3)")
8498 (define_insn "tle_hix22_sp32"
8499 [(set (match_operand:SI 0 "register_operand" "=r")
8500 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8502 "TARGET_TLS && TARGET_ARCH32"
8503 "sethi\\t%%tle_hix22(%a1), %0")
8505 (define_insn "tle_lox10_sp32"
8506 [(set (match_operand:SI 0 "register_operand" "=r")
8507 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8508 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8510 "TARGET_TLS && TARGET_ARCH32"
8511 "xor\\t%1, %%tle_lox10(%a2), %0")
8513 (define_insn "tle_hix22_sp64"
8514 [(set (match_operand:DI 0 "register_operand" "=r")
8515 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8517 "TARGET_TLS && TARGET_ARCH64"
8518 "sethi\\t%%tle_hix22(%a1), %0")
8520 (define_insn "tle_lox10_sp64"
8521 [(set (match_operand:DI 0 "register_operand" "=r")
8522 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8523 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8525 "TARGET_TLS && TARGET_ARCH64"
8526 "xor\\t%1, %%tle_lox10(%a2), %0")
8528 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8529 (define_insn "*tldo_ldub_sp32"
8530 [(set (match_operand:QI 0 "register_operand" "=r")
8531 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8532 (match_operand 3 "tld_symbolic_operand" "")]
8534 (match_operand:SI 1 "register_operand" "r"))))]
8535 "TARGET_TLS && TARGET_ARCH32"
8536 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8537 [(set_attr "type" "load")
8538 (set_attr "us3load_type" "3cycle")])
8540 (define_insn "*tldo_ldub1_sp32"
8541 [(set (match_operand:HI 0 "register_operand" "=r")
8542 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8543 (match_operand 3 "tld_symbolic_operand" "")]
8545 (match_operand:SI 1 "register_operand" "r")))))]
8546 "TARGET_TLS && TARGET_ARCH32"
8547 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8548 [(set_attr "type" "load")
8549 (set_attr "us3load_type" "3cycle")])
8551 (define_insn "*tldo_ldub2_sp32"
8552 [(set (match_operand:SI 0 "register_operand" "=r")
8553 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8554 (match_operand 3 "tld_symbolic_operand" "")]
8556 (match_operand:SI 1 "register_operand" "r")))))]
8557 "TARGET_TLS && TARGET_ARCH32"
8558 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8559 [(set_attr "type" "load")
8560 (set_attr "us3load_type" "3cycle")])
8562 (define_insn "*tldo_ldsb1_sp32"
8563 [(set (match_operand:HI 0 "register_operand" "=r")
8564 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8565 (match_operand 3 "tld_symbolic_operand" "")]
8567 (match_operand:SI 1 "register_operand" "r")))))]
8568 "TARGET_TLS && TARGET_ARCH32"
8569 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8570 [(set_attr "type" "sload")
8571 (set_attr "us3load_type" "3cycle")])
8573 (define_insn "*tldo_ldsb2_sp32"
8574 [(set (match_operand:SI 0 "register_operand" "=r")
8575 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8576 (match_operand 3 "tld_symbolic_operand" "")]
8578 (match_operand:SI 1 "register_operand" "r")))))]
8579 "TARGET_TLS && TARGET_ARCH32"
8580 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8581 [(set_attr "type" "sload")
8582 (set_attr "us3load_type" "3cycle")])
8584 (define_insn "*tldo_ldub_sp64"
8585 [(set (match_operand:QI 0 "register_operand" "=r")
8586 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8587 (match_operand 3 "tld_symbolic_operand" "")]
8589 (match_operand:DI 1 "register_operand" "r"))))]
8590 "TARGET_TLS && TARGET_ARCH64"
8591 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8592 [(set_attr "type" "load")
8593 (set_attr "us3load_type" "3cycle")])
8595 (define_insn "*tldo_ldub1_sp64"
8596 [(set (match_operand:HI 0 "register_operand" "=r")
8597 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8598 (match_operand 3 "tld_symbolic_operand" "")]
8600 (match_operand:DI 1 "register_operand" "r")))))]
8601 "TARGET_TLS && TARGET_ARCH64"
8602 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8603 [(set_attr "type" "load")
8604 (set_attr "us3load_type" "3cycle")])
8606 (define_insn "*tldo_ldub2_sp64"
8607 [(set (match_operand:SI 0 "register_operand" "=r")
8608 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8609 (match_operand 3 "tld_symbolic_operand" "")]
8611 (match_operand:DI 1 "register_operand" "r")))))]
8612 "TARGET_TLS && TARGET_ARCH64"
8613 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8614 [(set_attr "type" "load")
8615 (set_attr "us3load_type" "3cycle")])
8617 (define_insn "*tldo_ldub3_sp64"
8618 [(set (match_operand:DI 0 "register_operand" "=r")
8619 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8620 (match_operand 3 "tld_symbolic_operand" "")]
8622 (match_operand:DI 1 "register_operand" "r")))))]
8623 "TARGET_TLS && TARGET_ARCH64"
8624 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8625 [(set_attr "type" "load")
8626 (set_attr "us3load_type" "3cycle")])
8628 (define_insn "*tldo_ldsb1_sp64"
8629 [(set (match_operand:HI 0 "register_operand" "=r")
8630 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8631 (match_operand 3 "tld_symbolic_operand" "")]
8633 (match_operand:DI 1 "register_operand" "r")))))]
8634 "TARGET_TLS && TARGET_ARCH64"
8635 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8636 [(set_attr "type" "sload")
8637 (set_attr "us3load_type" "3cycle")])
8639 (define_insn "*tldo_ldsb2_sp64"
8640 [(set (match_operand:SI 0 "register_operand" "=r")
8641 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8642 (match_operand 3 "tld_symbolic_operand" "")]
8644 (match_operand:DI 1 "register_operand" "r")))))]
8645 "TARGET_TLS && TARGET_ARCH64"
8646 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8647 [(set_attr "type" "sload")
8648 (set_attr "us3load_type" "3cycle")])
8650 (define_insn "*tldo_ldsb3_sp64"
8651 [(set (match_operand:DI 0 "register_operand" "=r")
8652 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8653 (match_operand 3 "tld_symbolic_operand" "")]
8655 (match_operand:DI 1 "register_operand" "r")))))]
8656 "TARGET_TLS && TARGET_ARCH64"
8657 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8658 [(set_attr "type" "sload")
8659 (set_attr "us3load_type" "3cycle")])
8661 (define_insn "*tldo_lduh_sp32"
8662 [(set (match_operand:HI 0 "register_operand" "=r")
8663 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8664 (match_operand 3 "tld_symbolic_operand" "")]
8666 (match_operand:SI 1 "register_operand" "r"))))]
8667 "TARGET_TLS && TARGET_ARCH32"
8668 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8669 [(set_attr "type" "load")
8670 (set_attr "us3load_type" "3cycle")])
8672 (define_insn "*tldo_lduh1_sp32"
8673 [(set (match_operand:SI 0 "register_operand" "=r")
8674 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8675 (match_operand 3 "tld_symbolic_operand" "")]
8677 (match_operand:SI 1 "register_operand" "r")))))]
8678 "TARGET_TLS && TARGET_ARCH32"
8679 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8680 [(set_attr "type" "load")
8681 (set_attr "us3load_type" "3cycle")])
8683 (define_insn "*tldo_ldsh1_sp32"
8684 [(set (match_operand:SI 0 "register_operand" "=r")
8685 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8686 (match_operand 3 "tld_symbolic_operand" "")]
8688 (match_operand:SI 1 "register_operand" "r")))))]
8689 "TARGET_TLS && TARGET_ARCH32"
8690 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8691 [(set_attr "type" "sload")
8692 (set_attr "us3load_type" "3cycle")])
8694 (define_insn "*tldo_lduh_sp64"
8695 [(set (match_operand:HI 0 "register_operand" "=r")
8696 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8697 (match_operand 3 "tld_symbolic_operand" "")]
8699 (match_operand:DI 1 "register_operand" "r"))))]
8700 "TARGET_TLS && TARGET_ARCH64"
8701 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8702 [(set_attr "type" "load")
8703 (set_attr "us3load_type" "3cycle")])
8705 (define_insn "*tldo_lduh1_sp64"
8706 [(set (match_operand:SI 0 "register_operand" "=r")
8707 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8708 (match_operand 3 "tld_symbolic_operand" "")]
8710 (match_operand:DI 1 "register_operand" "r")))))]
8711 "TARGET_TLS && TARGET_ARCH64"
8712 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8713 [(set_attr "type" "load")
8714 (set_attr "us3load_type" "3cycle")])
8716 (define_insn "*tldo_lduh2_sp64"
8717 [(set (match_operand:DI 0 "register_operand" "=r")
8718 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8719 (match_operand 3 "tld_symbolic_operand" "")]
8721 (match_operand:DI 1 "register_operand" "r")))))]
8722 "TARGET_TLS && TARGET_ARCH64"
8723 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8724 [(set_attr "type" "load")
8725 (set_attr "us3load_type" "3cycle")])
8727 (define_insn "*tldo_ldsh1_sp64"
8728 [(set (match_operand:SI 0 "register_operand" "=r")
8729 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8730 (match_operand 3 "tld_symbolic_operand" "")]
8732 (match_operand:DI 1 "register_operand" "r")))))]
8733 "TARGET_TLS && TARGET_ARCH64"
8734 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8735 [(set_attr "type" "sload")
8736 (set_attr "us3load_type" "3cycle")])
8738 (define_insn "*tldo_ldsh2_sp64"
8739 [(set (match_operand:DI 0 "register_operand" "=r")
8740 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8741 (match_operand 3 "tld_symbolic_operand" "")]
8743 (match_operand:DI 1 "register_operand" "r")))))]
8744 "TARGET_TLS && TARGET_ARCH64"
8745 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8746 [(set_attr "type" "sload")
8747 (set_attr "us3load_type" "3cycle")])
8749 (define_insn "*tldo_lduw_sp32"
8750 [(set (match_operand:SI 0 "register_operand" "=r")
8751 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8752 (match_operand 3 "tld_symbolic_operand" "")]
8754 (match_operand:SI 1 "register_operand" "r"))))]
8755 "TARGET_TLS && TARGET_ARCH32"
8756 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8757 [(set_attr "type" "load")])
8759 (define_insn "*tldo_lduw_sp64"
8760 [(set (match_operand:SI 0 "register_operand" "=r")
8761 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8762 (match_operand 3 "tld_symbolic_operand" "")]
8764 (match_operand:DI 1 "register_operand" "r"))))]
8765 "TARGET_TLS && TARGET_ARCH64"
8766 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8767 [(set_attr "type" "load")])
8769 (define_insn "*tldo_lduw1_sp64"
8770 [(set (match_operand:DI 0 "register_operand" "=r")
8771 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8772 (match_operand 3 "tld_symbolic_operand" "")]
8774 (match_operand:DI 1 "register_operand" "r")))))]
8775 "TARGET_TLS && TARGET_ARCH64"
8776 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8777 [(set_attr "type" "load")])
8779 (define_insn "*tldo_ldsw1_sp64"
8780 [(set (match_operand:DI 0 "register_operand" "=r")
8781 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8782 (match_operand 3 "tld_symbolic_operand" "")]
8784 (match_operand:DI 1 "register_operand" "r")))))]
8785 "TARGET_TLS && TARGET_ARCH64"
8786 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8787 [(set_attr "type" "sload")
8788 (set_attr "us3load_type" "3cycle")])
8790 (define_insn "*tldo_ldx_sp64"
8791 [(set (match_operand:DI 0 "register_operand" "=r")
8792 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8793 (match_operand 3 "tld_symbolic_operand" "")]
8795 (match_operand:DI 1 "register_operand" "r"))))]
8796 "TARGET_TLS && TARGET_ARCH64"
8797 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8798 [(set_attr "type" "load")])
8800 (define_insn "*tldo_stb_sp32"
8801 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8802 (match_operand 3 "tld_symbolic_operand" "")]
8804 (match_operand:SI 1 "register_operand" "r")))
8805 (match_operand:QI 0 "register_operand" "=r"))]
8806 "TARGET_TLS && TARGET_ARCH32"
8807 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8808 [(set_attr "type" "store")])
8810 (define_insn "*tldo_stb_sp64"
8811 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8812 (match_operand 3 "tld_symbolic_operand" "")]
8814 (match_operand:DI 1 "register_operand" "r")))
8815 (match_operand:QI 0 "register_operand" "=r"))]
8816 "TARGET_TLS && TARGET_ARCH64"
8817 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8818 [(set_attr "type" "store")])
8820 (define_insn "*tldo_sth_sp32"
8821 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8822 (match_operand 3 "tld_symbolic_operand" "")]
8824 (match_operand:SI 1 "register_operand" "r")))
8825 (match_operand:HI 0 "register_operand" "=r"))]
8826 "TARGET_TLS && TARGET_ARCH32"
8827 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8828 [(set_attr "type" "store")])
8830 (define_insn "*tldo_sth_sp64"
8831 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8832 (match_operand 3 "tld_symbolic_operand" "")]
8834 (match_operand:DI 1 "register_operand" "r")))
8835 (match_operand:HI 0 "register_operand" "=r"))]
8836 "TARGET_TLS && TARGET_ARCH64"
8837 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8838 [(set_attr "type" "store")])
8840 (define_insn "*tldo_stw_sp32"
8841 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8842 (match_operand 3 "tld_symbolic_operand" "")]
8844 (match_operand:SI 1 "register_operand" "r")))
8845 (match_operand:SI 0 "register_operand" "=r"))]
8846 "TARGET_TLS && TARGET_ARCH32"
8847 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8848 [(set_attr "type" "store")])
8850 (define_insn "*tldo_stw_sp64"
8851 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8852 (match_operand 3 "tld_symbolic_operand" "")]
8854 (match_operand:DI 1 "register_operand" "r")))
8855 (match_operand:SI 0 "register_operand" "=r"))]
8856 "TARGET_TLS && TARGET_ARCH64"
8857 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8858 [(set_attr "type" "store")])
8860 (define_insn "*tldo_stx_sp64"
8861 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8862 (match_operand 3 "tld_symbolic_operand" "")]
8864 (match_operand:DI 1 "register_operand" "r")))
8865 (match_operand:DI 0 "register_operand" "=r"))]
8866 "TARGET_TLS && TARGET_ARCH64"
8867 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8868 [(set_attr "type" "store")])