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)
60 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
61 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
62 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
63 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
64 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
66 ;; Attribute for cpu type.
67 ;; These must match the values for enum processor_type in sparc.h.
74 hypersparc,sparclite86x,
79 (const (symbol_ref "sparc_cpu_attr")))
81 ;; Attribute for the instruction set.
82 ;; At present we only need to distinguish v9/!v9, but for clarity we
83 ;; test TARGET_V8 too.
84 (define_attr "isa" "v7,v8,v9,sparclet"
86 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
87 (symbol_ref "TARGET_V8") (const_string "v8")
88 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
89 (const_string "v7"))))
92 (define_attr "arch" "arch32bit,arch64bit"
94 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
95 (const_string "arch32bit"))))
102 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
110 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
113 multi,savew,flushw,iflush,trap"
114 (const_string "ialu"))
116 ;; true if branch/call has empty delay slot and will emit a nop in it
117 (define_attr "empty_delay_slot" "false,true"
118 (symbol_ref "empty_delay_slot (insn)"))
120 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
122 (define_attr "pic" "false,true"
123 (symbol_ref "flag_pic != 0"))
125 (define_attr "current_function_calls_alloca" "false,true"
126 (symbol_ref "current_function_calls_alloca != 0"))
128 (define_attr "delayed_branch" "false,true"
129 (symbol_ref "flag_delayed_branch != 0"))
131 ;; Length (in # of insns).
132 (define_attr "length" ""
133 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
134 (if_then_else (eq_attr "empty_delay_slot" "true")
137 (eq_attr "branch_type" "icc")
138 (if_then_else (match_operand 0 "noov_compare64_op" "")
139 (if_then_else (lt (pc) (match_dup 1))
140 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
141 (if_then_else (eq_attr "empty_delay_slot" "true")
144 (if_then_else (eq_attr "empty_delay_slot" "true")
147 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (if_then_else (eq_attr "empty_delay_slot" "true")
157 (eq_attr "branch_type" "fcc")
158 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
159 (if_then_else (eq_attr "empty_delay_slot" "true")
160 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
163 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
166 (if_then_else (lt (pc) (match_dup 2))
167 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
168 (if_then_else (eq_attr "empty_delay_slot" "true")
171 (if_then_else (eq_attr "empty_delay_slot" "true")
174 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
175 (if_then_else (eq_attr "empty_delay_slot" "true")
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (eq_attr "branch_type" "reg")
182 (if_then_else (lt (pc) (match_dup 2))
183 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
191 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (if_then_else (eq_attr "empty_delay_slot" "true")
200 (define_attr "fptype" "single,double" (const_string "single"))
202 ;; UltraSPARC-III integer load type.
203 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
205 (define_asm_attributes
206 [(set_attr "length" "2")
207 (set_attr "type" "multi")])
209 ;; Attributes for instruction and branch scheduling
211 (define_attr "tls_call_delay" "false,true"
212 (symbol_ref "tls_call_delay (insn)"))
214 (define_attr "in_call_delay" "false,true"
215 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
216 (const_string "false")
217 (eq_attr "type" "load,fpload,store,fpstore")
218 (if_then_else (eq_attr "length" "1")
219 (const_string "true")
220 (const_string "false"))]
221 (if_then_else (and (eq_attr "length" "1")
222 (eq_attr "tls_call_delay" "true"))
223 (const_string "true")
224 (const_string "false"))))
226 (define_attr "eligible_for_sibcall_delay" "false,true"
227 (symbol_ref "eligible_for_sibcall_delay (insn)"))
229 (define_attr "eligible_for_return_delay" "false,true"
230 (symbol_ref "eligible_for_return_delay (insn)"))
232 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
233 ;; branches. This would allow us to remove the nop always inserted before
234 ;; a floating point branch.
236 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
237 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
238 ;; This is because doing so will add several pipeline stalls to the path
239 ;; that the load/store did not come from. Unfortunately, there is no way
240 ;; to prevent fill_eager_delay_slots from using load/store without completely
241 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
242 ;; because it prevents us from moving back the final store of inner loops.
244 (define_attr "in_branch_delay" "false,true"
245 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
246 (eq_attr "length" "1"))
247 (const_string "true")
248 (const_string "false")))
250 (define_attr "in_uncond_branch_delay" "false,true"
251 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
252 (eq_attr "length" "1"))
253 (const_string "true")
254 (const_string "false")))
256 (define_attr "in_annul_branch_delay" "false,true"
257 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
258 (eq_attr "length" "1"))
259 (const_string "true")
260 (const_string "false")))
262 (define_delay (eq_attr "type" "call")
263 [(eq_attr "in_call_delay" "true") (nil) (nil)])
265 (define_delay (eq_attr "type" "sibcall")
266 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
268 (define_delay (eq_attr "type" "branch")
269 [(eq_attr "in_branch_delay" "true")
270 (nil) (eq_attr "in_annul_branch_delay" "true")])
272 (define_delay (eq_attr "type" "uncond_branch")
273 [(eq_attr "in_uncond_branch_delay" "true")
276 (define_delay (eq_attr "type" "return")
277 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
279 ;; Include SPARC DFA schedulers
281 (include "cypress.md")
282 (include "supersparc.md")
283 (include "hypersparc.md")
284 (include "sparclet.md")
285 (include "ultra1_2.md")
286 (include "ultra3.md")
289 ;; Compare instructions.
290 ;; This controls RTL generation and register allocation.
292 ;; We generate RTL for comparisons and branches by having the cmpxx
293 ;; patterns store away the operands. Then, the scc and bcc patterns
294 ;; emit RTL for both the compare and the branch.
296 ;; We do this because we want to generate different code for an sne and
297 ;; seq insn. In those cases, if the second operand of the compare is not
298 ;; const0_rtx, we want to compute the xor of the two operands and test
301 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
302 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
303 ;; insns that actually require more than one machine instruction.
305 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
307 (define_expand "cmpsi"
309 (compare:CC (match_operand:SI 0 "compare_operand" "")
310 (match_operand:SI 1 "arith_operand" "")))]
313 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
314 operands[0] = force_reg (SImode, operands[0]);
316 sparc_compare_op0 = operands[0];
317 sparc_compare_op1 = operands[1];
321 (define_expand "cmpdi"
323 (compare:CCX (match_operand:DI 0 "compare_operand" "")
324 (match_operand:DI 1 "arith_double_operand" "")))]
327 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
328 operands[0] = force_reg (DImode, operands[0]);
330 sparc_compare_op0 = operands[0];
331 sparc_compare_op1 = operands[1];
335 (define_expand "cmpsf"
336 ;; The 96 here isn't ever used by anyone.
338 (compare:CCFP (match_operand:SF 0 "register_operand" "")
339 (match_operand:SF 1 "register_operand" "")))]
342 sparc_compare_op0 = operands[0];
343 sparc_compare_op1 = operands[1];
347 (define_expand "cmpdf"
348 ;; The 96 here isn't ever used by anyone.
350 (compare:CCFP (match_operand:DF 0 "register_operand" "")
351 (match_operand:DF 1 "register_operand" "")))]
354 sparc_compare_op0 = operands[0];
355 sparc_compare_op1 = operands[1];
359 (define_expand "cmptf"
360 ;; The 96 here isn't ever used by anyone.
362 (compare:CCFP (match_operand:TF 0 "register_operand" "")
363 (match_operand:TF 1 "register_operand" "")))]
366 sparc_compare_op0 = operands[0];
367 sparc_compare_op1 = operands[1];
371 ;; Now the compare DEFINE_INSNs.
373 (define_insn "*cmpsi_insn"
375 (compare:CC (match_operand:SI 0 "register_operand" "r")
376 (match_operand:SI 1 "arith_operand" "rI")))]
379 [(set_attr "type" "compare")])
381 (define_insn "*cmpdi_sp64"
383 (compare:CCX (match_operand:DI 0 "register_operand" "r")
384 (match_operand:DI 1 "arith_double_operand" "rHI")))]
387 [(set_attr "type" "compare")])
389 (define_insn "*cmpsf_fpe"
390 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
391 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
392 (match_operand:SF 2 "register_operand" "f")))]
396 return "fcmpes\t%0, %1, %2";
397 return "fcmpes\t%1, %2";
399 [(set_attr "type" "fpcmp")])
401 (define_insn "*cmpdf_fpe"
402 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
403 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
404 (match_operand:DF 2 "register_operand" "e")))]
408 return "fcmped\t%0, %1, %2";
409 return "fcmped\t%1, %2";
411 [(set_attr "type" "fpcmp")
412 (set_attr "fptype" "double")])
414 (define_insn "*cmptf_fpe"
415 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
416 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
417 (match_operand:TF 2 "register_operand" "e")))]
418 "TARGET_FPU && TARGET_HARD_QUAD"
421 return "fcmpeq\t%0, %1, %2";
422 return "fcmpeq\t%1, %2";
424 [(set_attr "type" "fpcmp")])
426 (define_insn "*cmpsf_fp"
427 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
428 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
429 (match_operand:SF 2 "register_operand" "f")))]
433 return "fcmps\t%0, %1, %2";
434 return "fcmps\t%1, %2";
436 [(set_attr "type" "fpcmp")])
438 (define_insn "*cmpdf_fp"
439 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
440 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
441 (match_operand:DF 2 "register_operand" "e")))]
445 return "fcmpd\t%0, %1, %2";
446 return "fcmpd\t%1, %2";
448 [(set_attr "type" "fpcmp")
449 (set_attr "fptype" "double")])
451 (define_insn "*cmptf_fp"
452 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
453 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
454 (match_operand:TF 2 "register_operand" "e")))]
455 "TARGET_FPU && TARGET_HARD_QUAD"
458 return "fcmpq\t%0, %1, %2";
459 return "fcmpq\t%1, %2";
461 [(set_attr "type" "fpcmp")])
463 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
464 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
465 ;; the same code as v8 (the addx/subx method has more applications). The
466 ;; exception to this is "reg != 0" which can be done in one instruction on v9
467 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
470 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
471 ;; generate addcc/subcc instructions.
473 (define_expand "seqsi_special"
475 (xor:SI (match_operand:SI 1 "register_operand" "")
476 (match_operand:SI 2 "register_operand" "")))
477 (parallel [(set (match_operand:SI 0 "register_operand" "")
478 (eq:SI (match_dup 3) (const_int 0)))
479 (clobber (reg:CC 100))])]
481 { operands[3] = gen_reg_rtx (SImode); })
483 (define_expand "seqdi_special"
485 (xor:DI (match_operand:DI 1 "register_operand" "")
486 (match_operand:DI 2 "register_operand" "")))
487 (set (match_operand:DI 0 "register_operand" "")
488 (eq:DI (match_dup 3) (const_int 0)))]
490 { operands[3] = gen_reg_rtx (DImode); })
492 (define_expand "snesi_special"
494 (xor:SI (match_operand:SI 1 "register_operand" "")
495 (match_operand:SI 2 "register_operand" "")))
496 (parallel [(set (match_operand:SI 0 "register_operand" "")
497 (ne:SI (match_dup 3) (const_int 0)))
498 (clobber (reg:CC 100))])]
500 { operands[3] = gen_reg_rtx (SImode); })
502 (define_expand "snedi_special"
504 (xor:DI (match_operand:DI 1 "register_operand" "")
505 (match_operand:DI 2 "register_operand" "")))
506 (set (match_operand:DI 0 "register_operand" "")
507 (ne:DI (match_dup 3) (const_int 0)))]
509 { operands[3] = gen_reg_rtx (DImode); })
511 (define_expand "seqdi_special_trunc"
513 (xor:DI (match_operand:DI 1 "register_operand" "")
514 (match_operand:DI 2 "register_operand" "")))
515 (set (match_operand:SI 0 "register_operand" "")
516 (eq:SI (match_dup 3) (const_int 0)))]
518 { operands[3] = gen_reg_rtx (DImode); })
520 (define_expand "snedi_special_trunc"
522 (xor:DI (match_operand:DI 1 "register_operand" "")
523 (match_operand:DI 2 "register_operand" "")))
524 (set (match_operand:SI 0 "register_operand" "")
525 (ne:SI (match_dup 3) (const_int 0)))]
527 { operands[3] = gen_reg_rtx (DImode); })
529 (define_expand "seqsi_special_extend"
531 (xor:SI (match_operand:SI 1 "register_operand" "")
532 (match_operand:SI 2 "register_operand" "")))
533 (parallel [(set (match_operand:DI 0 "register_operand" "")
534 (eq:DI (match_dup 3) (const_int 0)))
535 (clobber (reg:CC 100))])]
537 { operands[3] = gen_reg_rtx (SImode); })
539 (define_expand "snesi_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 (ne:DI (match_dup 3) (const_int 0)))
545 (clobber (reg:CC 100))])]
547 { operands[3] = gen_reg_rtx (SImode); })
549 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
550 ;; However, the code handles both SImode and DImode.
552 [(set (match_operand:SI 0 "intreg_operand" "")
553 (eq:SI (match_dup 1) (const_int 0)))]
556 if (GET_MODE (sparc_compare_op0) == SImode)
560 if (GET_MODE (operands[0]) == SImode)
561 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
563 else if (! TARGET_ARCH64)
566 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
571 else if (GET_MODE (sparc_compare_op0) == DImode)
577 else if (GET_MODE (operands[0]) == SImode)
578 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
581 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
586 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
588 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
589 emit_jump_insn (gen_sne (operands[0]));
594 if (gen_v9_scc (EQ, operands))
601 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
602 ;; However, the code handles both SImode and DImode.
604 [(set (match_operand:SI 0 "intreg_operand" "")
605 (ne:SI (match_dup 1) (const_int 0)))]
608 if (GET_MODE (sparc_compare_op0) == SImode)
612 if (GET_MODE (operands[0]) == SImode)
613 pat = gen_snesi_special (operands[0], sparc_compare_op0,
615 else if (! TARGET_ARCH64)
618 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
623 else if (GET_MODE (sparc_compare_op0) == DImode)
629 else if (GET_MODE (operands[0]) == SImode)
630 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
633 pat = gen_snedi_special (operands[0], sparc_compare_op0,
638 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
640 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
641 emit_jump_insn (gen_sne (operands[0]));
646 if (gen_v9_scc (NE, operands))
654 [(set (match_operand:SI 0 "intreg_operand" "")
655 (gt:SI (match_dup 1) (const_int 0)))]
658 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
660 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
661 emit_jump_insn (gen_sne (operands[0]));
666 if (gen_v9_scc (GT, operands))
674 [(set (match_operand:SI 0 "intreg_operand" "")
675 (lt:SI (match_dup 1) (const_int 0)))]
678 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
680 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
681 emit_jump_insn (gen_sne (operands[0]));
686 if (gen_v9_scc (LT, operands))
694 [(set (match_operand:SI 0 "intreg_operand" "")
695 (ge:SI (match_dup 1) (const_int 0)))]
698 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
700 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
701 emit_jump_insn (gen_sne (operands[0]));
706 if (gen_v9_scc (GE, operands))
714 [(set (match_operand:SI 0 "intreg_operand" "")
715 (le:SI (match_dup 1) (const_int 0)))]
718 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
720 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
721 emit_jump_insn (gen_sne (operands[0]));
726 if (gen_v9_scc (LE, operands))
733 (define_expand "sgtu"
734 [(set (match_operand:SI 0 "intreg_operand" "")
735 (gtu:SI (match_dup 1) (const_int 0)))]
742 /* We can do ltu easily, so if both operands are registers, swap them and
744 if ((GET_CODE (sparc_compare_op0) == REG
745 || GET_CODE (sparc_compare_op0) == SUBREG)
746 && (GET_CODE (sparc_compare_op1) == REG
747 || GET_CODE (sparc_compare_op1) == SUBREG))
749 tem = sparc_compare_op0;
750 sparc_compare_op0 = sparc_compare_op1;
751 sparc_compare_op1 = tem;
752 pat = gen_sltu (operands[0]);
761 if (gen_v9_scc (GTU, operands))
767 (define_expand "sltu"
768 [(set (match_operand:SI 0 "intreg_operand" "")
769 (ltu:SI (match_dup 1) (const_int 0)))]
774 if (gen_v9_scc (LTU, operands))
777 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
780 (define_expand "sgeu"
781 [(set (match_operand:SI 0 "intreg_operand" "")
782 (geu:SI (match_dup 1) (const_int 0)))]
787 if (gen_v9_scc (GEU, operands))
790 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
793 (define_expand "sleu"
794 [(set (match_operand:SI 0 "intreg_operand" "")
795 (leu:SI (match_dup 1) (const_int 0)))]
802 /* We can do geu easily, so if both operands are registers, swap them and
804 if ((GET_CODE (sparc_compare_op0) == REG
805 || GET_CODE (sparc_compare_op0) == SUBREG)
806 && (GET_CODE (sparc_compare_op1) == REG
807 || GET_CODE (sparc_compare_op1) == SUBREG))
809 tem = sparc_compare_op0;
810 sparc_compare_op0 = sparc_compare_op1;
811 sparc_compare_op1 = tem;
812 pat = gen_sgeu (operands[0]);
821 if (gen_v9_scc (LEU, operands))
827 ;; Now the DEFINE_INSNs for the scc cases.
829 ;; The SEQ and SNE patterns are special because they can be done
830 ;; without any branching and do not involve a COMPARE. We want
831 ;; them to always use the splitz below so the results can be
834 (define_insn_and_split "*snesi_zero"
835 [(set (match_operand:SI 0 "register_operand" "=r")
836 (ne:SI (match_operand:SI 1 "register_operand" "r")
838 (clobber (reg:CC 100))]
842 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
844 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
846 [(set_attr "length" "2")])
848 (define_insn_and_split "*neg_snesi_zero"
849 [(set (match_operand:SI 0 "register_operand" "=r")
850 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
852 (clobber (reg:CC 100))]
856 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
858 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
860 [(set_attr "length" "2")])
862 (define_insn_and_split "*snesi_zero_extend"
863 [(set (match_operand:DI 0 "register_operand" "=r")
864 (ne:DI (match_operand:SI 1 "register_operand" "r")
866 (clobber (reg:CC 100))]
870 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
873 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
875 (ltu:SI (reg:CC_NOOV 100)
878 [(set_attr "length" "2")])
880 (define_insn_and_split "*snedi_zero"
881 [(set (match_operand:DI 0 "register_operand" "=&r")
882 (ne:DI (match_operand:DI 1 "register_operand" "r")
886 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
887 [(set (match_dup 0) (const_int 0))
888 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
893 [(set_attr "length" "2")])
895 (define_insn_and_split "*neg_snedi_zero"
896 [(set (match_operand:DI 0 "register_operand" "=&r")
897 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
901 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
902 [(set (match_dup 0) (const_int 0))
903 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
908 [(set_attr "length" "2")])
910 (define_insn_and_split "*snedi_zero_trunc"
911 [(set (match_operand:SI 0 "register_operand" "=&r")
912 (ne:SI (match_operand:DI 1 "register_operand" "r")
916 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
917 [(set (match_dup 0) (const_int 0))
918 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
923 [(set_attr "length" "2")])
925 (define_insn_and_split "*seqsi_zero"
926 [(set (match_operand:SI 0 "register_operand" "=r")
927 (eq:SI (match_operand:SI 1 "register_operand" "r")
929 (clobber (reg:CC 100))]
933 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
935 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
937 [(set_attr "length" "2")])
939 (define_insn_and_split "*neg_seqsi_zero"
940 [(set (match_operand:SI 0 "register_operand" "=r")
941 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
943 (clobber (reg:CC 100))]
947 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
949 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
951 [(set_attr "length" "2")])
953 (define_insn_and_split "*seqsi_zero_extend"
954 [(set (match_operand:DI 0 "register_operand" "=r")
955 (eq:DI (match_operand:SI 1 "register_operand" "r")
957 (clobber (reg:CC 100))]
961 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
964 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
966 (ltu:SI (reg:CC_NOOV 100)
969 [(set_attr "length" "2")])
971 (define_insn_and_split "*seqdi_zero"
972 [(set (match_operand:DI 0 "register_operand" "=&r")
973 (eq:DI (match_operand:DI 1 "register_operand" "r")
977 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
978 [(set (match_dup 0) (const_int 0))
979 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
984 [(set_attr "length" "2")])
986 (define_insn_and_split "*neg_seqdi_zero"
987 [(set (match_operand:DI 0 "register_operand" "=&r")
988 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
992 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
993 [(set (match_dup 0) (const_int 0))
994 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
999 [(set_attr "length" "2")])
1001 (define_insn_and_split "*seqdi_zero_trunc"
1002 [(set (match_operand:SI 0 "register_operand" "=&r")
1003 (eq:SI (match_operand:DI 1 "register_operand" "r")
1007 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1008 [(set (match_dup 0) (const_int 0))
1009 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1014 [(set_attr "length" "2")])
1016 ;; We can also do (x + (i == 0)) and related, so put them in.
1017 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1020 (define_insn_and_split "*x_plus_i_ne_0"
1021 [(set (match_operand:SI 0 "register_operand" "=r")
1022 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1024 (match_operand:SI 2 "register_operand" "r")))
1025 (clobber (reg:CC 100))]
1029 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1031 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1034 [(set_attr "length" "2")])
1036 (define_insn_and_split "*x_minus_i_ne_0"
1037 [(set (match_operand:SI 0 "register_operand" "=r")
1038 (minus:SI (match_operand:SI 2 "register_operand" "r")
1039 (ne:SI (match_operand:SI 1 "register_operand" "r")
1041 (clobber (reg:CC 100))]
1045 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1047 (set (match_dup 0) (minus:SI (match_dup 2)
1048 (ltu:SI (reg:CC 100) (const_int 0))))]
1050 [(set_attr "length" "2")])
1052 (define_insn_and_split "*x_plus_i_eq_0"
1053 [(set (match_operand:SI 0 "register_operand" "=r")
1054 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1056 (match_operand:SI 2 "register_operand" "r")))
1057 (clobber (reg:CC 100))]
1061 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1063 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1066 [(set_attr "length" "2")])
1068 (define_insn_and_split "*x_minus_i_eq_0"
1069 [(set (match_operand:SI 0 "register_operand" "=r")
1070 (minus:SI (match_operand:SI 2 "register_operand" "r")
1071 (eq:SI (match_operand:SI 1 "register_operand" "r")
1073 (clobber (reg:CC 100))]
1077 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1079 (set (match_dup 0) (minus:SI (match_dup 2)
1080 (geu:SI (reg:CC 100) (const_int 0))))]
1082 [(set_attr "length" "2")])
1084 ;; We can also do GEU and LTU directly, but these operate after a compare.
1085 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1088 (define_insn "*sltu_insn"
1089 [(set (match_operand:SI 0 "register_operand" "=r")
1090 (ltu:SI (reg:CC 100) (const_int 0)))]
1093 [(set_attr "type" "ialuX")])
1095 (define_insn "*neg_sltu_insn"
1096 [(set (match_operand:SI 0 "register_operand" "=r")
1097 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1100 [(set_attr "type" "ialuX")])
1102 ;; ??? Combine should canonicalize these next two to the same pattern.
1103 (define_insn "*neg_sltu_minus_x"
1104 [(set (match_operand:SI 0 "register_operand" "=r")
1105 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1106 (match_operand:SI 1 "arith_operand" "rI")))]
1108 "subx\t%%g0, %1, %0"
1109 [(set_attr "type" "ialuX")])
1111 (define_insn "*neg_sltu_plus_x"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1114 (match_operand:SI 1 "arith_operand" "rI"))))]
1116 "subx\t%%g0, %1, %0"
1117 [(set_attr "type" "ialuX")])
1119 (define_insn "*sgeu_insn"
1120 [(set (match_operand:SI 0 "register_operand" "=r")
1121 (geu:SI (reg:CC 100) (const_int 0)))]
1123 "subx\t%%g0, -1, %0"
1124 [(set_attr "type" "ialuX")])
1126 (define_insn "*neg_sgeu_insn"
1127 [(set (match_operand:SI 0 "register_operand" "=r")
1128 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1130 "addx\t%%g0, -1, %0"
1131 [(set_attr "type" "ialuX")])
1133 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1134 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1137 (define_insn "*sltu_plus_x"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1140 (match_operand:SI 1 "arith_operand" "rI")))]
1142 "addx\t%%g0, %1, %0"
1143 [(set_attr "type" "ialuX")])
1145 (define_insn "*sltu_plus_x_plus_y"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1148 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1149 (match_operand:SI 2 "arith_operand" "rI"))))]
1152 [(set_attr "type" "ialuX")])
1154 (define_insn "*x_minus_sltu"
1155 [(set (match_operand:SI 0 "register_operand" "=r")
1156 (minus:SI (match_operand:SI 1 "register_operand" "r")
1157 (ltu:SI (reg:CC 100) (const_int 0))))]
1160 [(set_attr "type" "ialuX")])
1162 ;; ??? Combine should canonicalize these next two to the same pattern.
1163 (define_insn "*x_minus_y_minus_sltu"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1166 (match_operand:SI 2 "arith_operand" "rI"))
1167 (ltu:SI (reg:CC 100) (const_int 0))))]
1170 [(set_attr "type" "ialuX")])
1172 (define_insn "*x_minus_sltu_plus_y"
1173 [(set (match_operand:SI 0 "register_operand" "=r")
1174 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1175 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1176 (match_operand:SI 2 "arith_operand" "rI"))))]
1179 [(set_attr "type" "ialuX")])
1181 (define_insn "*sgeu_plus_x"
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1183 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1184 (match_operand:SI 1 "register_operand" "r")))]
1187 [(set_attr "type" "ialuX")])
1189 (define_insn "*x_minus_sgeu"
1190 [(set (match_operand:SI 0 "register_operand" "=r")
1191 (minus:SI (match_operand:SI 1 "register_operand" "r")
1192 (geu:SI (reg:CC 100) (const_int 0))))]
1195 [(set_attr "type" "ialuX")])
1198 [(set (match_operand:SI 0 "register_operand" "")
1199 (match_operator:SI 2 "noov_compare_op"
1200 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1202 ;; 32 bit LTU/GEU are better implemented using addx/subx
1203 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1204 && (GET_MODE (operands[1]) == CCXmode
1205 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1206 [(set (match_dup 0) (const_int 0))
1208 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1214 ;; These control RTL generation for conditional jump insns
1216 ;; The quad-word fp compare library routines all return nonzero to indicate
1217 ;; true, which is different from the equivalent libgcc routines, so we must
1218 ;; handle them specially here.
1220 (define_expand "beq"
1222 (if_then_else (eq (match_dup 1) (const_int 0))
1223 (label_ref (match_operand 0 "" ""))
1227 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1228 && GET_CODE (sparc_compare_op0) == REG
1229 && GET_MODE (sparc_compare_op0) == DImode)
1231 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1234 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1236 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1237 emit_jump_insn (gen_bne (operands[0]));
1240 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1243 (define_expand "bne"
1245 (if_then_else (ne (match_dup 1) (const_int 0))
1246 (label_ref (match_operand 0 "" ""))
1250 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1251 && GET_CODE (sparc_compare_op0) == REG
1252 && GET_MODE (sparc_compare_op0) == DImode)
1254 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1257 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1259 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1260 emit_jump_insn (gen_bne (operands[0]));
1263 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1266 (define_expand "bgt"
1268 (if_then_else (gt (match_dup 1) (const_int 0))
1269 (label_ref (match_operand 0 "" ""))
1273 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1274 && GET_CODE (sparc_compare_op0) == REG
1275 && GET_MODE (sparc_compare_op0) == DImode)
1277 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1280 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1282 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1283 emit_jump_insn (gen_bne (operands[0]));
1286 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1289 (define_expand "bgtu"
1291 (if_then_else (gtu (match_dup 1) (const_int 0))
1292 (label_ref (match_operand 0 "" ""))
1296 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1299 (define_expand "blt"
1301 (if_then_else (lt (match_dup 1) (const_int 0))
1302 (label_ref (match_operand 0 "" ""))
1306 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1307 && GET_CODE (sparc_compare_op0) == REG
1308 && GET_MODE (sparc_compare_op0) == DImode)
1310 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1313 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1315 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1316 emit_jump_insn (gen_bne (operands[0]));
1319 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1322 (define_expand "bltu"
1324 (if_then_else (ltu (match_dup 1) (const_int 0))
1325 (label_ref (match_operand 0 "" ""))
1329 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1332 (define_expand "bge"
1334 (if_then_else (ge (match_dup 1) (const_int 0))
1335 (label_ref (match_operand 0 "" ""))
1339 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1340 && GET_CODE (sparc_compare_op0) == REG
1341 && GET_MODE (sparc_compare_op0) == DImode)
1343 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1346 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1348 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1349 emit_jump_insn (gen_bne (operands[0]));
1352 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1355 (define_expand "bgeu"
1357 (if_then_else (geu (match_dup 1) (const_int 0))
1358 (label_ref (match_operand 0 "" ""))
1362 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1365 (define_expand "ble"
1367 (if_then_else (le (match_dup 1) (const_int 0))
1368 (label_ref (match_operand 0 "" ""))
1372 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1373 && GET_CODE (sparc_compare_op0) == REG
1374 && GET_MODE (sparc_compare_op0) == DImode)
1376 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1379 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1381 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1382 emit_jump_insn (gen_bne (operands[0]));
1385 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1388 (define_expand "bleu"
1390 (if_then_else (leu (match_dup 1) (const_int 0))
1391 (label_ref (match_operand 0 "" ""))
1395 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1398 (define_expand "bunordered"
1400 (if_then_else (unordered (match_dup 1) (const_int 0))
1401 (label_ref (match_operand 0 "" ""))
1405 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1407 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1409 emit_jump_insn (gen_beq (operands[0]));
1412 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1416 (define_expand "bordered"
1418 (if_then_else (ordered (match_dup 1) (const_int 0))
1419 (label_ref (match_operand 0 "" ""))
1423 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1425 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1426 emit_jump_insn (gen_bne (operands[0]));
1429 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1433 (define_expand "bungt"
1435 (if_then_else (ungt (match_dup 1) (const_int 0))
1436 (label_ref (match_operand 0 "" ""))
1440 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1442 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1443 emit_jump_insn (gen_bgt (operands[0]));
1446 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1449 (define_expand "bunlt"
1451 (if_then_else (unlt (match_dup 1) (const_int 0))
1452 (label_ref (match_operand 0 "" ""))
1456 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1458 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1459 emit_jump_insn (gen_bne (operands[0]));
1462 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1465 (define_expand "buneq"
1467 (if_then_else (uneq (match_dup 1) (const_int 0))
1468 (label_ref (match_operand 0 "" ""))
1472 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1474 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1475 emit_jump_insn (gen_beq (operands[0]));
1478 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1481 (define_expand "bunge"
1483 (if_then_else (unge (match_dup 1) (const_int 0))
1484 (label_ref (match_operand 0 "" ""))
1488 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1490 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1491 emit_jump_insn (gen_bne (operands[0]));
1494 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1497 (define_expand "bunle"
1499 (if_then_else (unle (match_dup 1) (const_int 0))
1500 (label_ref (match_operand 0 "" ""))
1504 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1506 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1507 emit_jump_insn (gen_bne (operands[0]));
1510 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1513 (define_expand "bltgt"
1515 (if_then_else (ltgt (match_dup 1) (const_int 0))
1516 (label_ref (match_operand 0 "" ""))
1520 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1522 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1523 emit_jump_insn (gen_bne (operands[0]));
1526 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1529 ;; Now match both normal and inverted jump.
1531 ;; XXX fpcmp nop braindamage
1532 (define_insn "*normal_branch"
1534 (if_then_else (match_operator 0 "noov_compare_op"
1535 [(reg 100) (const_int 0)])
1536 (label_ref (match_operand 1 "" ""))
1540 return output_cbranch (operands[0], operands[1], 1, 0,
1541 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1542 ! final_sequence, insn);
1544 [(set_attr "type" "branch")
1545 (set_attr "branch_type" "icc")])
1547 ;; XXX fpcmp nop braindamage
1548 (define_insn "*inverted_branch"
1550 (if_then_else (match_operator 0 "noov_compare_op"
1551 [(reg 100) (const_int 0)])
1553 (label_ref (match_operand 1 "" ""))))]
1556 return output_cbranch (operands[0], operands[1], 1, 1,
1557 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1558 ! final_sequence, insn);
1560 [(set_attr "type" "branch")
1561 (set_attr "branch_type" "icc")])
1563 ;; XXX fpcmp nop braindamage
1564 (define_insn "*normal_fp_branch"
1566 (if_then_else (match_operator 1 "comparison_operator"
1567 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1569 (label_ref (match_operand 2 "" ""))
1573 return output_cbranch (operands[1], operands[2], 2, 0,
1574 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1575 ! final_sequence, insn);
1577 [(set_attr "type" "branch")
1578 (set_attr "branch_type" "fcc")])
1580 ;; XXX fpcmp nop braindamage
1581 (define_insn "*inverted_fp_branch"
1583 (if_then_else (match_operator 1 "comparison_operator"
1584 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1587 (label_ref (match_operand 2 "" ""))))]
1590 return output_cbranch (operands[1], operands[2], 2, 1,
1591 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1592 ! final_sequence, insn);
1594 [(set_attr "type" "branch")
1595 (set_attr "branch_type" "fcc")])
1597 ;; XXX fpcmp nop braindamage
1598 (define_insn "*normal_fpe_branch"
1600 (if_then_else (match_operator 1 "comparison_operator"
1601 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1603 (label_ref (match_operand 2 "" ""))
1607 return output_cbranch (operands[1], operands[2], 2, 0,
1608 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1609 ! final_sequence, insn);
1611 [(set_attr "type" "branch")
1612 (set_attr "branch_type" "fcc")])
1614 ;; XXX fpcmp nop braindamage
1615 (define_insn "*inverted_fpe_branch"
1617 (if_then_else (match_operator 1 "comparison_operator"
1618 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1621 (label_ref (match_operand 2 "" ""))))]
1624 return output_cbranch (operands[1], operands[2], 2, 1,
1625 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1626 ! final_sequence, insn);
1628 [(set_attr "type" "branch")
1629 (set_attr "branch_type" "fcc")])
1631 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1632 ;; in the architecture.
1634 ;; There are no 32 bit brreg insns.
1637 (define_insn "*normal_int_branch_sp64"
1639 (if_then_else (match_operator 0 "v9_regcmp_op"
1640 [(match_operand:DI 1 "register_operand" "r")
1642 (label_ref (match_operand 2 "" ""))
1646 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1647 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1648 ! final_sequence, insn);
1650 [(set_attr "type" "branch")
1651 (set_attr "branch_type" "reg")])
1654 (define_insn "*inverted_int_branch_sp64"
1656 (if_then_else (match_operator 0 "v9_regcmp_op"
1657 [(match_operand:DI 1 "register_operand" "r")
1660 (label_ref (match_operand 2 "" ""))))]
1663 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1664 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1665 ! final_sequence, insn);
1667 [(set_attr "type" "branch")
1668 (set_attr "branch_type" "reg")])
1670 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1671 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1672 ;; that adds the PC value at the call point to operand 0.
1674 (define_insn "load_pcrel_sym"
1675 [(set (match_operand 0 "register_operand" "=r")
1676 (unspec [(match_operand 1 "symbolic_operand" "")
1677 (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1678 (clobber (reg:SI 15))]
1681 if (flag_delayed_branch)
1682 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1684 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1686 [(set (attr "type") (const_string "multi"))
1687 (set (attr "length")
1688 (if_then_else (eq_attr "delayed_branch" "true")
1692 ;; Move instructions
1694 (define_expand "movqi"
1695 [(set (match_operand:QI 0 "general_operand" "")
1696 (match_operand:QI 1 "general_operand" ""))]
1699 /* Working with CONST_INTs is easier, so convert
1700 a double if needed. */
1701 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1703 operands[1] = GEN_INT (trunc_int_for_mode
1704 (CONST_DOUBLE_LOW (operands[1]), QImode));
1707 /* Handle sets of MEM first. */
1708 if (GET_CODE (operands[0]) == MEM)
1710 if (reg_or_0_operand (operands[1], QImode))
1713 if (! reload_in_progress)
1715 operands[0] = validize_mem (operands[0]);
1716 operands[1] = force_reg (QImode, operands[1]);
1720 /* Fixup TLS cases. */
1721 if (tls_symbolic_operand (operands [1]))
1722 operands[1] = legitimize_tls_address (operands[1]);
1724 /* Fixup PIC cases. */
1727 if (CONSTANT_P (operands[1])
1728 && pic_address_needs_scratch (operands[1]))
1729 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1731 if (symbolic_operand (operands[1], QImode))
1733 operands[1] = legitimize_pic_address (operands[1],
1735 (reload_in_progress ?
1742 /* All QI constants require only one insn, so proceed. */
1748 (define_insn "*movqi_insn"
1749 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1750 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1751 "(register_operand (operands[0], QImode)
1752 || reg_or_0_operand (operands[1], QImode))"
1757 [(set_attr "type" "*,load,store")
1758 (set_attr "us3load_type" "*,3cycle,*")])
1760 (define_expand "movhi"
1761 [(set (match_operand:HI 0 "general_operand" "")
1762 (match_operand:HI 1 "general_operand" ""))]
1765 /* Working with CONST_INTs is easier, so convert
1766 a double if needed. */
1767 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1768 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1770 /* Handle sets of MEM first. */
1771 if (GET_CODE (operands[0]) == MEM)
1773 if (reg_or_0_operand (operands[1], HImode))
1776 if (! reload_in_progress)
1778 operands[0] = validize_mem (operands[0]);
1779 operands[1] = force_reg (HImode, operands[1]);
1783 /* Fixup TLS cases. */
1784 if (tls_symbolic_operand (operands [1]))
1785 operands[1] = legitimize_tls_address (operands[1]);
1787 /* Fixup PIC cases. */
1790 if (CONSTANT_P (operands[1])
1791 && pic_address_needs_scratch (operands[1]))
1792 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1794 if (symbolic_operand (operands[1], HImode))
1796 operands[1] = legitimize_pic_address (operands[1],
1798 (reload_in_progress ?
1805 /* This makes sure we will not get rematched due to splittage. */
1806 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1808 else if (CONSTANT_P (operands[1])
1809 && GET_CODE (operands[1]) != HIGH
1810 && GET_CODE (operands[1]) != LO_SUM)
1812 sparc_emit_set_const32 (operands[0], operands[1]);
1819 (define_insn "*movhi_const64_special"
1820 [(set (match_operand:HI 0 "register_operand" "=r")
1821 (match_operand:HI 1 "const64_high_operand" ""))]
1823 "sethi\t%%hi(%a1), %0")
1825 (define_insn "*movhi_insn"
1826 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1827 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1828 "(register_operand (operands[0], HImode)
1829 || reg_or_0_operand (operands[1], HImode))"
1832 sethi\t%%hi(%a1), %0
1835 [(set_attr "type" "*,*,load,store")
1836 (set_attr "us3load_type" "*,*,3cycle,*")])
1838 ;; We always work with constants here.
1839 (define_insn "*movhi_lo_sum"
1840 [(set (match_operand:HI 0 "register_operand" "=r")
1841 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1842 (match_operand:HI 2 "small_int" "I")))]
1846 (define_expand "movsi"
1847 [(set (match_operand:SI 0 "general_operand" "")
1848 (match_operand:SI 1 "general_operand" ""))]
1851 /* Working with CONST_INTs is easier, so convert
1852 a double if needed. */
1853 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1854 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1856 /* Handle sets of MEM first. */
1857 if (GET_CODE (operands[0]) == MEM)
1859 if (reg_or_0_operand (operands[1], SImode))
1862 if (! reload_in_progress)
1864 operands[0] = validize_mem (operands[0]);
1865 operands[1] = force_reg (SImode, operands[1]);
1869 /* Fixup TLS cases. */
1870 if (tls_symbolic_operand (operands [1]))
1871 operands[1] = legitimize_tls_address (operands[1]);
1873 /* Fixup PIC cases. */
1876 if (CONSTANT_P (operands[1])
1877 && pic_address_needs_scratch (operands[1]))
1878 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1880 if (GET_CODE (operands[1]) == LABEL_REF)
1883 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1887 if (symbolic_operand (operands[1], SImode))
1889 operands[1] = legitimize_pic_address (operands[1],
1891 (reload_in_progress ?
1898 /* If we are trying to toss an integer constant into the
1899 FPU registers, force it into memory. */
1900 if (GET_CODE (operands[0]) == REG
1901 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1902 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1903 && CONSTANT_P (operands[1]))
1904 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1907 /* This makes sure we will not get rematched due to splittage. */
1908 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1910 else if (CONSTANT_P (operands[1])
1911 && GET_CODE (operands[1]) != HIGH
1912 && GET_CODE (operands[1]) != LO_SUM)
1914 sparc_emit_set_const32 (operands[0], operands[1]);
1921 ;; This is needed to show CSE exactly which bits are set
1922 ;; in a 64-bit register by sethi instructions.
1923 (define_insn "*movsi_const64_special"
1924 [(set (match_operand:SI 0 "register_operand" "=r")
1925 (match_operand:SI 1 "const64_high_operand" ""))]
1927 "sethi\t%%hi(%a1), %0")
1929 (define_insn "*movsi_insn"
1930 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1931 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1932 "(register_operand (operands[0], SImode)
1933 || reg_or_0_operand (operands[1], SImode))"
1937 sethi\t%%hi(%a1), %0
1944 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1946 (define_insn "*movsi_lo_sum"
1947 [(set (match_operand:SI 0 "register_operand" "=r")
1948 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1949 (match_operand:SI 2 "immediate_operand" "in")))]
1951 "or\t%1, %%lo(%a2), %0")
1953 (define_insn "*movsi_high"
1954 [(set (match_operand:SI 0 "register_operand" "=r")
1955 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1957 "sethi\t%%hi(%a1), %0")
1959 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1960 ;; so that CSE won't optimize the address computation away.
1961 (define_insn "movsi_lo_sum_pic"
1962 [(set (match_operand:SI 0 "register_operand" "=r")
1963 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1964 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1966 "or\t%1, %%lo(%a2), %0")
1968 (define_insn "movsi_high_pic"
1969 [(set (match_operand:SI 0 "register_operand" "=r")
1970 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1971 "flag_pic && check_pic (1)"
1972 "sethi\t%%hi(%a1), %0")
1974 (define_expand "movsi_pic_label_ref"
1975 [(set (match_dup 3) (high:SI
1976 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1977 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1978 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1979 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1980 (set (match_operand:SI 0 "register_operand" "=r")
1981 (minus:SI (match_dup 5) (match_dup 4)))]
1984 current_function_uses_pic_offset_table = 1;
1985 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1988 operands[3] = operands[0];
1989 operands[4] = operands[0];
1993 operands[3] = gen_reg_rtx (SImode);
1994 operands[4] = gen_reg_rtx (SImode);
1996 operands[5] = pic_offset_table_rtx;
1999 (define_insn "*movsi_high_pic_label_ref"
2000 [(set (match_operand:SI 0 "register_operand" "=r")
2002 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2003 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2005 "sethi\t%%hi(%a2-(%a1-.)), %0")
2007 (define_insn "*movsi_lo_sum_pic_label_ref"
2008 [(set (match_operand:SI 0 "register_operand" "=r")
2009 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2010 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2011 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2013 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2015 (define_expand "movdi"
2016 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2017 (match_operand:DI 1 "general_operand" ""))]
2020 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2021 if (GET_CODE (operands[1]) == CONST_DOUBLE
2022 #if HOST_BITS_PER_WIDE_INT == 32
2023 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2024 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2025 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2026 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2029 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2031 /* Handle MEM cases first. */
2032 if (GET_CODE (operands[0]) == MEM)
2034 /* If it's a REG, we can always do it.
2035 The const zero case is more complex, on v9
2036 we can always perform it. */
2037 if (register_operand (operands[1], DImode)
2039 && (operands[1] == const0_rtx)))
2042 if (! reload_in_progress)
2044 operands[0] = validize_mem (operands[0]);
2045 operands[1] = force_reg (DImode, operands[1]);
2049 /* Fixup TLS cases. */
2050 if (tls_symbolic_operand (operands [1]))
2051 operands[1] = legitimize_tls_address (operands[1]);
2055 if (CONSTANT_P (operands[1])
2056 && pic_address_needs_scratch (operands[1]))
2057 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2059 if (GET_CODE (operands[1]) == LABEL_REF)
2061 if (! TARGET_ARCH64)
2063 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2067 if (symbolic_operand (operands[1], DImode))
2069 operands[1] = legitimize_pic_address (operands[1],
2071 (reload_in_progress ?
2078 /* If we are trying to toss an integer constant into the
2079 FPU registers, force it into memory. */
2080 if (GET_CODE (operands[0]) == REG
2081 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2082 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2083 && CONSTANT_P (operands[1]))
2084 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2087 /* This makes sure we will not get rematched due to splittage. */
2088 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2090 else if (TARGET_ARCH64
2091 && CONSTANT_P (operands[1])
2092 && GET_CODE (operands[1]) != HIGH
2093 && GET_CODE (operands[1]) != LO_SUM)
2095 sparc_emit_set_const64 (operands[0], operands[1]);
2103 ;; Be careful, fmovd does not exist when !v9.
2104 ;; We match MEM moves directly when we have correct even
2105 ;; numbered registers, but fall into splits otherwise.
2106 ;; The constraint ordering here is really important to
2107 ;; avoid insane problems in reload, especially for patterns
2110 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2111 ;; (const_int -5016)))
2115 (define_insn "*movdi_insn_sp32_v9"
2116 [(set (match_operand:DI 0 "nonimmediate_operand"
2117 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2118 (match_operand:DI 1 "input_operand"
2119 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2120 "! TARGET_ARCH64 && TARGET_V9
2121 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2138 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2139 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2140 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2142 (define_insn "*movdi_insn_sp32"
2143 [(set (match_operand:DI 0 "nonimmediate_operand"
2144 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2145 (match_operand:DI 1 "input_operand"
2146 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2148 && (register_operand (operands[0], DImode)
2149 || register_operand (operands[1], DImode))"
2163 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2164 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2166 ;; The following are generated by sparc_emit_set_const64
2167 (define_insn "*movdi_sp64_dbl"
2168 [(set (match_operand:DI 0 "register_operand" "=r")
2169 (match_operand:DI 1 "const64_operand" ""))]
2171 && HOST_BITS_PER_WIDE_INT != 64)"
2174 ;; This is needed to show CSE exactly which bits are set
2175 ;; in a 64-bit register by sethi instructions.
2176 (define_insn "*movdi_const64_special"
2177 [(set (match_operand:DI 0 "register_operand" "=r")
2178 (match_operand:DI 1 "const64_high_operand" ""))]
2180 "sethi\t%%hi(%a1), %0")
2182 (define_insn "*movdi_insn_sp64_novis"
2183 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2184 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2185 "TARGET_ARCH64 && ! TARGET_VIS
2186 && (register_operand (operands[0], DImode)
2187 || reg_or_0_operand (operands[1], DImode))"
2190 sethi\t%%hi(%a1), %0
2197 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2198 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2200 (define_insn "*movdi_insn_sp64_vis"
2201 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2202 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2203 "TARGET_ARCH64 && TARGET_VIS &&
2204 (register_operand (operands[0], DImode)
2205 || reg_or_0_operand (operands[1], DImode))"
2208 sethi\t%%hi(%a1), %0
2216 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2217 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2219 (define_expand "movdi_pic_label_ref"
2220 [(set (match_dup 3) (high:DI
2221 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2222 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2223 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2224 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2225 (set (match_operand:DI 0 "register_operand" "=r")
2226 (minus:DI (match_dup 5) (match_dup 4)))]
2227 "TARGET_ARCH64 && flag_pic"
2229 current_function_uses_pic_offset_table = 1;
2230 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2233 operands[3] = operands[0];
2234 operands[4] = operands[0];
2238 operands[3] = gen_reg_rtx (DImode);
2239 operands[4] = gen_reg_rtx (DImode);
2241 operands[5] = pic_offset_table_rtx;
2244 (define_insn "*movdi_high_pic_label_ref"
2245 [(set (match_operand:DI 0 "register_operand" "=r")
2247 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2248 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2249 "TARGET_ARCH64 && flag_pic"
2250 "sethi\t%%hi(%a2-(%a1-.)), %0")
2252 (define_insn "*movdi_lo_sum_pic_label_ref"
2253 [(set (match_operand:DI 0 "register_operand" "=r")
2254 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2255 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2256 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2257 "TARGET_ARCH64 && flag_pic"
2258 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2260 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2261 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2263 (define_insn "movdi_lo_sum_pic"
2264 [(set (match_operand:DI 0 "register_operand" "=r")
2265 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2266 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2267 "TARGET_ARCH64 && flag_pic"
2268 "or\t%1, %%lo(%a2), %0")
2270 (define_insn "movdi_high_pic"
2271 [(set (match_operand:DI 0 "register_operand" "=r")
2272 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2273 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2274 "sethi\t%%hi(%a1), %0")
2276 (define_insn "*sethi_di_medlow_embmedany_pic"
2277 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2279 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2280 "sethi\t%%hi(%a1), %0")
2282 (define_insn "*sethi_di_medlow"
2283 [(set (match_operand:DI 0 "register_operand" "=r")
2284 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2285 "TARGET_CM_MEDLOW && check_pic (1)"
2286 "sethi\t%%hi(%a1), %0")
2288 (define_insn "*losum_di_medlow"
2289 [(set (match_operand:DI 0 "register_operand" "=r")
2290 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2291 (match_operand:DI 2 "symbolic_operand" "")))]
2293 "or\t%1, %%lo(%a2), %0")
2295 (define_insn "seth44"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2299 "sethi\t%%h44(%a1), %0")
2301 (define_insn "setm44"
2302 [(set (match_operand:DI 0 "register_operand" "=r")
2303 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2304 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2306 "or\t%1, %%m44(%a2), %0")
2308 (define_insn "setl44"
2309 [(set (match_operand:DI 0 "register_operand" "=r")
2310 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2311 (match_operand:DI 2 "symbolic_operand" "")))]
2313 "or\t%1, %%l44(%a2), %0")
2315 (define_insn "sethh"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2317 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2319 "sethi\t%%hh(%a1), %0")
2321 (define_insn "setlm"
2322 [(set (match_operand:DI 0 "register_operand" "=r")
2323 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2325 "sethi\t%%lm(%a1), %0")
2327 (define_insn "sethm"
2328 [(set (match_operand:DI 0 "register_operand" "=r")
2329 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2330 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2332 "or\t%1, %%hm(%a2), %0")
2334 (define_insn "setlo"
2335 [(set (match_operand:DI 0 "register_operand" "=r")
2336 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2337 (match_operand:DI 2 "symbolic_operand" "")))]
2339 "or\t%1, %%lo(%a2), %0")
2341 (define_insn "embmedany_sethi"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2344 "TARGET_CM_EMBMEDANY && check_pic (1)"
2345 "sethi\t%%hi(%a1), %0")
2347 (define_insn "embmedany_losum"
2348 [(set (match_operand:DI 0 "register_operand" "=r")
2349 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2350 (match_operand:DI 2 "data_segment_operand" "")))]
2351 "TARGET_CM_EMBMEDANY"
2352 "add\t%1, %%lo(%a2), %0")
2354 (define_insn "embmedany_brsum"
2355 [(set (match_operand:DI 0 "register_operand" "=r")
2356 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2357 "TARGET_CM_EMBMEDANY"
2360 (define_insn "embmedany_textuhi"
2361 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2363 "TARGET_CM_EMBMEDANY && check_pic (1)"
2364 "sethi\t%%uhi(%a1), %0")
2366 (define_insn "embmedany_texthi"
2367 [(set (match_operand:DI 0 "register_operand" "=r")
2368 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2369 "TARGET_CM_EMBMEDANY && check_pic (1)"
2370 "sethi\t%%hi(%a1), %0")
2372 (define_insn "embmedany_textulo"
2373 [(set (match_operand:DI 0 "register_operand" "=r")
2374 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2375 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2376 "TARGET_CM_EMBMEDANY"
2377 "or\t%1, %%ulo(%a2), %0")
2379 (define_insn "embmedany_textlo"
2380 [(set (match_operand:DI 0 "register_operand" "=r")
2381 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2382 (match_operand:DI 2 "text_segment_operand" "")))]
2383 "TARGET_CM_EMBMEDANY"
2384 "or\t%1, %%lo(%a2), %0")
2386 ;; Now some patterns to help reload out a bit.
2387 (define_expand "reload_indi"
2388 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2389 (match_operand:DI 1 "immediate_operand" "")
2390 (match_operand:TI 2 "register_operand" "=&r")])]
2392 || TARGET_CM_EMBMEDANY)
2395 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2399 (define_expand "reload_outdi"
2400 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2401 (match_operand:DI 1 "immediate_operand" "")
2402 (match_operand:TI 2 "register_operand" "=&r")])]
2404 || TARGET_CM_EMBMEDANY)
2407 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2411 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2413 [(set (match_operand:DI 0 "register_operand" "")
2414 (match_operand:DI 1 "const_int_operand" ""))]
2415 "! TARGET_ARCH64 && reload_completed"
2416 [(clobber (const_int 0))]
2418 #if HOST_BITS_PER_WIDE_INT == 32
2419 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2420 (INTVAL (operands[1]) < 0) ?
2423 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2426 unsigned int low, high;
2428 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2429 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2430 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2432 /* Slick... but this trick loses if this subreg constant part
2433 can be done in one insn. */
2434 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2435 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2436 gen_highpart (SImode, operands[0])));
2438 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2444 [(set (match_operand:DI 0 "register_operand" "")
2445 (match_operand:DI 1 "const_double_operand" ""))]
2449 && ((GET_CODE (operands[0]) == REG
2450 && REGNO (operands[0]) < 32)
2451 || (GET_CODE (operands[0]) == SUBREG
2452 && GET_CODE (SUBREG_REG (operands[0])) == REG
2453 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2454 [(clobber (const_int 0))]
2456 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2457 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2459 /* Slick... but this trick loses if this subreg constant part
2460 can be done in one insn. */
2461 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2462 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2463 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2465 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2466 gen_highpart (SImode, operands[0])));
2470 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2471 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2477 [(set (match_operand:DI 0 "register_operand" "")
2478 (match_operand:DI 1 "register_operand" ""))]
2482 && ((GET_CODE (operands[0]) == REG
2483 && REGNO (operands[0]) < 32)
2484 || (GET_CODE (operands[0]) == SUBREG
2485 && GET_CODE (SUBREG_REG (operands[0])) == REG
2486 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2487 [(clobber (const_int 0))]
2489 rtx set_dest = operands[0];
2490 rtx set_src = operands[1];
2494 dest1 = gen_highpart (SImode, set_dest);
2495 dest2 = gen_lowpart (SImode, set_dest);
2496 src1 = gen_highpart (SImode, set_src);
2497 src2 = gen_lowpart (SImode, set_src);
2499 /* Now emit using the real source and destination we found, swapping
2500 the order if we detect overlap. */
2501 if (reg_overlap_mentioned_p (dest1, src2))
2503 emit_insn (gen_movsi (dest2, src2));
2504 emit_insn (gen_movsi (dest1, src1));
2508 emit_insn (gen_movsi (dest1, src1));
2509 emit_insn (gen_movsi (dest2, src2));
2514 ;; Now handle the cases of memory moves from/to non-even
2515 ;; DI mode register pairs.
2517 [(set (match_operand:DI 0 "register_operand" "")
2518 (match_operand:DI 1 "memory_operand" ""))]
2521 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2522 [(clobber (const_int 0))]
2524 rtx word0 = adjust_address (operands[1], SImode, 0);
2525 rtx word1 = adjust_address (operands[1], SImode, 4);
2526 rtx high_part = gen_highpart (SImode, operands[0]);
2527 rtx low_part = gen_lowpart (SImode, operands[0]);
2529 if (reg_overlap_mentioned_p (high_part, word1))
2531 emit_insn (gen_movsi (low_part, word1));
2532 emit_insn (gen_movsi (high_part, word0));
2536 emit_insn (gen_movsi (high_part, word0));
2537 emit_insn (gen_movsi (low_part, word1));
2543 [(set (match_operand:DI 0 "memory_operand" "")
2544 (match_operand:DI 1 "register_operand" ""))]
2547 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2548 [(clobber (const_int 0))]
2550 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2551 gen_highpart (SImode, operands[1])));
2552 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2553 gen_lowpart (SImode, operands[1])));
2558 [(set (match_operand:DI 0 "memory_operand" "")
2563 && ! mem_min_alignment (operands[0], 8)))
2564 && offsettable_memref_p (operands[0])"
2565 [(clobber (const_int 0))]
2567 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2568 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2572 ;; Floating point move insns
2574 (define_insn "*movsf_insn_novis"
2575 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2576 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2577 "(TARGET_FPU && ! TARGET_VIS)
2578 && (register_operand (operands[0], SFmode)
2579 || register_operand (operands[1], SFmode)
2580 || fp_zero_operand (operands[1], SFmode))"
2582 if (GET_CODE (operands[1]) == CONST_DOUBLE
2583 && (which_alternative == 2
2584 || which_alternative == 3
2585 || which_alternative == 4))
2590 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2591 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2592 operands[1] = GEN_INT (i);
2595 switch (which_alternative)
2598 return "fmovs\t%1, %0";
2602 return "sethi\t%%hi(%a1), %0";
2604 return "mov\t%1, %0";
2609 return "ld\t%1, %0";
2612 return "st\t%r1, %0";
2617 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2619 (define_insn "*movsf_insn_vis"
2620 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2621 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2622 "(TARGET_FPU && TARGET_VIS)
2623 && (register_operand (operands[0], SFmode)
2624 || register_operand (operands[1], SFmode)
2625 || fp_zero_operand (operands[1], SFmode))"
2627 if (GET_CODE (operands[1]) == CONST_DOUBLE
2628 && (which_alternative == 3
2629 || which_alternative == 4
2630 || which_alternative == 5))
2635 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2636 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2637 operands[1] = GEN_INT (i);
2640 switch (which_alternative)
2643 return "fmovs\t%1, %0";
2645 return "fzeros\t%0";
2649 return "sethi\t%%hi(%a1), %0";
2651 return "mov\t%1, %0";
2656 return "ld\t%1, %0";
2659 return "st\t%r1, %0";
2664 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2666 ;; Exactly the same as above, except that all `f' cases are deleted.
2667 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2670 (define_insn "*movsf_no_f_insn"
2671 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2672 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2674 && (register_operand (operands[0], SFmode)
2675 || register_operand (operands[1], SFmode)
2676 || fp_zero_operand (operands[1], SFmode))"
2678 if (GET_CODE (operands[1]) == CONST_DOUBLE
2679 && (which_alternative == 1
2680 || which_alternative == 2
2681 || which_alternative == 3))
2686 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2687 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2688 operands[1] = GEN_INT (i);
2691 switch (which_alternative)
2696 return "sethi\t%%hi(%a1), %0";
2698 return "mov\t%1, %0";
2702 return "ld\t%1, %0";
2704 return "st\t%r1, %0";
2709 [(set_attr "type" "*,*,*,*,load,store")])
2711 (define_insn "*movsf_lo_sum"
2712 [(set (match_operand:SF 0 "register_operand" "=r")
2713 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2714 (match_operand:SF 2 "const_double_operand" "S")))]
2715 "fp_high_losum_p (operands[2])"
2720 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2721 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2722 operands[2] = GEN_INT (i);
2723 return "or\t%1, %%lo(%a2), %0";
2726 (define_insn "*movsf_high"
2727 [(set (match_operand:SF 0 "register_operand" "=r")
2728 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2729 "fp_high_losum_p (operands[1])"
2734 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2735 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2736 operands[1] = GEN_INT (i);
2737 return "sethi\t%%hi(%1), %0";
2741 [(set (match_operand:SF 0 "register_operand" "")
2742 (match_operand:SF 1 "const_double_operand" ""))]
2743 "fp_high_losum_p (operands[1])
2744 && (GET_CODE (operands[0]) == REG
2745 && REGNO (operands[0]) < 32)"
2746 [(set (match_dup 0) (high:SF (match_dup 1)))
2747 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2749 (define_expand "movsf"
2750 [(set (match_operand:SF 0 "general_operand" "")
2751 (match_operand:SF 1 "general_operand" ""))]
2754 /* Force SFmode constants into memory. */
2755 if (GET_CODE (operands[0]) == REG
2756 && CONSTANT_P (operands[1]))
2758 /* emit_group_store will send such bogosity to us when it is
2759 not storing directly into memory. So fix this up to avoid
2760 crashes in output_constant_pool. */
2761 if (operands [1] == const0_rtx)
2762 operands[1] = CONST0_RTX (SFmode);
2764 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2767 /* We are able to build any SF constant in integer registers
2768 with at most 2 instructions. */
2769 if (REGNO (operands[0]) < 32)
2772 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2776 /* Handle sets of MEM first. */
2777 if (GET_CODE (operands[0]) == MEM)
2779 if (register_operand (operands[1], SFmode)
2780 || fp_zero_operand (operands[1], SFmode))
2783 if (! reload_in_progress)
2785 operands[0] = validize_mem (operands[0]);
2786 operands[1] = force_reg (SFmode, operands[1]);
2790 /* Fixup PIC cases. */
2793 if (CONSTANT_P (operands[1])
2794 && pic_address_needs_scratch (operands[1]))
2795 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2797 if (symbolic_operand (operands[1], SFmode))
2799 operands[1] = legitimize_pic_address (operands[1],
2801 (reload_in_progress ?
2811 (define_expand "movdf"
2812 [(set (match_operand:DF 0 "general_operand" "")
2813 (match_operand:DF 1 "general_operand" ""))]
2816 /* Force DFmode constants into memory. */
2817 if (GET_CODE (operands[0]) == REG
2818 && CONSTANT_P (operands[1]))
2820 /* emit_group_store will send such bogosity to us when it is
2821 not storing directly into memory. So fix this up to avoid
2822 crashes in output_constant_pool. */
2823 if (operands [1] == const0_rtx)
2824 operands[1] = CONST0_RTX (DFmode);
2826 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2827 && fp_zero_operand (operands[1], DFmode))
2830 /* We are able to build any DF constant in integer registers. */
2831 if (REGNO (operands[0]) < 32
2832 && (reload_completed || reload_in_progress))
2835 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2839 /* Handle MEM cases first. */
2840 if (GET_CODE (operands[0]) == MEM)
2842 if (register_operand (operands[1], DFmode)
2843 || fp_zero_operand (operands[1], DFmode))
2846 if (! reload_in_progress)
2848 operands[0] = validize_mem (operands[0]);
2849 operands[1] = force_reg (DFmode, operands[1]);
2853 /* Fixup PIC cases. */
2856 if (CONSTANT_P (operands[1])
2857 && pic_address_needs_scratch (operands[1]))
2858 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2860 if (symbolic_operand (operands[1], DFmode))
2862 operands[1] = legitimize_pic_address (operands[1],
2864 (reload_in_progress ?
2874 ;; Be careful, fmovd does not exist when !v9.
2875 (define_insn "*movdf_insn_sp32"
2876 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2877 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2880 && (register_operand (operands[0], DFmode)
2881 || register_operand (operands[1], DFmode)
2882 || fp_zero_operand (operands[1], DFmode))"
2894 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2895 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2897 (define_insn "*movdf_no_e_insn_sp32"
2898 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2899 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2903 && (register_operand (operands[0], DFmode)
2904 || register_operand (operands[1], DFmode)
2905 || fp_zero_operand (operands[1], DFmode))"
2912 [(set_attr "type" "load,store,*,*,*")
2913 (set_attr "length" "*,*,2,2,2")])
2915 (define_insn "*movdf_no_e_insn_v9_sp32"
2916 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2917 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2921 && (register_operand (operands[0], DFmode)
2922 || register_operand (operands[1], DFmode)
2923 || fp_zero_operand (operands[1], DFmode))"
2930 [(set_attr "type" "load,store,store,*,*")
2931 (set_attr "length" "*,*,*,2,2")])
2933 ;; We have available v9 double floats but not 64-bit
2934 ;; integer registers and no VIS.
2935 (define_insn "*movdf_insn_v9only_novis"
2936 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2937 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2942 && (register_operand (operands[0], DFmode)
2943 || register_operand (operands[1], DFmode)
2944 || fp_zero_operand (operands[1], DFmode))"
2955 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2956 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2957 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2959 ;; We have available v9 double floats but not 64-bit
2960 ;; integer registers but we have VIS.
2961 (define_insn "*movdf_insn_v9only_vis"
2962 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2963 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2967 && (register_operand (operands[0], DFmode)
2968 || register_operand (operands[1], DFmode)
2969 || fp_zero_operand (operands[1], DFmode))"
2981 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2982 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2983 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2985 ;; We have available both v9 double floats and 64-bit
2986 ;; integer registers. No VIS though.
2987 (define_insn "*movdf_insn_sp64_novis"
2988 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2989 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2993 && (register_operand (operands[0], DFmode)
2994 || register_operand (operands[1], DFmode)
2995 || fp_zero_operand (operands[1], DFmode))"
3004 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3005 (set_attr "length" "*,*,*,*,*,*,2")
3006 (set_attr "fptype" "double,*,*,*,*,*,*")])
3008 ;; We have available both v9 double floats and 64-bit
3009 ;; integer registers. And we have VIS.
3010 (define_insn "*movdf_insn_sp64_vis"
3011 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3012 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3016 && (register_operand (operands[0], DFmode)
3017 || register_operand (operands[1], DFmode)
3018 || fp_zero_operand (operands[1], DFmode))"
3028 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3029 (set_attr "length" "*,*,*,*,*,*,*,2")
3030 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3032 (define_insn "*movdf_no_e_insn_sp64"
3033 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3034 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3037 && (register_operand (operands[0], DFmode)
3038 || register_operand (operands[1], DFmode)
3039 || fp_zero_operand (operands[1], DFmode))"
3044 [(set_attr "type" "*,load,store")])
3047 [(set (match_operand:DF 0 "register_operand" "")
3048 (match_operand:DF 1 "const_double_operand" ""))]
3050 && (GET_CODE (operands[0]) == REG
3051 && REGNO (operands[0]) < 32)
3052 && ! fp_zero_operand(operands[1], DFmode)
3053 && reload_completed"
3054 [(clobber (const_int 0))]
3059 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3060 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3061 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3065 #if HOST_BITS_PER_WIDE_INT == 64
3068 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3069 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3070 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3072 emit_insn (gen_movdi (operands[0],
3073 immed_double_const (l[1], l[0], DImode)));
3078 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3081 /* Slick... but this trick loses if this subreg constant part
3082 can be done in one insn. */
3084 && !(SPARC_SETHI32_P (l[0])
3085 || SPARC_SIMM13_P (l[0])))
3087 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3088 gen_highpart (SImode, operands[0])));
3092 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3099 ;; Ok, now the splits to handle all the multi insn and
3100 ;; mis-aligned memory address cases.
3101 ;; In these splits please take note that we must be
3102 ;; careful when V9 but not ARCH64 because the integer
3103 ;; register DFmode cases must be handled.
3105 [(set (match_operand:DF 0 "register_operand" "")
3106 (match_operand:DF 1 "register_operand" ""))]
3109 && ((GET_CODE (operands[0]) == REG
3110 && REGNO (operands[0]) < 32)
3111 || (GET_CODE (operands[0]) == SUBREG
3112 && GET_CODE (SUBREG_REG (operands[0])) == REG
3113 && REGNO (SUBREG_REG (operands[0])) < 32))))
3114 && reload_completed"
3115 [(clobber (const_int 0))]
3117 rtx set_dest = operands[0];
3118 rtx set_src = operands[1];
3122 dest1 = gen_highpart (SFmode, set_dest);
3123 dest2 = gen_lowpart (SFmode, set_dest);
3124 src1 = gen_highpart (SFmode, set_src);
3125 src2 = gen_lowpart (SFmode, set_src);
3127 /* Now emit using the real source and destination we found, swapping
3128 the order if we detect overlap. */
3129 if (reg_overlap_mentioned_p (dest1, src2))
3131 emit_insn (gen_movsf (dest2, src2));
3132 emit_insn (gen_movsf (dest1, src1));
3136 emit_insn (gen_movsf (dest1, src1));
3137 emit_insn (gen_movsf (dest2, src2));
3143 [(set (match_operand:DF 0 "register_operand" "")
3144 (match_operand:DF 1 "memory_operand" ""))]
3147 && (((REGNO (operands[0]) % 2) != 0)
3148 || ! mem_min_alignment (operands[1], 8))
3149 && offsettable_memref_p (operands[1])"
3150 [(clobber (const_int 0))]
3152 rtx word0 = adjust_address (operands[1], SFmode, 0);
3153 rtx word1 = adjust_address (operands[1], SFmode, 4);
3155 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3157 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3159 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3164 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3166 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3173 [(set (match_operand:DF 0 "memory_operand" "")
3174 (match_operand:DF 1 "register_operand" ""))]
3177 && (((REGNO (operands[1]) % 2) != 0)
3178 || ! mem_min_alignment (operands[0], 8))
3179 && offsettable_memref_p (operands[0])"
3180 [(clobber (const_int 0))]
3182 rtx word0 = adjust_address (operands[0], SFmode, 0);
3183 rtx word1 = adjust_address (operands[0], SFmode, 4);
3185 emit_insn (gen_movsf (word0,
3186 gen_highpart (SFmode, operands[1])));
3187 emit_insn (gen_movsf (word1,
3188 gen_lowpart (SFmode, operands[1])));
3193 [(set (match_operand:DF 0 "memory_operand" "")
3194 (match_operand:DF 1 "fp_zero_operand" ""))]
3198 && ! mem_min_alignment (operands[0], 8)))
3199 && offsettable_memref_p (operands[0])"
3200 [(clobber (const_int 0))]
3204 dest1 = adjust_address (operands[0], SFmode, 0);
3205 dest2 = adjust_address (operands[0], SFmode, 4);
3207 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3208 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3213 [(set (match_operand:DF 0 "register_operand" "")
3214 (match_operand:DF 1 "fp_zero_operand" ""))]
3217 && ((GET_CODE (operands[0]) == REG
3218 && REGNO (operands[0]) < 32)
3219 || (GET_CODE (operands[0]) == SUBREG
3220 && GET_CODE (SUBREG_REG (operands[0])) == REG
3221 && REGNO (SUBREG_REG (operands[0])) < 32))"
3222 [(clobber (const_int 0))]
3224 rtx set_dest = operands[0];
3227 dest1 = gen_highpart (SFmode, set_dest);
3228 dest2 = gen_lowpart (SFmode, set_dest);
3229 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3230 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3234 (define_expand "movtf"
3235 [(set (match_operand:TF 0 "general_operand" "")
3236 (match_operand:TF 1 "general_operand" ""))]
3239 /* Force TFmode constants into memory. */
3240 if (GET_CODE (operands[0]) == REG
3241 && CONSTANT_P (operands[1]))
3243 /* emit_group_store will send such bogosity to us when it is
3244 not storing directly into memory. So fix this up to avoid
3245 crashes in output_constant_pool. */
3246 if (operands [1] == const0_rtx)
3247 operands[1] = CONST0_RTX (TFmode);
3249 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3252 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3256 /* Handle MEM cases first, note that only v9 guarantees
3257 full 16-byte alignment for quads. */
3258 if (GET_CODE (operands[0]) == MEM)
3260 if (register_operand (operands[1], TFmode)
3261 || fp_zero_operand (operands[1], TFmode))
3264 if (! reload_in_progress)
3266 operands[0] = validize_mem (operands[0]);
3267 operands[1] = force_reg (TFmode, operands[1]);
3271 /* Fixup PIC cases. */
3274 if (CONSTANT_P (operands[1])
3275 && pic_address_needs_scratch (operands[1]))
3276 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3278 if (symbolic_operand (operands[1], TFmode))
3280 operands[1] = legitimize_pic_address (operands[1],
3282 (reload_in_progress ?
3292 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3293 ;; we must split them all. :-(
3294 (define_insn "*movtf_insn_sp32"
3295 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3296 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3300 && (register_operand (operands[0], TFmode)
3301 || register_operand (operands[1], TFmode)
3302 || fp_zero_operand (operands[1], TFmode))"
3304 [(set_attr "length" "4")])
3306 (define_insn "*movtf_insn_vis_sp32"
3307 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3308 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3312 && (register_operand (operands[0], TFmode)
3313 || register_operand (operands[1], TFmode)
3314 || fp_zero_operand (operands[1], TFmode))"
3316 [(set_attr "length" "4")])
3318 ;; Exactly the same as above, except that all `e' cases are deleted.
3319 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3322 (define_insn "*movtf_no_e_insn_sp32"
3323 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3324 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3327 && (register_operand (operands[0], TFmode)
3328 || register_operand (operands[1], TFmode)
3329 || fp_zero_operand (operands[1], TFmode))"
3331 [(set_attr "length" "4")])
3333 ;; Now handle the float reg cases directly when arch64,
3334 ;; hard_quad, and proper reg number alignment are all true.
3335 (define_insn "*movtf_insn_hq_sp64"
3336 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3337 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3342 && (register_operand (operands[0], TFmode)
3343 || register_operand (operands[1], TFmode)
3344 || fp_zero_operand (operands[1], TFmode))"
3351 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3352 (set_attr "length" "*,*,*,2,2")])
3354 (define_insn "*movtf_insn_hq_vis_sp64"
3355 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3356 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3361 && (register_operand (operands[0], TFmode)
3362 || register_operand (operands[1], TFmode)
3363 || fp_zero_operand (operands[1], TFmode))"
3371 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3372 (set_attr "length" "*,*,*,2,2,2")])
3374 ;; Now we allow the integer register cases even when
3375 ;; only arch64 is true.
3376 (define_insn "*movtf_insn_sp64"
3377 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3378 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3382 && ! TARGET_HARD_QUAD
3383 && (register_operand (operands[0], TFmode)
3384 || register_operand (operands[1], TFmode)
3385 || fp_zero_operand (operands[1], TFmode))"
3387 [(set_attr "length" "2")])
3389 (define_insn "*movtf_insn_vis_sp64"
3390 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3391 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3395 && ! TARGET_HARD_QUAD
3396 && (register_operand (operands[0], TFmode)
3397 || register_operand (operands[1], TFmode)
3398 || fp_zero_operand (operands[1], TFmode))"
3400 [(set_attr "length" "2")])
3402 (define_insn "*movtf_no_e_insn_sp64"
3403 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3404 (match_operand:TF 1 "input_operand" "orG,rG"))]
3407 && (register_operand (operands[0], TFmode)
3408 || register_operand (operands[1], TFmode)
3409 || fp_zero_operand (operands[1], TFmode))"
3411 [(set_attr "length" "2")])
3413 ;; Now all the splits to handle multi-insn TF mode moves.
3415 [(set (match_operand:TF 0 "register_operand" "")
3416 (match_operand:TF 1 "register_operand" ""))]
3420 && ! TARGET_HARD_QUAD)
3421 || ! fp_register_operand (operands[0], TFmode))"
3422 [(clobber (const_int 0))]
3424 rtx set_dest = operands[0];
3425 rtx set_src = operands[1];
3429 dest1 = gen_df_reg (set_dest, 0);
3430 dest2 = gen_df_reg (set_dest, 1);
3431 src1 = gen_df_reg (set_src, 0);
3432 src2 = gen_df_reg (set_src, 1);
3434 /* Now emit using the real source and destination we found, swapping
3435 the order if we detect overlap. */
3436 if (reg_overlap_mentioned_p (dest1, src2))
3438 emit_insn (gen_movdf (dest2, src2));
3439 emit_insn (gen_movdf (dest1, src1));
3443 emit_insn (gen_movdf (dest1, src1));
3444 emit_insn (gen_movdf (dest2, src2));
3450 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3451 (match_operand:TF 1 "fp_zero_operand" ""))]
3453 [(clobber (const_int 0))]
3455 rtx set_dest = operands[0];
3458 switch (GET_CODE (set_dest))
3461 dest1 = gen_df_reg (set_dest, 0);
3462 dest2 = gen_df_reg (set_dest, 1);
3465 dest1 = adjust_address (set_dest, DFmode, 0);
3466 dest2 = adjust_address (set_dest, DFmode, 8);
3472 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3473 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3478 [(set (match_operand:TF 0 "register_operand" "")
3479 (match_operand:TF 1 "memory_operand" ""))]
3481 && offsettable_memref_p (operands[1])
3483 || ! TARGET_HARD_QUAD
3484 || ! fp_register_operand (operands[0], TFmode)))"
3485 [(clobber (const_int 0))]
3487 rtx word0 = adjust_address (operands[1], DFmode, 0);
3488 rtx word1 = adjust_address (operands[1], DFmode, 8);
3489 rtx set_dest, dest1, dest2;
3491 set_dest = operands[0];
3493 dest1 = gen_df_reg (set_dest, 0);
3494 dest2 = gen_df_reg (set_dest, 1);
3496 /* Now output, ordering such that we don't clobber any registers
3497 mentioned in the address. */
3498 if (reg_overlap_mentioned_p (dest1, word1))
3501 emit_insn (gen_movdf (dest2, word1));
3502 emit_insn (gen_movdf (dest1, word0));
3506 emit_insn (gen_movdf (dest1, word0));
3507 emit_insn (gen_movdf (dest2, word1));
3513 [(set (match_operand:TF 0 "memory_operand" "")
3514 (match_operand:TF 1 "register_operand" ""))]
3516 && offsettable_memref_p (operands[0])
3518 || ! TARGET_HARD_QUAD
3519 || ! fp_register_operand (operands[1], TFmode)))"
3520 [(clobber (const_int 0))]
3522 rtx set_src = operands[1];
3524 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3525 gen_df_reg (set_src, 0)));
3526 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3527 gen_df_reg (set_src, 1)));
3531 ;; SPARC V9 conditional move instructions.
3533 ;; We can handle larger constants here for some flavors, but for now we keep
3534 ;; it simple and only allow those constants supported by all flavors.
3535 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3536 ;; 3 contains the constant if one is present, but we handle either for
3537 ;; generality (sparc.c puts a constant in operand 2).
3539 (define_expand "movqicc"
3540 [(set (match_operand:QI 0 "register_operand" "")
3541 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3542 (match_operand:QI 2 "arith10_operand" "")
3543 (match_operand:QI 3 "arith10_operand" "")))]
3546 enum rtx_code code = GET_CODE (operands[1]);
3548 if (GET_MODE (sparc_compare_op0) == DImode
3552 if (sparc_compare_op1 == const0_rtx
3553 && GET_CODE (sparc_compare_op0) == REG
3554 && GET_MODE (sparc_compare_op0) == DImode
3555 && v9_regcmp_p (code))
3557 operands[1] = gen_rtx_fmt_ee (code, DImode,
3558 sparc_compare_op0, sparc_compare_op1);
3562 rtx cc_reg = gen_compare_reg (code,
3563 sparc_compare_op0, sparc_compare_op1);
3564 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3568 (define_expand "movhicc"
3569 [(set (match_operand:HI 0 "register_operand" "")
3570 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3571 (match_operand:HI 2 "arith10_operand" "")
3572 (match_operand:HI 3 "arith10_operand" "")))]
3575 enum rtx_code code = GET_CODE (operands[1]);
3577 if (GET_MODE (sparc_compare_op0) == DImode
3581 if (sparc_compare_op1 == const0_rtx
3582 && GET_CODE (sparc_compare_op0) == REG
3583 && GET_MODE (sparc_compare_op0) == DImode
3584 && v9_regcmp_p (code))
3586 operands[1] = gen_rtx_fmt_ee (code, DImode,
3587 sparc_compare_op0, sparc_compare_op1);
3591 rtx cc_reg = gen_compare_reg (code,
3592 sparc_compare_op0, sparc_compare_op1);
3593 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3597 (define_expand "movsicc"
3598 [(set (match_operand:SI 0 "register_operand" "")
3599 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3600 (match_operand:SI 2 "arith10_operand" "")
3601 (match_operand:SI 3 "arith10_operand" "")))]
3604 enum rtx_code code = GET_CODE (operands[1]);
3605 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3607 if (sparc_compare_op1 == const0_rtx
3608 && GET_CODE (sparc_compare_op0) == REG
3609 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3611 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3612 sparc_compare_op0, sparc_compare_op1);
3616 rtx cc_reg = gen_compare_reg (code,
3617 sparc_compare_op0, sparc_compare_op1);
3618 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3619 cc_reg, const0_rtx);
3623 (define_expand "movdicc"
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3626 (match_operand:DI 2 "arith10_double_operand" "")
3627 (match_operand:DI 3 "arith10_double_operand" "")))]
3630 enum rtx_code code = GET_CODE (operands[1]);
3632 if (sparc_compare_op1 == const0_rtx
3633 && GET_CODE (sparc_compare_op0) == REG
3634 && GET_MODE (sparc_compare_op0) == DImode
3635 && v9_regcmp_p (code))
3637 operands[1] = gen_rtx_fmt_ee (code, DImode,
3638 sparc_compare_op0, sparc_compare_op1);
3642 rtx cc_reg = gen_compare_reg (code,
3643 sparc_compare_op0, sparc_compare_op1);
3644 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3645 cc_reg, const0_rtx);
3649 (define_expand "movsfcc"
3650 [(set (match_operand:SF 0 "register_operand" "")
3651 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3652 (match_operand:SF 2 "register_operand" "")
3653 (match_operand:SF 3 "register_operand" "")))]
3654 "TARGET_V9 && TARGET_FPU"
3656 enum rtx_code code = GET_CODE (operands[1]);
3658 if (GET_MODE (sparc_compare_op0) == DImode
3662 if (sparc_compare_op1 == const0_rtx
3663 && GET_CODE (sparc_compare_op0) == REG
3664 && GET_MODE (sparc_compare_op0) == DImode
3665 && v9_regcmp_p (code))
3667 operands[1] = gen_rtx_fmt_ee (code, DImode,
3668 sparc_compare_op0, sparc_compare_op1);
3672 rtx cc_reg = gen_compare_reg (code,
3673 sparc_compare_op0, sparc_compare_op1);
3674 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3678 (define_expand "movdfcc"
3679 [(set (match_operand:DF 0 "register_operand" "")
3680 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3681 (match_operand:DF 2 "register_operand" "")
3682 (match_operand:DF 3 "register_operand" "")))]
3683 "TARGET_V9 && TARGET_FPU"
3685 enum rtx_code code = GET_CODE (operands[1]);
3687 if (GET_MODE (sparc_compare_op0) == DImode
3691 if (sparc_compare_op1 == const0_rtx
3692 && GET_CODE (sparc_compare_op0) == REG
3693 && GET_MODE (sparc_compare_op0) == DImode
3694 && v9_regcmp_p (code))
3696 operands[1] = gen_rtx_fmt_ee (code, DImode,
3697 sparc_compare_op0, sparc_compare_op1);
3701 rtx cc_reg = gen_compare_reg (code,
3702 sparc_compare_op0, sparc_compare_op1);
3703 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3707 (define_expand "movtfcc"
3708 [(set (match_operand:TF 0 "register_operand" "")
3709 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3710 (match_operand:TF 2 "register_operand" "")
3711 (match_operand:TF 3 "register_operand" "")))]
3712 "TARGET_V9 && TARGET_FPU"
3714 enum rtx_code code = GET_CODE (operands[1]);
3716 if (GET_MODE (sparc_compare_op0) == DImode
3720 if (sparc_compare_op1 == const0_rtx
3721 && GET_CODE (sparc_compare_op0) == REG
3722 && GET_MODE (sparc_compare_op0) == DImode
3723 && v9_regcmp_p (code))
3725 operands[1] = gen_rtx_fmt_ee (code, DImode,
3726 sparc_compare_op0, sparc_compare_op1);
3730 rtx cc_reg = gen_compare_reg (code,
3731 sparc_compare_op0, sparc_compare_op1);
3732 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3736 ;; Conditional move define_insns.
3738 (define_insn "*movqi_cc_sp64"
3739 [(set (match_operand:QI 0 "register_operand" "=r,r")
3740 (if_then_else:QI (match_operator 1 "comparison_operator"
3741 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3743 (match_operand:QI 3 "arith11_operand" "rL,0")
3744 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3748 mov%c1\t%x2, %4, %0"
3749 [(set_attr "type" "cmove")])
3751 (define_insn "*movhi_cc_sp64"
3752 [(set (match_operand:HI 0 "register_operand" "=r,r")
3753 (if_then_else:HI (match_operator 1 "comparison_operator"
3754 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3756 (match_operand:HI 3 "arith11_operand" "rL,0")
3757 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3761 mov%c1\t%x2, %4, %0"
3762 [(set_attr "type" "cmove")])
3764 (define_insn "*movsi_cc_sp64"
3765 [(set (match_operand:SI 0 "register_operand" "=r,r")
3766 (if_then_else:SI (match_operator 1 "comparison_operator"
3767 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3769 (match_operand:SI 3 "arith11_operand" "rL,0")
3770 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3774 mov%c1\t%x2, %4, %0"
3775 [(set_attr "type" "cmove")])
3777 ;; ??? The constraints of operands 3,4 need work.
3778 (define_insn "*movdi_cc_sp64"
3779 [(set (match_operand:DI 0 "register_operand" "=r,r")
3780 (if_then_else:DI (match_operator 1 "comparison_operator"
3781 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3783 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3784 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3788 mov%c1\t%x2, %4, %0"
3789 [(set_attr "type" "cmove")])
3791 (define_insn "*movdi_cc_sp64_trunc"
3792 [(set (match_operand:SI 0 "register_operand" "=r,r")
3793 (if_then_else:SI (match_operator 1 "comparison_operator"
3794 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3796 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3797 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3801 mov%c1\t%x2, %4, %0"
3802 [(set_attr "type" "cmove")])
3804 (define_insn "*movsf_cc_sp64"
3805 [(set (match_operand:SF 0 "register_operand" "=f,f")
3806 (if_then_else:SF (match_operator 1 "comparison_operator"
3807 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809 (match_operand:SF 3 "register_operand" "f,0")
3810 (match_operand:SF 4 "register_operand" "0,f")))]
3811 "TARGET_V9 && TARGET_FPU"
3813 fmovs%C1\t%x2, %3, %0
3814 fmovs%c1\t%x2, %4, %0"
3815 [(set_attr "type" "fpcmove")])
3817 (define_insn "movdf_cc_sp64"
3818 [(set (match_operand:DF 0 "register_operand" "=e,e")
3819 (if_then_else:DF (match_operator 1 "comparison_operator"
3820 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3822 (match_operand:DF 3 "register_operand" "e,0")
3823 (match_operand:DF 4 "register_operand" "0,e")))]
3824 "TARGET_V9 && TARGET_FPU"
3826 fmovd%C1\t%x2, %3, %0
3827 fmovd%c1\t%x2, %4, %0"
3828 [(set_attr "type" "fpcmove")
3829 (set_attr "fptype" "double")])
3831 (define_insn "*movtf_cc_hq_sp64"
3832 [(set (match_operand:TF 0 "register_operand" "=e,e")
3833 (if_then_else:TF (match_operator 1 "comparison_operator"
3834 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3836 (match_operand:TF 3 "register_operand" "e,0")
3837 (match_operand:TF 4 "register_operand" "0,e")))]
3838 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3840 fmovq%C1\t%x2, %3, %0
3841 fmovq%c1\t%x2, %4, %0"
3842 [(set_attr "type" "fpcmove")])
3844 (define_insn_and_split "*movtf_cc_sp64"
3845 [(set (match_operand:TF 0 "register_operand" "=e,e")
3846 (if_then_else:TF (match_operator 1 "comparison_operator"
3847 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3849 (match_operand:TF 3 "register_operand" "e,0")
3850 (match_operand:TF 4 "register_operand" "0,e")))]
3851 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3853 "&& reload_completed"
3854 [(clobber (const_int 0))]
3856 rtx set_dest = operands[0];
3857 rtx set_srca = operands[3];
3858 rtx set_srcb = operands[4];
3859 int third = rtx_equal_p (set_dest, set_srca);
3861 rtx srca1, srca2, srcb1, srcb2;
3863 dest1 = gen_df_reg (set_dest, 0);
3864 dest2 = gen_df_reg (set_dest, 1);
3865 srca1 = gen_df_reg (set_srca, 0);
3866 srca2 = gen_df_reg (set_srca, 1);
3867 srcb1 = gen_df_reg (set_srcb, 0);
3868 srcb2 = gen_df_reg (set_srcb, 1);
3870 /* Now emit using the real source and destination we found, swapping
3871 the order if we detect overlap. */
3872 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3873 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3875 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3876 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3880 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3881 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3885 [(set_attr "length" "2")])
3887 (define_insn "*movqi_cc_reg_sp64"
3888 [(set (match_operand:QI 0 "register_operand" "=r,r")
3889 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3890 [(match_operand:DI 2 "register_operand" "r,r")
3892 (match_operand:QI 3 "arith10_operand" "rM,0")
3893 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3896 movr%D1\t%2, %r3, %0
3897 movr%d1\t%2, %r4, %0"
3898 [(set_attr "type" "cmove")])
3900 (define_insn "*movhi_cc_reg_sp64"
3901 [(set (match_operand:HI 0 "register_operand" "=r,r")
3902 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3903 [(match_operand:DI 2 "register_operand" "r,r")
3905 (match_operand:HI 3 "arith10_operand" "rM,0")
3906 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3909 movr%D1\t%2, %r3, %0
3910 movr%d1\t%2, %r4, %0"
3911 [(set_attr "type" "cmove")])
3913 (define_insn "*movsi_cc_reg_sp64"
3914 [(set (match_operand:SI 0 "register_operand" "=r,r")
3915 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3916 [(match_operand:DI 2 "register_operand" "r,r")
3918 (match_operand:SI 3 "arith10_operand" "rM,0")
3919 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3922 movr%D1\t%2, %r3, %0
3923 movr%d1\t%2, %r4, %0"
3924 [(set_attr "type" "cmove")])
3926 ;; ??? The constraints of operands 3,4 need work.
3927 (define_insn "*movdi_cc_reg_sp64"
3928 [(set (match_operand:DI 0 "register_operand" "=r,r")
3929 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3930 [(match_operand:DI 2 "register_operand" "r,r")
3932 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3933 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3936 movr%D1\t%2, %r3, %0
3937 movr%d1\t%2, %r4, %0"
3938 [(set_attr "type" "cmove")])
3940 (define_insn "*movdi_cc_reg_sp64_trunc"
3941 [(set (match_operand:SI 0 "register_operand" "=r,r")
3942 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3943 [(match_operand:DI 2 "register_operand" "r,r")
3945 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3946 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3949 movr%D1\t%2, %r3, %0
3950 movr%d1\t%2, %r4, %0"
3951 [(set_attr "type" "cmove")])
3953 (define_insn "*movsf_cc_reg_sp64"
3954 [(set (match_operand:SF 0 "register_operand" "=f,f")
3955 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3956 [(match_operand:DI 2 "register_operand" "r,r")
3958 (match_operand:SF 3 "register_operand" "f,0")
3959 (match_operand:SF 4 "register_operand" "0,f")))]
3960 "TARGET_ARCH64 && TARGET_FPU"
3962 fmovrs%D1\t%2, %3, %0
3963 fmovrs%d1\t%2, %4, %0"
3964 [(set_attr "type" "fpcrmove")])
3966 (define_insn "movdf_cc_reg_sp64"
3967 [(set (match_operand:DF 0 "register_operand" "=e,e")
3968 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3969 [(match_operand:DI 2 "register_operand" "r,r")
3971 (match_operand:DF 3 "register_operand" "e,0")
3972 (match_operand:DF 4 "register_operand" "0,e")))]
3973 "TARGET_ARCH64 && TARGET_FPU"
3975 fmovrd%D1\t%2, %3, %0
3976 fmovrd%d1\t%2, %4, %0"
3977 [(set_attr "type" "fpcrmove")
3978 (set_attr "fptype" "double")])
3980 (define_insn "*movtf_cc_reg_hq_sp64"
3981 [(set (match_operand:TF 0 "register_operand" "=e,e")
3982 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3983 [(match_operand:DI 2 "register_operand" "r,r")
3985 (match_operand:TF 3 "register_operand" "e,0")
3986 (match_operand:TF 4 "register_operand" "0,e")))]
3987 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3989 fmovrq%D1\t%2, %3, %0
3990 fmovrq%d1\t%2, %4, %0"
3991 [(set_attr "type" "fpcrmove")])
3993 (define_insn_and_split "*movtf_cc_reg_sp64"
3994 [(set (match_operand:TF 0 "register_operand" "=e,e")
3995 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3996 [(match_operand:DI 2 "register_operand" "r,r")
3998 (match_operand:TF 3 "register_operand" "e,0")
3999 (match_operand:TF 4 "register_operand" "0,e")))]
4000 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4002 "&& reload_completed"
4003 [(clobber (const_int 0))]
4005 rtx set_dest = operands[0];
4006 rtx set_srca = operands[3];
4007 rtx set_srcb = operands[4];
4008 int third = rtx_equal_p (set_dest, set_srca);
4010 rtx srca1, srca2, srcb1, srcb2;
4012 dest1 = gen_df_reg (set_dest, 0);
4013 dest2 = gen_df_reg (set_dest, 1);
4014 srca1 = gen_df_reg (set_srca, 0);
4015 srca2 = gen_df_reg (set_srca, 1);
4016 srcb1 = gen_df_reg (set_srcb, 0);
4017 srcb2 = gen_df_reg (set_srcb, 1);
4019 /* Now emit using the real source and destination we found, swapping
4020 the order if we detect overlap. */
4021 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4022 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4024 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4025 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4029 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4030 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4034 [(set_attr "length" "2")])
4037 ;;- zero extension instructions
4039 ;; These patterns originally accepted general_operands, however, slightly
4040 ;; better code is generated by only accepting register_operands, and then
4041 ;; letting combine generate the ldu[hb] insns.
4043 (define_expand "zero_extendhisi2"
4044 [(set (match_operand:SI 0 "register_operand" "")
4045 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4048 rtx temp = gen_reg_rtx (SImode);
4049 rtx shift_16 = GEN_INT (16);
4050 int op1_subbyte = 0;
4052 if (GET_CODE (operand1) == SUBREG)
4054 op1_subbyte = SUBREG_BYTE (operand1);
4055 op1_subbyte /= GET_MODE_SIZE (SImode);
4056 op1_subbyte *= GET_MODE_SIZE (SImode);
4057 operand1 = XEXP (operand1, 0);
4060 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4062 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4066 (define_insn "*zero_extendhisi2_insn"
4067 [(set (match_operand:SI 0 "register_operand" "=r")
4068 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4071 [(set_attr "type" "load")
4072 (set_attr "us3load_type" "3cycle")])
4074 (define_expand "zero_extendqihi2"
4075 [(set (match_operand:HI 0 "register_operand" "")
4076 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4080 (define_insn "*zero_extendqihi2_insn"
4081 [(set (match_operand:HI 0 "register_operand" "=r,r")
4082 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4083 "GET_CODE (operands[1]) != CONST_INT"
4087 [(set_attr "type" "*,load")
4088 (set_attr "us3load_type" "*,3cycle")])
4090 (define_expand "zero_extendqisi2"
4091 [(set (match_operand:SI 0 "register_operand" "")
4092 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4096 (define_insn "*zero_extendqisi2_insn"
4097 [(set (match_operand:SI 0 "register_operand" "=r,r")
4098 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4099 "GET_CODE (operands[1]) != CONST_INT"
4103 [(set_attr "type" "*,load")
4104 (set_attr "us3load_type" "*,3cycle")])
4106 (define_expand "zero_extendqidi2"
4107 [(set (match_operand:DI 0 "register_operand" "")
4108 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4112 (define_insn "*zero_extendqidi2_insn"
4113 [(set (match_operand:DI 0 "register_operand" "=r,r")
4114 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4115 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4119 [(set_attr "type" "*,load")
4120 (set_attr "us3load_type" "*,3cycle")])
4122 (define_expand "zero_extendhidi2"
4123 [(set (match_operand:DI 0 "register_operand" "")
4124 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4127 rtx temp = gen_reg_rtx (DImode);
4128 rtx shift_48 = GEN_INT (48);
4129 int op1_subbyte = 0;
4131 if (GET_CODE (operand1) == SUBREG)
4133 op1_subbyte = SUBREG_BYTE (operand1);
4134 op1_subbyte /= GET_MODE_SIZE (DImode);
4135 op1_subbyte *= GET_MODE_SIZE (DImode);
4136 operand1 = XEXP (operand1, 0);
4139 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4141 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4145 (define_insn "*zero_extendhidi2_insn"
4146 [(set (match_operand:DI 0 "register_operand" "=r")
4147 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4150 [(set_attr "type" "load")
4151 (set_attr "us3load_type" "3cycle")])
4154 ;; ??? Write truncdisi pattern using sra?
4156 (define_expand "zero_extendsidi2"
4157 [(set (match_operand:DI 0 "register_operand" "")
4158 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4162 (define_insn "*zero_extendsidi2_insn_sp64"
4163 [(set (match_operand:DI 0 "register_operand" "=r,r")
4164 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4165 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4169 [(set_attr "type" "shift,load")])
4171 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4172 [(set (match_operand:DI 0 "register_operand" "=r")
4173 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4176 "&& reload_completed"
4177 [(set (match_dup 2) (match_dup 3))
4178 (set (match_dup 4) (match_dup 5))]
4182 dest1 = gen_highpart (SImode, operands[0]);
4183 dest2 = gen_lowpart (SImode, operands[0]);
4185 /* Swap the order in case of overlap. */
4186 if (REGNO (dest1) == REGNO (operands[1]))
4188 operands[2] = dest2;
4189 operands[3] = operands[1];
4190 operands[4] = dest1;
4191 operands[5] = const0_rtx;
4195 operands[2] = dest1;
4196 operands[3] = const0_rtx;
4197 operands[4] = dest2;
4198 operands[5] = operands[1];
4201 [(set_attr "length" "2")])
4203 ;; Simplify comparisons of extended values.
4205 (define_insn "*cmp_zero_extendqisi2"
4207 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4210 "andcc\t%0, 0xff, %%g0"
4211 [(set_attr "type" "compare")])
4213 (define_insn "*cmp_zero_qi"
4215 (compare:CC (match_operand:QI 0 "register_operand" "r")
4218 "andcc\t%0, 0xff, %%g0"
4219 [(set_attr "type" "compare")])
4221 (define_insn "*cmp_zero_extendqisi2_set"
4223 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4225 (set (match_operand:SI 0 "register_operand" "=r")
4226 (zero_extend:SI (match_dup 1)))]
4228 "andcc\t%1, 0xff, %0"
4229 [(set_attr "type" "compare")])
4231 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4233 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4236 (set (match_operand:SI 0 "register_operand" "=r")
4237 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4239 "andcc\t%1, 0xff, %0"
4240 [(set_attr "type" "compare")])
4242 (define_insn "*cmp_zero_extendqidi2"
4244 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4247 "andcc\t%0, 0xff, %%g0"
4248 [(set_attr "type" "compare")])
4250 (define_insn "*cmp_zero_qi_sp64"
4252 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4255 "andcc\t%0, 0xff, %%g0"
4256 [(set_attr "type" "compare")])
4258 (define_insn "*cmp_zero_extendqidi2_set"
4260 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4262 (set (match_operand:DI 0 "register_operand" "=r")
4263 (zero_extend:DI (match_dup 1)))]
4265 "andcc\t%1, 0xff, %0"
4266 [(set_attr "type" "compare")])
4268 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4270 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4273 (set (match_operand:DI 0 "register_operand" "=r")
4274 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4276 "andcc\t%1, 0xff, %0"
4277 [(set_attr "type" "compare")])
4279 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4281 (define_insn "*cmp_siqi_trunc"
4283 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4286 "andcc\t%0, 0xff, %%g0"
4287 [(set_attr "type" "compare")])
4289 (define_insn "*cmp_siqi_trunc_set"
4291 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4293 (set (match_operand:QI 0 "register_operand" "=r")
4294 (subreg:QI (match_dup 1) 3))]
4296 "andcc\t%1, 0xff, %0"
4297 [(set_attr "type" "compare")])
4299 (define_insn "*cmp_diqi_trunc"
4301 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4304 "andcc\t%0, 0xff, %%g0"
4305 [(set_attr "type" "compare")])
4307 (define_insn "*cmp_diqi_trunc_set"
4309 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4311 (set (match_operand:QI 0 "register_operand" "=r")
4312 (subreg:QI (match_dup 1) 7))]
4314 "andcc\t%1, 0xff, %0"
4315 [(set_attr "type" "compare")])
4317 ;;- sign extension instructions
4319 ;; These patterns originally accepted general_operands, however, slightly
4320 ;; better code is generated by only accepting register_operands, and then
4321 ;; letting combine generate the lds[hb] insns.
4323 (define_expand "extendhisi2"
4324 [(set (match_operand:SI 0 "register_operand" "")
4325 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4328 rtx temp = gen_reg_rtx (SImode);
4329 rtx shift_16 = GEN_INT (16);
4330 int op1_subbyte = 0;
4332 if (GET_CODE (operand1) == SUBREG)
4334 op1_subbyte = SUBREG_BYTE (operand1);
4335 op1_subbyte /= GET_MODE_SIZE (SImode);
4336 op1_subbyte *= GET_MODE_SIZE (SImode);
4337 operand1 = XEXP (operand1, 0);
4340 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4342 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4346 (define_insn "*sign_extendhisi2_insn"
4347 [(set (match_operand:SI 0 "register_operand" "=r")
4348 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4351 [(set_attr "type" "sload")
4352 (set_attr "us3load_type" "3cycle")])
4354 (define_expand "extendqihi2"
4355 [(set (match_operand:HI 0 "register_operand" "")
4356 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4359 rtx temp = gen_reg_rtx (SImode);
4360 rtx shift_24 = GEN_INT (24);
4361 int op1_subbyte = 0;
4362 int op0_subbyte = 0;
4364 if (GET_CODE (operand1) == SUBREG)
4366 op1_subbyte = SUBREG_BYTE (operand1);
4367 op1_subbyte /= GET_MODE_SIZE (SImode);
4368 op1_subbyte *= GET_MODE_SIZE (SImode);
4369 operand1 = XEXP (operand1, 0);
4371 if (GET_CODE (operand0) == SUBREG)
4373 op0_subbyte = SUBREG_BYTE (operand0);
4374 op0_subbyte /= GET_MODE_SIZE (SImode);
4375 op0_subbyte *= GET_MODE_SIZE (SImode);
4376 operand0 = XEXP (operand0, 0);
4378 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4380 if (GET_MODE (operand0) != SImode)
4381 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4382 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4386 (define_insn "*sign_extendqihi2_insn"
4387 [(set (match_operand:HI 0 "register_operand" "=r")
4388 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4391 [(set_attr "type" "sload")
4392 (set_attr "us3load_type" "3cycle")])
4394 (define_expand "extendqisi2"
4395 [(set (match_operand:SI 0 "register_operand" "")
4396 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4399 rtx temp = gen_reg_rtx (SImode);
4400 rtx shift_24 = GEN_INT (24);
4401 int op1_subbyte = 0;
4403 if (GET_CODE (operand1) == SUBREG)
4405 op1_subbyte = SUBREG_BYTE (operand1);
4406 op1_subbyte /= GET_MODE_SIZE (SImode);
4407 op1_subbyte *= GET_MODE_SIZE (SImode);
4408 operand1 = XEXP (operand1, 0);
4411 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4413 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4417 (define_insn "*sign_extendqisi2_insn"
4418 [(set (match_operand:SI 0 "register_operand" "=r")
4419 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4422 [(set_attr "type" "sload")
4423 (set_attr "us3load_type" "3cycle")])
4425 (define_expand "extendqidi2"
4426 [(set (match_operand:DI 0 "register_operand" "")
4427 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4430 rtx temp = gen_reg_rtx (DImode);
4431 rtx shift_56 = GEN_INT (56);
4432 int op1_subbyte = 0;
4434 if (GET_CODE (operand1) == SUBREG)
4436 op1_subbyte = SUBREG_BYTE (operand1);
4437 op1_subbyte /= GET_MODE_SIZE (DImode);
4438 op1_subbyte *= GET_MODE_SIZE (DImode);
4439 operand1 = XEXP (operand1, 0);
4442 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4444 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4448 (define_insn "*sign_extendqidi2_insn"
4449 [(set (match_operand:DI 0 "register_operand" "=r")
4450 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4453 [(set_attr "type" "sload")
4454 (set_attr "us3load_type" "3cycle")])
4456 (define_expand "extendhidi2"
4457 [(set (match_operand:DI 0 "register_operand" "")
4458 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4461 rtx temp = gen_reg_rtx (DImode);
4462 rtx shift_48 = GEN_INT (48);
4463 int op1_subbyte = 0;
4465 if (GET_CODE (operand1) == SUBREG)
4467 op1_subbyte = SUBREG_BYTE (operand1);
4468 op1_subbyte /= GET_MODE_SIZE (DImode);
4469 op1_subbyte *= GET_MODE_SIZE (DImode);
4470 operand1 = XEXP (operand1, 0);
4473 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4475 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4479 (define_insn "*sign_extendhidi2_insn"
4480 [(set (match_operand:DI 0 "register_operand" "=r")
4481 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4484 [(set_attr "type" "sload")
4485 (set_attr "us3load_type" "3cycle")])
4487 (define_expand "extendsidi2"
4488 [(set (match_operand:DI 0 "register_operand" "")
4489 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4493 (define_insn "*sign_extendsidi2_insn"
4494 [(set (match_operand:DI 0 "register_operand" "=r,r")
4495 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4500 [(set_attr "type" "shift,sload")
4501 (set_attr "us3load_type" "*,3cycle")])
4503 ;; Special pattern for optimizing bit-field compares. This is needed
4504 ;; because combine uses this as a canonical form.
4506 (define_insn "*cmp_zero_extract"
4509 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4510 (match_operand:SI 1 "small_int_or_double" "n")
4511 (match_operand:SI 2 "small_int_or_double" "n"))
4513 "(GET_CODE (operands[2]) == CONST_INT
4514 && INTVAL (operands[2]) > 19)
4515 || (GET_CODE (operands[2]) == CONST_DOUBLE
4516 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4518 int len = (GET_CODE (operands[1]) == CONST_INT
4519 ? INTVAL (operands[1])
4520 : CONST_DOUBLE_LOW (operands[1]));
4522 (GET_CODE (operands[2]) == CONST_INT
4523 ? INTVAL (operands[2])
4524 : CONST_DOUBLE_LOW (operands[2])) - len;
4525 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4527 operands[1] = GEN_INT (mask);
4528 return "andcc\t%0, %1, %%g0";
4530 [(set_attr "type" "compare")])
4532 (define_insn "*cmp_zero_extract_sp64"
4535 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4536 (match_operand:SI 1 "small_int_or_double" "n")
4537 (match_operand:SI 2 "small_int_or_double" "n"))
4540 && ((GET_CODE (operands[2]) == CONST_INT
4541 && INTVAL (operands[2]) > 51)
4542 || (GET_CODE (operands[2]) == CONST_DOUBLE
4543 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4545 int len = (GET_CODE (operands[1]) == CONST_INT
4546 ? INTVAL (operands[1])
4547 : CONST_DOUBLE_LOW (operands[1]));
4549 (GET_CODE (operands[2]) == CONST_INT
4550 ? INTVAL (operands[2])
4551 : CONST_DOUBLE_LOW (operands[2])) - len;
4552 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4554 operands[1] = GEN_INT (mask);
4555 return "andcc\t%0, %1, %%g0";
4557 [(set_attr "type" "compare")])
4559 ;; Conversions between float, double and long double.
4561 (define_insn "extendsfdf2"
4562 [(set (match_operand:DF 0 "register_operand" "=e")
4564 (match_operand:SF 1 "register_operand" "f")))]
4567 [(set_attr "type" "fp")
4568 (set_attr "fptype" "double")])
4570 (define_expand "extendsftf2"
4571 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4573 (match_operand:SF 1 "register_operand" "")))]
4574 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4575 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4577 (define_insn "*extendsftf2_hq"
4578 [(set (match_operand:TF 0 "register_operand" "=e")
4580 (match_operand:SF 1 "register_operand" "f")))]
4581 "TARGET_FPU && TARGET_HARD_QUAD"
4583 [(set_attr "type" "fp")])
4585 (define_expand "extenddftf2"
4586 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4588 (match_operand:DF 1 "register_operand" "")))]
4589 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4590 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4592 (define_insn "*extenddftf2_hq"
4593 [(set (match_operand:TF 0 "register_operand" "=e")
4595 (match_operand:DF 1 "register_operand" "e")))]
4596 "TARGET_FPU && TARGET_HARD_QUAD"
4598 [(set_attr "type" "fp")])
4600 (define_insn "truncdfsf2"
4601 [(set (match_operand:SF 0 "register_operand" "=f")
4603 (match_operand:DF 1 "register_operand" "e")))]
4606 [(set_attr "type" "fp")
4607 (set_attr "fptype" "double")])
4609 (define_expand "trunctfsf2"
4610 [(set (match_operand:SF 0 "register_operand" "")
4612 (match_operand:TF 1 "general_operand" "")))]
4613 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4614 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4616 (define_insn "*trunctfsf2_hq"
4617 [(set (match_operand:SF 0 "register_operand" "=f")
4619 (match_operand:TF 1 "register_operand" "e")))]
4620 "TARGET_FPU && TARGET_HARD_QUAD"
4622 [(set_attr "type" "fp")])
4624 (define_expand "trunctfdf2"
4625 [(set (match_operand:DF 0 "register_operand" "")
4627 (match_operand:TF 1 "general_operand" "")))]
4628 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4629 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4631 (define_insn "*trunctfdf2_hq"
4632 [(set (match_operand:DF 0 "register_operand" "=e")
4634 (match_operand:TF 1 "register_operand" "e")))]
4635 "TARGET_FPU && TARGET_HARD_QUAD"
4637 [(set_attr "type" "fp")])
4639 ;; Conversion between fixed point and floating point.
4641 (define_insn "floatsisf2"
4642 [(set (match_operand:SF 0 "register_operand" "=f")
4643 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4646 [(set_attr "type" "fp")
4647 (set_attr "fptype" "double")])
4649 (define_insn "floatsidf2"
4650 [(set (match_operand:DF 0 "register_operand" "=e")
4651 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4654 [(set_attr "type" "fp")
4655 (set_attr "fptype" "double")])
4657 (define_expand "floatsitf2"
4658 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4659 (float:TF (match_operand:SI 1 "register_operand" "")))]
4660 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4661 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4663 (define_insn "*floatsitf2_hq"
4664 [(set (match_operand:TF 0 "register_operand" "=e")
4665 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4666 "TARGET_FPU && TARGET_HARD_QUAD"
4668 [(set_attr "type" "fp")])
4670 (define_expand "floatunssitf2"
4671 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4672 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4673 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4674 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4676 ;; Now the same for 64 bit sources.
4678 (define_insn "floatdisf2"
4679 [(set (match_operand:SF 0 "register_operand" "=f")
4680 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4681 "TARGET_V9 && TARGET_FPU"
4683 [(set_attr "type" "fp")
4684 (set_attr "fptype" "double")])
4686 (define_expand "floatunsdisf2"
4687 [(use (match_operand:SF 0 "register_operand" ""))
4688 (use (match_operand:DI 1 "general_operand" ""))]
4689 "TARGET_ARCH64 && TARGET_FPU"
4690 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4692 (define_insn "floatdidf2"
4693 [(set (match_operand:DF 0 "register_operand" "=e")
4694 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4695 "TARGET_V9 && TARGET_FPU"
4697 [(set_attr "type" "fp")
4698 (set_attr "fptype" "double")])
4700 (define_expand "floatunsdidf2"
4701 [(use (match_operand:DF 0 "register_operand" ""))
4702 (use (match_operand:DI 1 "general_operand" ""))]
4703 "TARGET_ARCH64 && TARGET_FPU"
4704 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4706 (define_expand "floatditf2"
4707 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4708 (float:TF (match_operand:DI 1 "register_operand" "")))]
4709 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4710 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4712 (define_insn "*floatditf2_hq"
4713 [(set (match_operand:TF 0 "register_operand" "=e")
4714 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4715 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4717 [(set_attr "type" "fp")])
4719 (define_expand "floatunsditf2"
4720 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4721 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4722 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4723 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4725 ;; Convert a float to an actual integer.
4726 ;; Truncation is performed as part of the conversion.
4728 (define_insn "fix_truncsfsi2"
4729 [(set (match_operand:SI 0 "register_operand" "=f")
4730 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4733 [(set_attr "type" "fp")
4734 (set_attr "fptype" "double")])
4736 (define_insn "fix_truncdfsi2"
4737 [(set (match_operand:SI 0 "register_operand" "=f")
4738 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4741 [(set_attr "type" "fp")
4742 (set_attr "fptype" "double")])
4744 (define_expand "fix_trunctfsi2"
4745 [(set (match_operand:SI 0 "register_operand" "")
4746 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4747 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4748 "emit_tfmode_cvt (FIX, operands); DONE;")
4750 (define_insn "*fix_trunctfsi2_hq"
4751 [(set (match_operand:SI 0 "register_operand" "=f")
4752 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4753 "TARGET_FPU && TARGET_HARD_QUAD"
4755 [(set_attr "type" "fp")])
4757 (define_expand "fixuns_trunctfsi2"
4758 [(set (match_operand:SI 0 "register_operand" "")
4759 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4760 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4761 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4763 ;; Now the same, for V9 targets
4765 (define_insn "fix_truncsfdi2"
4766 [(set (match_operand:DI 0 "register_operand" "=e")
4767 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4768 "TARGET_V9 && TARGET_FPU"
4770 [(set_attr "type" "fp")
4771 (set_attr "fptype" "double")])
4773 (define_expand "fixuns_truncsfdi2"
4774 [(use (match_operand:DI 0 "register_operand" ""))
4775 (use (match_operand:SF 1 "general_operand" ""))]
4776 "TARGET_ARCH64 && TARGET_FPU"
4777 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4779 (define_insn "fix_truncdfdi2"
4780 [(set (match_operand:DI 0 "register_operand" "=e")
4781 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4782 "TARGET_V9 && TARGET_FPU"
4784 [(set_attr "type" "fp")
4785 (set_attr "fptype" "double")])
4787 (define_expand "fixuns_truncdfdi2"
4788 [(use (match_operand:DI 0 "register_operand" ""))
4789 (use (match_operand:DF 1 "general_operand" ""))]
4790 "TARGET_ARCH64 && TARGET_FPU"
4791 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4793 (define_expand "fix_trunctfdi2"
4794 [(set (match_operand:DI 0 "register_operand" "")
4795 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4796 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4797 "emit_tfmode_cvt (FIX, operands); DONE;")
4799 (define_insn "*fix_trunctfdi2_hq"
4800 [(set (match_operand:DI 0 "register_operand" "=e")
4801 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4802 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4804 [(set_attr "type" "fp")])
4806 (define_expand "fixuns_trunctfdi2"
4807 [(set (match_operand:DI 0 "register_operand" "")
4808 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4809 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4810 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4812 ;;- arithmetic instructions
4814 (define_expand "adddi3"
4815 [(set (match_operand:DI 0 "register_operand" "")
4816 (plus:DI (match_operand:DI 1 "register_operand" "")
4817 (match_operand:DI 2 "arith_double_add_operand" "")))]
4820 if (! TARGET_ARCH64)
4822 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4823 gen_rtx_SET (VOIDmode, operands[0],
4824 gen_rtx_PLUS (DImode, operands[1],
4826 gen_rtx_CLOBBER (VOIDmode,
4827 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4832 (define_insn_and_split "adddi3_insn_sp32"
4833 [(set (match_operand:DI 0 "register_operand" "=r")
4834 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4835 (match_operand:DI 2 "arith_double_operand" "rHI")))
4836 (clobber (reg:CC 100))]
4839 "&& reload_completed"
4840 [(parallel [(set (reg:CC_NOOV 100)
4841 (compare:CC_NOOV (plus:SI (match_dup 4)
4845 (plus:SI (match_dup 4) (match_dup 5)))])
4847 (plus:SI (plus:SI (match_dup 7)
4849 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4851 operands[3] = gen_lowpart (SImode, operands[0]);
4852 operands[4] = gen_lowpart (SImode, operands[1]);
4853 operands[5] = gen_lowpart (SImode, operands[2]);
4854 operands[6] = gen_highpart (SImode, operands[0]);
4855 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4856 #if HOST_BITS_PER_WIDE_INT == 32
4857 if (GET_CODE (operands[2]) == CONST_INT)
4859 if (INTVAL (operands[2]) < 0)
4860 operands[8] = constm1_rtx;
4862 operands[8] = const0_rtx;
4866 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4868 [(set_attr "length" "2")])
4871 [(set (match_operand:DI 0 "register_operand" "")
4872 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4873 (match_operand:DI 2 "arith_double_operand" "")))
4874 (clobber (reg:CC 100))]
4875 "! TARGET_ARCH64 && reload_completed"
4876 [(parallel [(set (reg:CC_NOOV 100)
4877 (compare:CC_NOOV (minus:SI (match_dup 4)
4881 (minus:SI (match_dup 4) (match_dup 5)))])
4883 (minus:SI (minus:SI (match_dup 7)
4885 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4887 operands[3] = gen_lowpart (SImode, operands[0]);
4888 operands[4] = gen_lowpart (SImode, operands[1]);
4889 operands[5] = gen_lowpart (SImode, operands[2]);
4890 operands[6] = gen_highpart (SImode, operands[0]);
4891 operands[7] = gen_highpart (SImode, operands[1]);
4892 #if HOST_BITS_PER_WIDE_INT == 32
4893 if (GET_CODE (operands[2]) == CONST_INT)
4895 if (INTVAL (operands[2]) < 0)
4896 operands[8] = constm1_rtx;
4898 operands[8] = const0_rtx;
4902 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4905 ;; LTU here means "carry set"
4907 [(set (match_operand:SI 0 "register_operand" "=r")
4908 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4909 (match_operand:SI 2 "arith_operand" "rI"))
4910 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4913 [(set_attr "type" "ialuX")])
4915 (define_insn_and_split "*addx_extend_sp32"
4916 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (zero_extend:DI (plus:SI (plus:SI
4918 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4919 (match_operand:SI 2 "arith_operand" "rI"))
4920 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4923 "&& reload_completed"
4924 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4925 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4926 (set (match_dup 4) (const_int 0))]
4927 "operands[3] = gen_lowpart (SImode, operands[0]);
4928 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4929 [(set_attr "length" "2")])
4931 (define_insn "*addx_extend_sp64"
4932 [(set (match_operand:DI 0 "register_operand" "=r")
4933 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4934 (match_operand:SI 2 "arith_operand" "rI"))
4935 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4938 [(set_attr "type" "ialuX")])
4941 [(set (match_operand:SI 0 "register_operand" "=r")
4942 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4943 (match_operand:SI 2 "arith_operand" "rI"))
4944 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4947 [(set_attr "type" "ialuX")])
4949 (define_insn "*subx_extend_sp64"
4950 [(set (match_operand:DI 0 "register_operand" "=r")
4951 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4952 (match_operand:SI 2 "arith_operand" "rI"))
4953 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4956 [(set_attr "type" "ialuX")])
4958 (define_insn_and_split "*subx_extend"
4959 [(set (match_operand:DI 0 "register_operand" "=r")
4960 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4961 (match_operand:SI 2 "arith_operand" "rI"))
4962 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4965 "&& reload_completed"
4966 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4967 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4968 (set (match_dup 4) (const_int 0))]
4969 "operands[3] = gen_lowpart (SImode, operands[0]);
4970 operands[4] = gen_highpart (SImode, operands[0]);"
4971 [(set_attr "length" "2")])
4973 (define_insn_and_split ""
4974 [(set (match_operand:DI 0 "register_operand" "=r")
4975 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4976 (match_operand:DI 2 "register_operand" "r")))
4977 (clobber (reg:CC 100))]
4980 "&& reload_completed"
4981 [(parallel [(set (reg:CC_NOOV 100)
4982 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4984 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4986 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4987 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4988 "operands[3] = gen_lowpart (SImode, operands[2]);
4989 operands[4] = gen_highpart (SImode, operands[2]);
4990 operands[5] = gen_lowpart (SImode, operands[0]);
4991 operands[6] = gen_highpart (SImode, operands[0]);"
4992 [(set_attr "length" "2")])
4994 (define_insn "*adddi3_sp64"
4995 [(set (match_operand:DI 0 "register_operand" "=r,r")
4996 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4997 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5003 (define_insn "addsi3"
5004 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5005 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5006 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5011 fpadd32s\t%1, %2, %0"
5012 [(set_attr "type" "*,*,fga")])
5014 (define_insn "*cmp_cc_plus"
5015 [(set (reg:CC_NOOV 100)
5016 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5017 (match_operand:SI 1 "arith_operand" "rI"))
5020 "addcc\t%0, %1, %%g0"
5021 [(set_attr "type" "compare")])
5023 (define_insn "*cmp_ccx_plus"
5024 [(set (reg:CCX_NOOV 100)
5025 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5026 (match_operand:DI 1 "arith_double_operand" "rHI"))
5029 "addcc\t%0, %1, %%g0"
5030 [(set_attr "type" "compare")])
5032 (define_insn "*cmp_cc_plus_set"
5033 [(set (reg:CC_NOOV 100)
5034 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5035 (match_operand:SI 2 "arith_operand" "rI"))
5037 (set (match_operand:SI 0 "register_operand" "=r")
5038 (plus:SI (match_dup 1) (match_dup 2)))]
5041 [(set_attr "type" "compare")])
5043 (define_insn "*cmp_ccx_plus_set"
5044 [(set (reg:CCX_NOOV 100)
5045 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5046 (match_operand:DI 2 "arith_double_operand" "rHI"))
5048 (set (match_operand:DI 0 "register_operand" "=r")
5049 (plus:DI (match_dup 1) (match_dup 2)))]
5052 [(set_attr "type" "compare")])
5054 (define_expand "subdi3"
5055 [(set (match_operand:DI 0 "register_operand" "")
5056 (minus:DI (match_operand:DI 1 "register_operand" "")
5057 (match_operand:DI 2 "arith_double_add_operand" "")))]
5060 if (! TARGET_ARCH64)
5062 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5063 gen_rtx_SET (VOIDmode, operands[0],
5064 gen_rtx_MINUS (DImode, operands[1],
5066 gen_rtx_CLOBBER (VOIDmode,
5067 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5072 (define_insn_and_split "*subdi3_sp32"
5073 [(set (match_operand:DI 0 "register_operand" "=r")
5074 (minus:DI (match_operand:DI 1 "register_operand" "r")
5075 (match_operand:DI 2 "arith_double_operand" "rHI")))
5076 (clobber (reg:CC 100))]
5079 "&& reload_completed
5080 && (GET_CODE (operands[2]) == CONST_INT
5081 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5082 [(clobber (const_int 0))]
5086 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5087 lowp = gen_lowpart (SImode, operands[2]);
5088 if ((lowp == const0_rtx)
5089 && (operands[0] == operands[1]))
5091 emit_insn (gen_rtx_SET (VOIDmode,
5092 gen_highpart (SImode, operands[0]),
5093 gen_rtx_MINUS (SImode,
5094 gen_highpart_mode (SImode, DImode,
5100 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5101 gen_lowpart (SImode, operands[1]),
5103 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5104 gen_highpart_mode (SImode, DImode, operands[1]),
5109 [(set_attr "length" "2")])
5112 [(set (match_operand:DI 0 "register_operand" "")
5113 (minus:DI (match_operand:DI 1 "register_operand" "")
5114 (match_operand:DI 2 "register_operand" "")))
5115 (clobber (reg:CC 100))]
5117 && reload_completed"
5118 [(clobber (const_int 0))]
5120 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5121 gen_lowpart (SImode, operands[1]),
5122 gen_lowpart (SImode, operands[2])));
5123 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5124 gen_highpart (SImode, operands[1]),
5125 gen_highpart (SImode, operands[2])));
5129 (define_insn_and_split ""
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5131 (minus:DI (match_operand:DI 1 "register_operand" "r")
5132 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5133 (clobber (reg:CC 100))]
5136 "&& reload_completed"
5137 [(parallel [(set (reg:CC_NOOV 100)
5138 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5140 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5142 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5143 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5144 "operands[3] = gen_lowpart (SImode, operands[1]);
5145 operands[4] = gen_highpart (SImode, operands[1]);
5146 operands[5] = gen_lowpart (SImode, operands[0]);
5147 operands[6] = gen_highpart (SImode, operands[0]);"
5148 [(set_attr "length" "2")])
5150 (define_insn "*subdi3_sp64"
5151 [(set (match_operand:DI 0 "register_operand" "=r,r")
5152 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5153 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5159 (define_insn "subsi3"
5160 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5161 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5162 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5167 fpsub32s\t%1, %2, %0"
5168 [(set_attr "type" "*,*,fga")])
5170 (define_insn "*cmp_minus_cc"
5171 [(set (reg:CC_NOOV 100)
5172 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5173 (match_operand:SI 1 "arith_operand" "rI"))
5176 "subcc\t%r0, %1, %%g0"
5177 [(set_attr "type" "compare")])
5179 (define_insn "*cmp_minus_ccx"
5180 [(set (reg:CCX_NOOV 100)
5181 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5182 (match_operand:DI 1 "arith_double_operand" "rHI"))
5185 "subcc\t%0, %1, %%g0"
5186 [(set_attr "type" "compare")])
5188 (define_insn "cmp_minus_cc_set"
5189 [(set (reg:CC_NOOV 100)
5190 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5191 (match_operand:SI 2 "arith_operand" "rI"))
5193 (set (match_operand:SI 0 "register_operand" "=r")
5194 (minus:SI (match_dup 1) (match_dup 2)))]
5196 "subcc\t%r1, %2, %0"
5197 [(set_attr "type" "compare")])
5199 (define_insn "*cmp_minus_ccx_set"
5200 [(set (reg:CCX_NOOV 100)
5201 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5202 (match_operand:DI 2 "arith_double_operand" "rHI"))
5204 (set (match_operand:DI 0 "register_operand" "=r")
5205 (minus:DI (match_dup 1) (match_dup 2)))]
5208 [(set_attr "type" "compare")])
5210 ;; Integer Multiply/Divide.
5212 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5213 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5215 (define_insn "mulsi3"
5216 [(set (match_operand:SI 0 "register_operand" "=r")
5217 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5218 (match_operand:SI 2 "arith_operand" "rI")))]
5221 [(set_attr "type" "imul")])
5223 (define_expand "muldi3"
5224 [(set (match_operand:DI 0 "register_operand" "=r")
5225 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5226 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5227 "TARGET_ARCH64 || TARGET_V8PLUS"
5231 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5236 (define_insn "*muldi3_sp64"
5237 [(set (match_operand:DI 0 "register_operand" "=r")
5238 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5239 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5242 [(set_attr "type" "imul")])
5244 ;; V8plus wide multiply.
5246 (define_insn "muldi3_v8plus"
5247 [(set (match_operand:DI 0 "register_operand" "=r,h")
5248 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5249 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5250 (clobber (match_scratch:SI 3 "=&h,X"))
5251 (clobber (match_scratch:SI 4 "=&h,X"))]
5254 if (sparc_check_64 (operands[1], insn) <= 0)
5255 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5256 if (which_alternative == 1)
5257 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5258 if (GET_CODE (operands[2]) == CONST_INT)
5260 if (which_alternative == 1)
5261 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5263 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";
5265 else if (rtx_equal_p (operands[1], operands[2]))
5267 if (which_alternative == 1)
5268 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5270 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";
5272 if (sparc_check_64 (operands[2], insn) <= 0)
5273 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5274 if (which_alternative == 1)
5275 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";
5277 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";
5279 [(set_attr "type" "multi")
5280 (set_attr "length" "9,8")])
5282 (define_insn "*cmp_mul_set"
5284 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5285 (match_operand:SI 2 "arith_operand" "rI"))
5287 (set (match_operand:SI 0 "register_operand" "=r")
5288 (mult:SI (match_dup 1) (match_dup 2)))]
5289 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5290 "smulcc\t%1, %2, %0"
5291 [(set_attr "type" "imul")])
5293 (define_expand "mulsidi3"
5294 [(set (match_operand:DI 0 "register_operand" "")
5295 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5296 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5299 if (CONSTANT_P (operands[2]))
5302 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5304 else if (TARGET_ARCH32)
5305 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5308 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5314 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5319 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5320 ;; registers can hold 64 bit values in the V8plus environment.
5322 (define_insn "mulsidi3_v8plus"
5323 [(set (match_operand:DI 0 "register_operand" "=h,r")
5324 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5325 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5326 (clobber (match_scratch:SI 3 "=X,&h"))]
5329 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5330 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5331 [(set_attr "type" "multi")
5332 (set_attr "length" "2,3")])
5335 (define_insn "const_mulsidi3_v8plus"
5336 [(set (match_operand:DI 0 "register_operand" "=h,r")
5337 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5338 (match_operand:DI 2 "small_int" "I,I")))
5339 (clobber (match_scratch:SI 3 "=X,&h"))]
5342 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5343 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5344 [(set_attr "type" "multi")
5345 (set_attr "length" "2,3")])
5348 (define_insn "*mulsidi3_sp32"
5349 [(set (match_operand:DI 0 "register_operand" "=r")
5350 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5351 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5354 return TARGET_SPARCLET
5355 ? "smuld\t%1, %2, %L0"
5356 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5359 (if_then_else (eq_attr "isa" "sparclet")
5360 (const_string "imul") (const_string "multi")))
5361 (set (attr "length")
5362 (if_then_else (eq_attr "isa" "sparclet")
5363 (const_int 1) (const_int 2)))])
5365 (define_insn "*mulsidi3_sp64"
5366 [(set (match_operand:DI 0 "register_operand" "=r")
5367 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5368 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5369 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5371 [(set_attr "type" "imul")])
5373 ;; Extra pattern, because sign_extend of a constant isn't valid.
5376 (define_insn "const_mulsidi3_sp32"
5377 [(set (match_operand:DI 0 "register_operand" "=r")
5378 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5379 (match_operand:DI 2 "small_int" "I")))]
5382 return TARGET_SPARCLET
5383 ? "smuld\t%1, %2, %L0"
5384 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5387 (if_then_else (eq_attr "isa" "sparclet")
5388 (const_string "imul") (const_string "multi")))
5389 (set (attr "length")
5390 (if_then_else (eq_attr "isa" "sparclet")
5391 (const_int 1) (const_int 2)))])
5393 (define_insn "const_mulsidi3_sp64"
5394 [(set (match_operand:DI 0 "register_operand" "=r")
5395 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5396 (match_operand:DI 2 "small_int" "I")))]
5397 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5399 [(set_attr "type" "imul")])
5401 (define_expand "smulsi3_highpart"
5402 [(set (match_operand:SI 0 "register_operand" "")
5404 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5405 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5407 "TARGET_HARD_MUL && TARGET_ARCH32"
5409 if (CONSTANT_P (operands[2]))
5413 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5419 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5424 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5425 operands[2], GEN_INT (32)));
5431 (define_insn "smulsi3_highpart_v8plus"
5432 [(set (match_operand:SI 0 "register_operand" "=h,r")
5434 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5435 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5436 (match_operand:SI 3 "const_int_operand" "i,i"))))
5437 (clobber (match_scratch:SI 4 "=X,&h"))]
5440 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5441 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5442 [(set_attr "type" "multi")
5443 (set_attr "length" "2")])
5445 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5448 [(set (match_operand:SI 0 "register_operand" "=h,r")
5451 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5452 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5453 (match_operand:SI 3 "const_int_operand" "i,i"))
5455 (clobber (match_scratch:SI 4 "=X,&h"))]
5458 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5459 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5460 [(set_attr "type" "multi")
5461 (set_attr "length" "2")])
5464 (define_insn "const_smulsi3_highpart_v8plus"
5465 [(set (match_operand:SI 0 "register_operand" "=h,r")
5467 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5468 (match_operand:DI 2 "small_int" "i,i"))
5469 (match_operand:SI 3 "const_int_operand" "i,i"))))
5470 (clobber (match_scratch:SI 4 "=X,&h"))]
5473 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5474 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5475 [(set_attr "type" "multi")
5476 (set_attr "length" "2")])
5479 (define_insn "*smulsi3_highpart_sp32"
5480 [(set (match_operand:SI 0 "register_operand" "=r")
5482 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5483 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5486 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5487 [(set_attr "type" "multi")
5488 (set_attr "length" "2")])
5491 (define_insn "const_smulsi3_highpart"
5492 [(set (match_operand:SI 0 "register_operand" "=r")
5494 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5495 (match_operand:DI 2 "small_int" "i"))
5498 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5499 [(set_attr "type" "multi")
5500 (set_attr "length" "2")])
5502 (define_expand "umulsidi3"
5503 [(set (match_operand:DI 0 "register_operand" "")
5504 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5505 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5508 if (CONSTANT_P (operands[2]))
5511 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5513 else if (TARGET_ARCH32)
5514 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5517 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5523 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5529 (define_insn "umulsidi3_v8plus"
5530 [(set (match_operand:DI 0 "register_operand" "=h,r")
5531 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5532 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5533 (clobber (match_scratch:SI 3 "=X,&h"))]
5536 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5537 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5538 [(set_attr "type" "multi")
5539 (set_attr "length" "2,3")])
5542 (define_insn "*umulsidi3_sp32"
5543 [(set (match_operand:DI 0 "register_operand" "=r")
5544 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5545 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5548 return TARGET_SPARCLET
5549 ? "umuld\t%1, %2, %L0"
5550 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5553 (if_then_else (eq_attr "isa" "sparclet")
5554 (const_string "imul") (const_string "multi")))
5555 (set (attr "length")
5556 (if_then_else (eq_attr "isa" "sparclet")
5557 (const_int 1) (const_int 2)))])
5559 (define_insn "*umulsidi3_sp64"
5560 [(set (match_operand:DI 0 "register_operand" "=r")
5561 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5562 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5563 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5565 [(set_attr "type" "imul")])
5567 ;; Extra pattern, because sign_extend of a constant isn't valid.
5570 (define_insn "const_umulsidi3_sp32"
5571 [(set (match_operand:DI 0 "register_operand" "=r")
5572 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5573 (match_operand:DI 2 "uns_small_int" "")))]
5576 return TARGET_SPARCLET
5577 ? "umuld\t%1, %s2, %L0"
5578 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5581 (if_then_else (eq_attr "isa" "sparclet")
5582 (const_string "imul") (const_string "multi")))
5583 (set (attr "length")
5584 (if_then_else (eq_attr "isa" "sparclet")
5585 (const_int 1) (const_int 2)))])
5587 (define_insn "const_umulsidi3_sp64"
5588 [(set (match_operand:DI 0 "register_operand" "=r")
5589 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5590 (match_operand:DI 2 "uns_small_int" "")))]
5591 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5593 [(set_attr "type" "imul")])
5596 (define_insn "const_umulsidi3_v8plus"
5597 [(set (match_operand:DI 0 "register_operand" "=h,r")
5598 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5599 (match_operand:DI 2 "uns_small_int" "")))
5600 (clobber (match_scratch:SI 3 "=X,h"))]
5603 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5604 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5605 [(set_attr "type" "multi")
5606 (set_attr "length" "2,3")])
5608 (define_expand "umulsi3_highpart"
5609 [(set (match_operand:SI 0 "register_operand" "")
5611 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5612 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5614 "TARGET_HARD_MUL && TARGET_ARCH32"
5616 if (CONSTANT_P (operands[2]))
5620 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5626 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5631 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5632 operands[2], GEN_INT (32)));
5638 (define_insn "umulsi3_highpart_v8plus"
5639 [(set (match_operand:SI 0 "register_operand" "=h,r")
5641 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5642 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5643 (match_operand:SI 3 "const_int_operand" "i,i"))))
5644 (clobber (match_scratch:SI 4 "=X,h"))]
5647 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5648 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5649 [(set_attr "type" "multi")
5650 (set_attr "length" "2")])
5653 (define_insn "const_umulsi3_highpart_v8plus"
5654 [(set (match_operand:SI 0 "register_operand" "=h,r")
5656 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5657 (match_operand:DI 2 "uns_small_int" ""))
5658 (match_operand:SI 3 "const_int_operand" "i,i"))))
5659 (clobber (match_scratch:SI 4 "=X,h"))]
5662 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5663 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5664 [(set_attr "type" "multi")
5665 (set_attr "length" "2")])
5668 (define_insn "*umulsi3_highpart_sp32"
5669 [(set (match_operand:SI 0 "register_operand" "=r")
5671 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5672 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5675 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5676 [(set_attr "type" "multi")
5677 (set_attr "length" "2")])
5680 (define_insn "const_umulsi3_highpart"
5681 [(set (match_operand:SI 0 "register_operand" "=r")
5683 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5684 (match_operand:DI 2 "uns_small_int" ""))
5687 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5688 [(set_attr "type" "multi")
5689 (set_attr "length" "2")])
5691 ;; The v8 architecture specifies that there must be 3 instructions between
5692 ;; a y register write and a use of it for correct results.
5694 (define_expand "divsi3"
5695 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5696 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5697 (match_operand:SI 2 "input_operand" "rI,m")))
5698 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5699 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5703 operands[3] = gen_reg_rtx(SImode);
5704 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5705 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5711 (define_insn "divsi3_sp32"
5712 [(set (match_operand:SI 0 "register_operand" "=r,r")
5713 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5714 (match_operand:SI 2 "input_operand" "rI,m")))
5715 (clobber (match_scratch:SI 3 "=&r,&r"))]
5716 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5719 if (which_alternative == 0)
5721 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5723 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5726 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5728 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";
5730 [(set_attr "type" "multi")
5731 (set (attr "length")
5732 (if_then_else (eq_attr "isa" "v9")
5733 (const_int 4) (const_int 6)))])
5735 (define_insn "divsi3_sp64"
5736 [(set (match_operand:SI 0 "register_operand" "=r")
5737 (div:SI (match_operand:SI 1 "register_operand" "r")
5738 (match_operand:SI 2 "input_operand" "rI")))
5739 (use (match_operand:SI 3 "register_operand" "r"))]
5740 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5741 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5742 [(set_attr "type" "multi")
5743 (set_attr "length" "2")])
5745 (define_insn "divdi3"
5746 [(set (match_operand:DI 0 "register_operand" "=r")
5747 (div:DI (match_operand:DI 1 "register_operand" "r")
5748 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5751 [(set_attr "type" "idiv")])
5753 (define_insn "*cmp_sdiv_cc_set"
5755 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5756 (match_operand:SI 2 "arith_operand" "rI"))
5758 (set (match_operand:SI 0 "register_operand" "=r")
5759 (div:SI (match_dup 1) (match_dup 2)))
5760 (clobber (match_scratch:SI 3 "=&r"))]
5761 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5764 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5766 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5768 [(set_attr "type" "multi")
5769 (set (attr "length")
5770 (if_then_else (eq_attr "isa" "v9")
5771 (const_int 3) (const_int 6)))])
5774 (define_expand "udivsi3"
5775 [(set (match_operand:SI 0 "register_operand" "")
5776 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5777 (match_operand:SI 2 "input_operand" "")))]
5778 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5781 (define_insn "udivsi3_sp32"
5782 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5783 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5784 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5786 || TARGET_DEPRECATED_V8_INSNS)
5789 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5790 switch (which_alternative)
5793 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5795 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5797 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5800 [(set_attr "type" "multi")
5801 (set_attr "length" "5")])
5803 (define_insn "udivsi3_sp64"
5804 [(set (match_operand:SI 0 "register_operand" "=r")
5805 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5806 (match_operand:SI 2 "input_operand" "rI")))]
5807 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5808 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5809 [(set_attr "type" "multi")
5810 (set_attr "length" "2")])
5812 (define_insn "udivdi3"
5813 [(set (match_operand:DI 0 "register_operand" "=r")
5814 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5815 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5818 [(set_attr "type" "idiv")])
5820 (define_insn "*cmp_udiv_cc_set"
5822 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5823 (match_operand:SI 2 "arith_operand" "rI"))
5825 (set (match_operand:SI 0 "register_operand" "=r")
5826 (udiv:SI (match_dup 1) (match_dup 2)))]
5828 || TARGET_DEPRECATED_V8_INSNS"
5831 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5833 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5835 [(set_attr "type" "multi")
5836 (set (attr "length")
5837 (if_then_else (eq_attr "isa" "v9")
5838 (const_int 2) (const_int 5)))])
5840 ; sparclet multiply/accumulate insns
5842 (define_insn "*smacsi"
5843 [(set (match_operand:SI 0 "register_operand" "=r")
5844 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5845 (match_operand:SI 2 "arith_operand" "rI"))
5846 (match_operand:SI 3 "register_operand" "0")))]
5849 [(set_attr "type" "imul")])
5851 (define_insn "*smacdi"
5852 [(set (match_operand:DI 0 "register_operand" "=r")
5853 (plus:DI (mult:DI (sign_extend:DI
5854 (match_operand:SI 1 "register_operand" "%r"))
5856 (match_operand:SI 2 "register_operand" "r")))
5857 (match_operand:DI 3 "register_operand" "0")))]
5859 "smacd\t%1, %2, %L0"
5860 [(set_attr "type" "imul")])
5862 (define_insn "*umacdi"
5863 [(set (match_operand:DI 0 "register_operand" "=r")
5864 (plus:DI (mult:DI (zero_extend:DI
5865 (match_operand:SI 1 "register_operand" "%r"))
5867 (match_operand:SI 2 "register_operand" "r")))
5868 (match_operand:DI 3 "register_operand" "0")))]
5870 "umacd\t%1, %2, %L0"
5871 [(set_attr "type" "imul")])
5873 ;;- Boolean instructions
5874 ;; We define DImode `and' so with DImode `not' we can get
5875 ;; DImode `andn'. Other combinations are possible.
5877 (define_expand "anddi3"
5878 [(set (match_operand:DI 0 "register_operand" "")
5879 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5880 (match_operand:DI 2 "arith_double_operand" "")))]
5884 (define_insn "*anddi3_sp32"
5885 [(set (match_operand:DI 0 "register_operand" "=r,b")
5886 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5887 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5892 [(set_attr "type" "*,fga")
5893 (set_attr "length" "2,*")
5894 (set_attr "fptype" "double")])
5896 (define_insn "*anddi3_sp64"
5897 [(set (match_operand:DI 0 "register_operand" "=r,b")
5898 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5899 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5904 [(set_attr "type" "*,fga")
5905 (set_attr "fptype" "double")])
5907 (define_insn "andsi3"
5908 [(set (match_operand:SI 0 "register_operand" "=r,d")
5909 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5910 (match_operand:SI 2 "arith_operand" "rI,d")))]
5915 [(set_attr "type" "*,fga")])
5918 [(set (match_operand:SI 0 "register_operand" "")
5919 (and:SI (match_operand:SI 1 "register_operand" "")
5920 (match_operand:SI 2 "" "")))
5921 (clobber (match_operand:SI 3 "register_operand" ""))]
5922 "GET_CODE (operands[2]) == CONST_INT
5923 && !SMALL_INT32 (operands[2])
5924 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5925 [(set (match_dup 3) (match_dup 4))
5926 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5928 operands[4] = GEN_INT (~INTVAL (operands[2]));
5931 ;; Split DImode logical operations requiring two instructions.
5933 [(set (match_operand:DI 0 "register_operand" "")
5934 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5935 [(match_operand:DI 2 "register_operand" "")
5936 (match_operand:DI 3 "arith_double_operand" "")]))]
5939 && ((GET_CODE (operands[0]) == REG
5940 && REGNO (operands[0]) < 32)
5941 || (GET_CODE (operands[0]) == SUBREG
5942 && GET_CODE (SUBREG_REG (operands[0])) == REG
5943 && REGNO (SUBREG_REG (operands[0])) < 32))"
5944 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5945 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5947 operands[4] = gen_highpart (SImode, operands[0]);
5948 operands[5] = gen_lowpart (SImode, operands[0]);
5949 operands[6] = gen_highpart (SImode, operands[2]);
5950 operands[7] = gen_lowpart (SImode, operands[2]);
5951 #if HOST_BITS_PER_WIDE_INT == 32
5952 if (GET_CODE (operands[3]) == CONST_INT)
5954 if (INTVAL (operands[3]) < 0)
5955 operands[8] = constm1_rtx;
5957 operands[8] = const0_rtx;
5961 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5962 operands[9] = gen_lowpart (SImode, operands[3]);
5965 (define_insn_and_split "*and_not_di_sp32"
5966 [(set (match_operand:DI 0 "register_operand" "=r,b")
5967 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5968 (match_operand:DI 2 "register_operand" "r,b")))]
5972 fandnot1\t%1, %2, %0"
5973 "&& reload_completed
5974 && ((GET_CODE (operands[0]) == REG
5975 && REGNO (operands[0]) < 32)
5976 || (GET_CODE (operands[0]) == SUBREG
5977 && GET_CODE (SUBREG_REG (operands[0])) == REG
5978 && REGNO (SUBREG_REG (operands[0])) < 32))"
5979 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5980 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5981 "operands[3] = gen_highpart (SImode, operands[0]);
5982 operands[4] = gen_highpart (SImode, operands[1]);
5983 operands[5] = gen_highpart (SImode, operands[2]);
5984 operands[6] = gen_lowpart (SImode, operands[0]);
5985 operands[7] = gen_lowpart (SImode, operands[1]);
5986 operands[8] = gen_lowpart (SImode, operands[2]);"
5987 [(set_attr "type" "*,fga")
5988 (set_attr "length" "2,*")
5989 (set_attr "fptype" "double")])
5991 (define_insn "*and_not_di_sp64"
5992 [(set (match_operand:DI 0 "register_operand" "=r,b")
5993 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5994 (match_operand:DI 2 "register_operand" "r,b")))]
5998 fandnot1\t%1, %2, %0"
5999 [(set_attr "type" "*,fga")
6000 (set_attr "fptype" "double")])
6002 (define_insn "*and_not_si"
6003 [(set (match_operand:SI 0 "register_operand" "=r,d")
6004 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6005 (match_operand:SI 2 "register_operand" "r,d")))]
6009 fandnot1s\t%1, %2, %0"
6010 [(set_attr "type" "*,fga")])
6012 (define_expand "iordi3"
6013 [(set (match_operand:DI 0 "register_operand" "")
6014 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6015 (match_operand:DI 2 "arith_double_operand" "")))]
6019 (define_insn "*iordi3_sp32"
6020 [(set (match_operand:DI 0 "register_operand" "=r,b")
6021 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6022 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6027 [(set_attr "type" "*,fga")
6028 (set_attr "length" "2,*")
6029 (set_attr "fptype" "double")])
6031 (define_insn "*iordi3_sp64"
6032 [(set (match_operand:DI 0 "register_operand" "=r,b")
6033 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6034 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6039 [(set_attr "type" "*,fga")
6040 (set_attr "fptype" "double")])
6042 (define_insn "iorsi3"
6043 [(set (match_operand:SI 0 "register_operand" "=r,d")
6044 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6045 (match_operand:SI 2 "arith_operand" "rI,d")))]
6050 [(set_attr "type" "*,fga")])
6053 [(set (match_operand:SI 0 "register_operand" "")
6054 (ior:SI (match_operand:SI 1 "register_operand" "")
6055 (match_operand:SI 2 "" "")))
6056 (clobber (match_operand:SI 3 "register_operand" ""))]
6057 "GET_CODE (operands[2]) == CONST_INT
6058 && !SMALL_INT32 (operands[2])
6059 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6060 [(set (match_dup 3) (match_dup 4))
6061 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6063 operands[4] = GEN_INT (~INTVAL (operands[2]));
6066 (define_insn_and_split "*or_not_di_sp32"
6067 [(set (match_operand:DI 0 "register_operand" "=r,b")
6068 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6069 (match_operand:DI 2 "register_operand" "r,b")))]
6073 fornot1\t%1, %2, %0"
6074 "&& reload_completed
6075 && ((GET_CODE (operands[0]) == REG
6076 && REGNO (operands[0]) < 32)
6077 || (GET_CODE (operands[0]) == SUBREG
6078 && GET_CODE (SUBREG_REG (operands[0])) == REG
6079 && REGNO (SUBREG_REG (operands[0])) < 32))"
6080 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6081 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6082 "operands[3] = gen_highpart (SImode, operands[0]);
6083 operands[4] = gen_highpart (SImode, operands[1]);
6084 operands[5] = gen_highpart (SImode, operands[2]);
6085 operands[6] = gen_lowpart (SImode, operands[0]);
6086 operands[7] = gen_lowpart (SImode, operands[1]);
6087 operands[8] = gen_lowpart (SImode, operands[2]);"
6088 [(set_attr "type" "*,fga")
6089 (set_attr "length" "2,*")
6090 (set_attr "fptype" "double")])
6092 (define_insn "*or_not_di_sp64"
6093 [(set (match_operand:DI 0 "register_operand" "=r,b")
6094 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6095 (match_operand:DI 2 "register_operand" "r,b")))]
6099 fornot1\t%1, %2, %0"
6100 [(set_attr "type" "*,fga")
6101 (set_attr "fptype" "double")])
6103 (define_insn "*or_not_si"
6104 [(set (match_operand:SI 0 "register_operand" "=r,d")
6105 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6106 (match_operand:SI 2 "register_operand" "r,d")))]
6110 fornot1s\t%1, %2, %0"
6111 [(set_attr "type" "*,fga")])
6113 (define_expand "xordi3"
6114 [(set (match_operand:DI 0 "register_operand" "")
6115 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6116 (match_operand:DI 2 "arith_double_operand" "")))]
6120 (define_insn "*xordi3_sp32"
6121 [(set (match_operand:DI 0 "register_operand" "=r,b")
6122 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6123 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6128 [(set_attr "type" "*,fga")
6129 (set_attr "length" "2,*")
6130 (set_attr "fptype" "double")])
6132 (define_insn "*xordi3_sp64"
6133 [(set (match_operand:DI 0 "register_operand" "=r,b")
6134 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6135 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6140 [(set_attr "type" "*,fga")
6141 (set_attr "fptype" "double")])
6143 (define_insn "*xordi3_sp64_dbl"
6144 [(set (match_operand:DI 0 "register_operand" "=r")
6145 (xor:DI (match_operand:DI 1 "register_operand" "r")
6146 (match_operand:DI 2 "const64_operand" "")))]
6148 && HOST_BITS_PER_WIDE_INT != 64)"
6151 (define_insn "xorsi3"
6152 [(set (match_operand:SI 0 "register_operand" "=r,d")
6153 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6154 (match_operand:SI 2 "arith_operand" "rI,d")))]
6159 [(set_attr "type" "*,fga")])
6162 [(set (match_operand:SI 0 "register_operand" "")
6163 (xor:SI (match_operand:SI 1 "register_operand" "")
6164 (match_operand:SI 2 "" "")))
6165 (clobber (match_operand:SI 3 "register_operand" ""))]
6166 "GET_CODE (operands[2]) == CONST_INT
6167 && !SMALL_INT32 (operands[2])
6168 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6169 [(set (match_dup 3) (match_dup 4))
6170 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6172 operands[4] = GEN_INT (~INTVAL (operands[2]));
6176 [(set (match_operand:SI 0 "register_operand" "")
6177 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6178 (match_operand:SI 2 "" ""))))
6179 (clobber (match_operand:SI 3 "register_operand" ""))]
6180 "GET_CODE (operands[2]) == CONST_INT
6181 && !SMALL_INT32 (operands[2])
6182 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6183 [(set (match_dup 3) (match_dup 4))
6184 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6186 operands[4] = GEN_INT (~INTVAL (operands[2]));
6189 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6190 ;; Combine now canonicalizes to the rightmost expression.
6191 (define_insn_and_split "*xor_not_di_sp32"
6192 [(set (match_operand:DI 0 "register_operand" "=r,b")
6193 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6194 (match_operand:DI 2 "register_operand" "r,b"))))]
6199 "&& reload_completed
6200 && ((GET_CODE (operands[0]) == REG
6201 && REGNO (operands[0]) < 32)
6202 || (GET_CODE (operands[0]) == SUBREG
6203 && GET_CODE (SUBREG_REG (operands[0])) == REG
6204 && REGNO (SUBREG_REG (operands[0])) < 32))"
6205 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6206 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6207 "operands[3] = gen_highpart (SImode, operands[0]);
6208 operands[4] = gen_highpart (SImode, operands[1]);
6209 operands[5] = gen_highpart (SImode, operands[2]);
6210 operands[6] = gen_lowpart (SImode, operands[0]);
6211 operands[7] = gen_lowpart (SImode, operands[1]);
6212 operands[8] = gen_lowpart (SImode, operands[2]);"
6213 [(set_attr "type" "*,fga")
6214 (set_attr "length" "2,*")
6215 (set_attr "fptype" "double")])
6217 (define_insn "*xor_not_di_sp64"
6218 [(set (match_operand:DI 0 "register_operand" "=r,b")
6219 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6220 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6225 [(set_attr "type" "*,fga")
6226 (set_attr "fptype" "double")])
6228 (define_insn "*xor_not_si"
6229 [(set (match_operand:SI 0 "register_operand" "=r,d")
6230 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6231 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6236 [(set_attr "type" "*,fga")])
6238 ;; These correspond to the above in the case where we also (or only)
6239 ;; want to set the condition code.
6241 (define_insn "*cmp_cc_arith_op"
6244 (match_operator:SI 2 "cc_arithop"
6245 [(match_operand:SI 0 "arith_operand" "%r")
6246 (match_operand:SI 1 "arith_operand" "rI")])
6249 "%A2cc\t%0, %1, %%g0"
6250 [(set_attr "type" "compare")])
6252 (define_insn "*cmp_ccx_arith_op"
6255 (match_operator:DI 2 "cc_arithop"
6256 [(match_operand:DI 0 "arith_double_operand" "%r")
6257 (match_operand:DI 1 "arith_double_operand" "rHI")])
6260 "%A2cc\t%0, %1, %%g0"
6261 [(set_attr "type" "compare")])
6263 (define_insn "*cmp_cc_arith_op_set"
6266 (match_operator:SI 3 "cc_arithop"
6267 [(match_operand:SI 1 "arith_operand" "%r")
6268 (match_operand:SI 2 "arith_operand" "rI")])
6270 (set (match_operand:SI 0 "register_operand" "=r")
6271 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6272 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6274 [(set_attr "type" "compare")])
6276 (define_insn "*cmp_ccx_arith_op_set"
6279 (match_operator:DI 3 "cc_arithop"
6280 [(match_operand:DI 1 "arith_double_operand" "%r")
6281 (match_operand:DI 2 "arith_double_operand" "rHI")])
6283 (set (match_operand:DI 0 "register_operand" "=r")
6284 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6285 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6287 [(set_attr "type" "compare")])
6289 (define_insn "*cmp_cc_xor_not"
6292 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6293 (match_operand:SI 1 "arith_operand" "rI")))
6296 "xnorcc\t%r0, %1, %%g0"
6297 [(set_attr "type" "compare")])
6299 (define_insn "*cmp_ccx_xor_not"
6302 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6303 (match_operand:DI 1 "arith_double_operand" "rHI")))
6306 "xnorcc\t%r0, %1, %%g0"
6307 [(set_attr "type" "compare")])
6309 (define_insn "*cmp_cc_xor_not_set"
6312 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6313 (match_operand:SI 2 "arith_operand" "rI")))
6315 (set (match_operand:SI 0 "register_operand" "=r")
6316 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6318 "xnorcc\t%r1, %2, %0"
6319 [(set_attr "type" "compare")])
6321 (define_insn "*cmp_ccx_xor_not_set"
6324 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6325 (match_operand:DI 2 "arith_double_operand" "rHI")))
6327 (set (match_operand:DI 0 "register_operand" "=r")
6328 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6330 "xnorcc\t%r1, %2, %0"
6331 [(set_attr "type" "compare")])
6333 (define_insn "*cmp_cc_arith_op_not"
6336 (match_operator:SI 2 "cc_arithopn"
6337 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6338 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6341 "%B2cc\t%r1, %0, %%g0"
6342 [(set_attr "type" "compare")])
6344 (define_insn "*cmp_ccx_arith_op_not"
6347 (match_operator:DI 2 "cc_arithopn"
6348 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6349 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6352 "%B2cc\t%r1, %0, %%g0"
6353 [(set_attr "type" "compare")])
6355 (define_insn "*cmp_cc_arith_op_not_set"
6358 (match_operator:SI 3 "cc_arithopn"
6359 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6360 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6362 (set (match_operand:SI 0 "register_operand" "=r")
6363 (match_operator:SI 4 "cc_arithopn"
6364 [(not:SI (match_dup 1)) (match_dup 2)]))]
6365 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6366 "%B3cc\t%r2, %1, %0"
6367 [(set_attr "type" "compare")])
6369 (define_insn "*cmp_ccx_arith_op_not_set"
6372 (match_operator:DI 3 "cc_arithopn"
6373 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6374 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6376 (set (match_operand:DI 0 "register_operand" "=r")
6377 (match_operator:DI 4 "cc_arithopn"
6378 [(not:DI (match_dup 1)) (match_dup 2)]))]
6379 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6380 "%B3cc\t%r2, %1, %0"
6381 [(set_attr "type" "compare")])
6383 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6384 ;; does not know how to make it work for constants.
6386 (define_expand "negdi2"
6387 [(set (match_operand:DI 0 "register_operand" "=r")
6388 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6391 if (! TARGET_ARCH64)
6393 emit_insn (gen_rtx_PARALLEL
6396 gen_rtx_SET (VOIDmode, operand0,
6397 gen_rtx_NEG (DImode, operand1)),
6398 gen_rtx_CLOBBER (VOIDmode,
6399 gen_rtx_REG (CCmode,
6405 (define_insn_and_split "*negdi2_sp32"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6407 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6408 (clobber (reg:CC 100))]
6411 "&& reload_completed"
6412 [(parallel [(set (reg:CC_NOOV 100)
6413 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6415 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6416 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6417 (ltu:SI (reg:CC 100) (const_int 0))))]
6418 "operands[2] = gen_highpart (SImode, operands[0]);
6419 operands[3] = gen_highpart (SImode, operands[1]);
6420 operands[4] = gen_lowpart (SImode, operands[0]);
6421 operands[5] = gen_lowpart (SImode, operands[1]);"
6422 [(set_attr "length" "2")])
6424 (define_insn "*negdi2_sp64"
6425 [(set (match_operand:DI 0 "register_operand" "=r")
6426 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6428 "sub\t%%g0, %1, %0")
6430 (define_insn "negsi2"
6431 [(set (match_operand:SI 0 "register_operand" "=r")
6432 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6434 "sub\t%%g0, %1, %0")
6436 (define_insn "*cmp_cc_neg"
6437 [(set (reg:CC_NOOV 100)
6438 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6441 "subcc\t%%g0, %0, %%g0"
6442 [(set_attr "type" "compare")])
6444 (define_insn "*cmp_ccx_neg"
6445 [(set (reg:CCX_NOOV 100)
6446 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6449 "subcc\t%%g0, %0, %%g0"
6450 [(set_attr "type" "compare")])
6452 (define_insn "*cmp_cc_set_neg"
6453 [(set (reg:CC_NOOV 100)
6454 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6456 (set (match_operand:SI 0 "register_operand" "=r")
6457 (neg:SI (match_dup 1)))]
6459 "subcc\t%%g0, %1, %0"
6460 [(set_attr "type" "compare")])
6462 (define_insn "*cmp_ccx_set_neg"
6463 [(set (reg:CCX_NOOV 100)
6464 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6466 (set (match_operand:DI 0 "register_operand" "=r")
6467 (neg:DI (match_dup 1)))]
6469 "subcc\t%%g0, %1, %0"
6470 [(set_attr "type" "compare")])
6472 ;; We cannot use the "not" pseudo insn because the Sun assembler
6473 ;; does not know how to make it work for constants.
6474 (define_expand "one_cmpldi2"
6475 [(set (match_operand:DI 0 "register_operand" "")
6476 (not:DI (match_operand:DI 1 "register_operand" "")))]
6480 (define_insn_and_split "*one_cmpldi2_sp32"
6481 [(set (match_operand:DI 0 "register_operand" "=r,b")
6482 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6487 "&& reload_completed
6488 && ((GET_CODE (operands[0]) == REG
6489 && REGNO (operands[0]) < 32)
6490 || (GET_CODE (operands[0]) == SUBREG
6491 && GET_CODE (SUBREG_REG (operands[0])) == REG
6492 && REGNO (SUBREG_REG (operands[0])) < 32))"
6493 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6494 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6495 "operands[2] = gen_highpart (SImode, operands[0]);
6496 operands[3] = gen_highpart (SImode, operands[1]);
6497 operands[4] = gen_lowpart (SImode, operands[0]);
6498 operands[5] = gen_lowpart (SImode, operands[1]);"
6499 [(set_attr "type" "*,fga")
6500 (set_attr "length" "2,*")
6501 (set_attr "fptype" "double")])
6503 (define_insn "*one_cmpldi2_sp64"
6504 [(set (match_operand:DI 0 "register_operand" "=r,b")
6505 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6510 [(set_attr "type" "*,fga")
6511 (set_attr "fptype" "double")])
6513 (define_insn "one_cmplsi2"
6514 [(set (match_operand:SI 0 "register_operand" "=r,d")
6515 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6520 [(set_attr "type" "*,fga")])
6522 (define_insn "*cmp_cc_not"
6524 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6527 "xnorcc\t%%g0, %0, %%g0"
6528 [(set_attr "type" "compare")])
6530 (define_insn "*cmp_ccx_not"
6532 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6535 "xnorcc\t%%g0, %0, %%g0"
6536 [(set_attr "type" "compare")])
6538 (define_insn "*cmp_cc_set_not"
6540 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6542 (set (match_operand:SI 0 "register_operand" "=r")
6543 (not:SI (match_dup 1)))]
6545 "xnorcc\t%%g0, %1, %0"
6546 [(set_attr "type" "compare")])
6548 (define_insn "*cmp_ccx_set_not"
6550 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6552 (set (match_operand:DI 0 "register_operand" "=r")
6553 (not:DI (match_dup 1)))]
6555 "xnorcc\t%%g0, %1, %0"
6556 [(set_attr "type" "compare")])
6558 (define_insn "*cmp_cc_set"
6559 [(set (match_operand:SI 0 "register_operand" "=r")
6560 (match_operand:SI 1 "register_operand" "r"))
6562 (compare:CC (match_dup 1)
6566 [(set_attr "type" "compare")])
6568 (define_insn "*cmp_ccx_set64"
6569 [(set (match_operand:DI 0 "register_operand" "=r")
6570 (match_operand:DI 1 "register_operand" "r"))
6572 (compare:CCX (match_dup 1)
6576 [(set_attr "type" "compare")])
6578 ;; Floating point arithmetic instructions.
6580 (define_expand "addtf3"
6581 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6582 (plus:TF (match_operand:TF 1 "general_operand" "")
6583 (match_operand:TF 2 "general_operand" "")))]
6584 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6585 "emit_tfmode_binop (PLUS, operands); DONE;")
6587 (define_insn "*addtf3_hq"
6588 [(set (match_operand:TF 0 "register_operand" "=e")
6589 (plus:TF (match_operand:TF 1 "register_operand" "e")
6590 (match_operand:TF 2 "register_operand" "e")))]
6591 "TARGET_FPU && TARGET_HARD_QUAD"
6593 [(set_attr "type" "fp")])
6595 (define_insn "adddf3"
6596 [(set (match_operand:DF 0 "register_operand" "=e")
6597 (plus:DF (match_operand:DF 1 "register_operand" "e")
6598 (match_operand:DF 2 "register_operand" "e")))]
6601 [(set_attr "type" "fp")
6602 (set_attr "fptype" "double")])
6604 (define_insn "addsf3"
6605 [(set (match_operand:SF 0 "register_operand" "=f")
6606 (plus:SF (match_operand:SF 1 "register_operand" "f")
6607 (match_operand:SF 2 "register_operand" "f")))]
6610 [(set_attr "type" "fp")])
6612 (define_expand "subtf3"
6613 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6614 (minus:TF (match_operand:TF 1 "general_operand" "")
6615 (match_operand:TF 2 "general_operand" "")))]
6616 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6617 "emit_tfmode_binop (MINUS, operands); DONE;")
6619 (define_insn "*subtf3_hq"
6620 [(set (match_operand:TF 0 "register_operand" "=e")
6621 (minus:TF (match_operand:TF 1 "register_operand" "e")
6622 (match_operand:TF 2 "register_operand" "e")))]
6623 "TARGET_FPU && TARGET_HARD_QUAD"
6625 [(set_attr "type" "fp")])
6627 (define_insn "subdf3"
6628 [(set (match_operand:DF 0 "register_operand" "=e")
6629 (minus:DF (match_operand:DF 1 "register_operand" "e")
6630 (match_operand:DF 2 "register_operand" "e")))]
6633 [(set_attr "type" "fp")
6634 (set_attr "fptype" "double")])
6636 (define_insn "subsf3"
6637 [(set (match_operand:SF 0 "register_operand" "=f")
6638 (minus:SF (match_operand:SF 1 "register_operand" "f")
6639 (match_operand:SF 2 "register_operand" "f")))]
6642 [(set_attr "type" "fp")])
6644 (define_expand "multf3"
6645 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6646 (mult:TF (match_operand:TF 1 "general_operand" "")
6647 (match_operand:TF 2 "general_operand" "")))]
6648 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6649 "emit_tfmode_binop (MULT, operands); DONE;")
6651 (define_insn "*multf3_hq"
6652 [(set (match_operand:TF 0 "register_operand" "=e")
6653 (mult:TF (match_operand:TF 1 "register_operand" "e")
6654 (match_operand:TF 2 "register_operand" "e")))]
6655 "TARGET_FPU && TARGET_HARD_QUAD"
6657 [(set_attr "type" "fpmul")])
6659 (define_insn "muldf3"
6660 [(set (match_operand:DF 0 "register_operand" "=e")
6661 (mult:DF (match_operand:DF 1 "register_operand" "e")
6662 (match_operand:DF 2 "register_operand" "e")))]
6665 [(set_attr "type" "fpmul")
6666 (set_attr "fptype" "double")])
6668 (define_insn "mulsf3"
6669 [(set (match_operand:SF 0 "register_operand" "=f")
6670 (mult:SF (match_operand:SF 1 "register_operand" "f")
6671 (match_operand:SF 2 "register_operand" "f")))]
6674 [(set_attr "type" "fpmul")])
6676 (define_insn "*muldf3_extend"
6677 [(set (match_operand:DF 0 "register_operand" "=e")
6678 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6679 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6680 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6681 "fsmuld\t%1, %2, %0"
6682 [(set_attr "type" "fpmul")
6683 (set_attr "fptype" "double")])
6685 (define_insn "*multf3_extend"
6686 [(set (match_operand:TF 0 "register_operand" "=e")
6687 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6688 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6689 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6690 "fdmulq\t%1, %2, %0"
6691 [(set_attr "type" "fpmul")])
6693 (define_expand "divtf3"
6694 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6695 (div:TF (match_operand:TF 1 "general_operand" "")
6696 (match_operand:TF 2 "general_operand" "")))]
6697 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6698 "emit_tfmode_binop (DIV, operands); DONE;")
6700 ;; don't have timing for quad-prec. divide.
6701 (define_insn "*divtf3_hq"
6702 [(set (match_operand:TF 0 "register_operand" "=e")
6703 (div:TF (match_operand:TF 1 "register_operand" "e")
6704 (match_operand:TF 2 "register_operand" "e")))]
6705 "TARGET_FPU && TARGET_HARD_QUAD"
6707 [(set_attr "type" "fpdivd")])
6709 (define_insn "divdf3"
6710 [(set (match_operand:DF 0 "register_operand" "=e")
6711 (div:DF (match_operand:DF 1 "register_operand" "e")
6712 (match_operand:DF 2 "register_operand" "e")))]
6715 [(set_attr "type" "fpdivd")
6716 (set_attr "fptype" "double")])
6718 (define_insn "divsf3"
6719 [(set (match_operand:SF 0 "register_operand" "=f")
6720 (div:SF (match_operand:SF 1 "register_operand" "f")
6721 (match_operand:SF 2 "register_operand" "f")))]
6724 [(set_attr "type" "fpdivs")])
6726 (define_expand "negtf2"
6727 [(set (match_operand:TF 0 "register_operand" "=e,e")
6728 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6732 (define_insn_and_split "*negtf2_notv9"
6733 [(set (match_operand:TF 0 "register_operand" "=e,e")
6734 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6735 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6741 "&& reload_completed
6742 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6743 [(set (match_dup 2) (neg:SF (match_dup 3)))
6744 (set (match_dup 4) (match_dup 5))
6745 (set (match_dup 6) (match_dup 7))]
6746 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6747 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6748 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6749 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6750 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6751 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6752 [(set_attr "type" "fpmove,*")
6753 (set_attr "length" "*,2")])
6755 (define_insn_and_split "*negtf2_v9"
6756 [(set (match_operand:TF 0 "register_operand" "=e,e")
6757 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6758 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6759 "TARGET_FPU && TARGET_V9"
6763 "&& reload_completed
6764 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6765 [(set (match_dup 2) (neg:DF (match_dup 3)))
6766 (set (match_dup 4) (match_dup 5))]
6767 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6768 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6769 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6770 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6771 [(set_attr "type" "fpmove,*")
6772 (set_attr "length" "*,2")
6773 (set_attr "fptype" "double")])
6775 (define_expand "negdf2"
6776 [(set (match_operand:DF 0 "register_operand" "")
6777 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6781 (define_insn_and_split "*negdf2_notv9"
6782 [(set (match_operand:DF 0 "register_operand" "=e,e")
6783 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6784 "TARGET_FPU && ! TARGET_V9"
6788 "&& reload_completed
6789 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6790 [(set (match_dup 2) (neg:SF (match_dup 3)))
6791 (set (match_dup 4) (match_dup 5))]
6792 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6793 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6794 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6795 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6796 [(set_attr "type" "fpmove,*")
6797 (set_attr "length" "*,2")])
6799 (define_insn "*negdf2_v9"
6800 [(set (match_operand:DF 0 "register_operand" "=e")
6801 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6802 "TARGET_FPU && TARGET_V9"
6804 [(set_attr "type" "fpmove")
6805 (set_attr "fptype" "double")])
6807 (define_insn "negsf2"
6808 [(set (match_operand:SF 0 "register_operand" "=f")
6809 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6812 [(set_attr "type" "fpmove")])
6814 (define_expand "abstf2"
6815 [(set (match_operand:TF 0 "register_operand" "")
6816 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6820 (define_insn_and_split "*abstf2_notv9"
6821 [(set (match_operand:TF 0 "register_operand" "=e,e")
6822 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6823 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6824 "TARGET_FPU && ! TARGET_V9"
6828 "&& reload_completed
6829 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6830 [(set (match_dup 2) (abs:SF (match_dup 3)))
6831 (set (match_dup 4) (match_dup 5))
6832 (set (match_dup 6) (match_dup 7))]
6833 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6834 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6835 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6836 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6837 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6838 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6839 [(set_attr "type" "fpmove,*")
6840 (set_attr "length" "*,2")])
6842 (define_insn "*abstf2_hq_v9"
6843 [(set (match_operand:TF 0 "register_operand" "=e,e")
6844 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6845 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6849 [(set_attr "type" "fpmove")
6850 (set_attr "fptype" "double,*")])
6852 (define_insn_and_split "*abstf2_v9"
6853 [(set (match_operand:TF 0 "register_operand" "=e,e")
6854 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6855 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6859 "&& reload_completed
6860 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6861 [(set (match_dup 2) (abs:DF (match_dup 3)))
6862 (set (match_dup 4) (match_dup 5))]
6863 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6864 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6865 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6866 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6867 [(set_attr "type" "fpmove,*")
6868 (set_attr "length" "*,2")
6869 (set_attr "fptype" "double,*")])
6871 (define_expand "absdf2"
6872 [(set (match_operand:DF 0 "register_operand" "")
6873 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6877 (define_insn_and_split "*absdf2_notv9"
6878 [(set (match_operand:DF 0 "register_operand" "=e,e")
6879 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6880 "TARGET_FPU && ! TARGET_V9"
6884 "&& reload_completed
6885 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6886 [(set (match_dup 2) (abs:SF (match_dup 3)))
6887 (set (match_dup 4) (match_dup 5))]
6888 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6889 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6890 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6891 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6892 [(set_attr "type" "fpmove,*")
6893 (set_attr "length" "*,2")])
6895 (define_insn "*absdf2_v9"
6896 [(set (match_operand:DF 0 "register_operand" "=e")
6897 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6898 "TARGET_FPU && TARGET_V9"
6900 [(set_attr "type" "fpmove")
6901 (set_attr "fptype" "double")])
6903 (define_insn "abssf2"
6904 [(set (match_operand:SF 0 "register_operand" "=f")
6905 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6908 [(set_attr "type" "fpmove")])
6910 (define_expand "sqrttf2"
6911 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6912 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6913 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6914 "emit_tfmode_unop (SQRT, operands); DONE;")
6916 (define_insn "*sqrttf2_hq"
6917 [(set (match_operand:TF 0 "register_operand" "=e")
6918 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6919 "TARGET_FPU && TARGET_HARD_QUAD"
6921 [(set_attr "type" "fpsqrtd")])
6923 (define_insn "sqrtdf2"
6924 [(set (match_operand:DF 0 "register_operand" "=e")
6925 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6928 [(set_attr "type" "fpsqrtd")
6929 (set_attr "fptype" "double")])
6931 (define_insn "sqrtsf2"
6932 [(set (match_operand:SF 0 "register_operand" "=f")
6933 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6936 [(set_attr "type" "fpsqrts")])
6938 ;;- arithmetic shift instructions
6940 (define_insn "ashlsi3"
6941 [(set (match_operand:SI 0 "register_operand" "=r")
6942 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6943 (match_operand:SI 2 "arith_operand" "rI")))]
6946 if (operands[2] == const1_rtx)
6947 return "add\t%1, %1, %0";
6948 if (GET_CODE (operands[2]) == CONST_INT)
6949 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6950 return "sll\t%1, %2, %0";
6953 (if_then_else (match_operand 2 "const1_operand" "")
6954 (const_string "ialu") (const_string "shift")))])
6956 (define_expand "ashldi3"
6957 [(set (match_operand:DI 0 "register_operand" "=r")
6958 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6959 (match_operand:SI 2 "arith_operand" "rI")))]
6960 "TARGET_ARCH64 || TARGET_V8PLUS"
6962 if (! TARGET_ARCH64)
6964 if (GET_CODE (operands[2]) == CONST_INT)
6966 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6971 (define_insn "*ashldi3_sp64"
6972 [(set (match_operand:DI 0 "register_operand" "=r")
6973 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6974 (match_operand:SI 2 "arith_operand" "rI")))]
6977 if (operands[2] == const1_rtx)
6978 return "add\t%1, %1, %0";
6979 if (GET_CODE (operands[2]) == CONST_INT)
6980 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6981 return "sllx\t%1, %2, %0";
6984 (if_then_else (match_operand 2 "const1_operand" "")
6985 (const_string "ialu") (const_string "shift")))])
6988 (define_insn "ashldi3_v8plus"
6989 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6990 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6991 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6992 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6994 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6995 [(set_attr "type" "multi")
6996 (set_attr "length" "5,5,6")])
6998 ;; Optimize (1LL<<x)-1
6999 ;; XXX this also needs to be fixed to handle equal subregs
7000 ;; XXX first before we could re-enable it.
7002 ; [(set (match_operand:DI 0 "register_operand" "=h")
7003 ; (plus:DI (ashift:DI (const_int 1)
7004 ; (match_operand:SI 1 "arith_operand" "rI"))
7006 ; "0 && TARGET_V8PLUS"
7008 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7009 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7010 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7012 ; [(set_attr "type" "multi")
7013 ; (set_attr "length" "4")])
7015 (define_insn "*cmp_cc_ashift_1"
7016 [(set (reg:CC_NOOV 100)
7017 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7021 "addcc\t%0, %0, %%g0"
7022 [(set_attr "type" "compare")])
7024 (define_insn "*cmp_cc_set_ashift_1"
7025 [(set (reg:CC_NOOV 100)
7026 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7029 (set (match_operand:SI 0 "register_operand" "=r")
7030 (ashift:SI (match_dup 1) (const_int 1)))]
7033 [(set_attr "type" "compare")])
7035 (define_insn "ashrsi3"
7036 [(set (match_operand:SI 0 "register_operand" "=r")
7037 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7038 (match_operand:SI 2 "arith_operand" "rI")))]
7041 if (GET_CODE (operands[2]) == CONST_INT)
7042 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7043 return "sra\t%1, %2, %0";
7045 [(set_attr "type" "shift")])
7047 (define_insn "*ashrsi3_extend"
7048 [(set (match_operand:DI 0 "register_operand" "=r")
7049 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7050 (match_operand:SI 2 "arith_operand" "r"))))]
7053 [(set_attr "type" "shift")])
7055 ;; This handles the case as above, but with constant shift instead of
7056 ;; register. Combiner "simplifies" it for us a little bit though.
7057 (define_insn "*ashrsi3_extend2"
7058 [(set (match_operand:DI 0 "register_operand" "=r")
7059 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7061 (match_operand:SI 2 "small_int_or_double" "n")))]
7063 && ((GET_CODE (operands[2]) == CONST_INT
7064 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7065 || (GET_CODE (operands[2]) == CONST_DOUBLE
7066 && !CONST_DOUBLE_HIGH (operands[2])
7067 && CONST_DOUBLE_LOW (operands[2]) >= 32
7068 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7070 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7072 return "sra\t%1, %2, %0";
7074 [(set_attr "type" "shift")])
7076 (define_expand "ashrdi3"
7077 [(set (match_operand:DI 0 "register_operand" "=r")
7078 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7079 (match_operand:SI 2 "arith_operand" "rI")))]
7080 "TARGET_ARCH64 || TARGET_V8PLUS"
7082 if (! TARGET_ARCH64)
7084 if (GET_CODE (operands[2]) == CONST_INT)
7085 FAIL; /* prefer generic code in this case */
7086 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7091 (define_insn "*ashrdi3_sp64"
7092 [(set (match_operand:DI 0 "register_operand" "=r")
7093 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7094 (match_operand:SI 2 "arith_operand" "rI")))]
7098 if (GET_CODE (operands[2]) == CONST_INT)
7099 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7100 return "srax\t%1, %2, %0";
7102 [(set_attr "type" "shift")])
7105 (define_insn "ashrdi3_v8plus"
7106 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7107 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7108 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7109 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7111 "* return output_v8plus_shift (operands, insn, \"srax\");"
7112 [(set_attr "type" "multi")
7113 (set_attr "length" "5,5,6")])
7115 (define_insn "lshrsi3"
7116 [(set (match_operand:SI 0 "register_operand" "=r")
7117 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7118 (match_operand:SI 2 "arith_operand" "rI")))]
7121 if (GET_CODE (operands[2]) == CONST_INT)
7122 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7123 return "srl\t%1, %2, %0";
7125 [(set_attr "type" "shift")])
7127 ;; This handles the case where
7128 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7129 ;; but combiner "simplifies" it for us.
7130 (define_insn "*lshrsi3_extend"
7131 [(set (match_operand:DI 0 "register_operand" "=r")
7132 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7133 (match_operand:SI 2 "arith_operand" "r")) 0)
7134 (match_operand 3 "" "")))]
7136 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7137 && CONST_DOUBLE_HIGH (operands[3]) == 0
7138 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7139 || (HOST_BITS_PER_WIDE_INT >= 64
7140 && GET_CODE (operands[3]) == CONST_INT
7141 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7143 [(set_attr "type" "shift")])
7145 ;; This handles the case where
7146 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7147 ;; but combiner "simplifies" it for us.
7148 (define_insn "*lshrsi3_extend2"
7149 [(set (match_operand:DI 0 "register_operand" "=r")
7150 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7151 (match_operand 2 "small_int_or_double" "n")
7154 && ((GET_CODE (operands[2]) == CONST_INT
7155 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7156 || (GET_CODE (operands[2]) == CONST_DOUBLE
7157 && CONST_DOUBLE_HIGH (operands[2]) == 0
7158 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7160 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7162 return "srl\t%1, %2, %0";
7164 [(set_attr "type" "shift")])
7166 (define_expand "lshrdi3"
7167 [(set (match_operand:DI 0 "register_operand" "=r")
7168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7169 (match_operand:SI 2 "arith_operand" "rI")))]
7170 "TARGET_ARCH64 || TARGET_V8PLUS"
7172 if (! TARGET_ARCH64)
7174 if (GET_CODE (operands[2]) == CONST_INT)
7176 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7181 (define_insn "*lshrdi3_sp64"
7182 [(set (match_operand:DI 0 "register_operand" "=r")
7183 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7184 (match_operand:SI 2 "arith_operand" "rI")))]
7187 if (GET_CODE (operands[2]) == CONST_INT)
7188 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7189 return "srlx\t%1, %2, %0";
7191 [(set_attr "type" "shift")])
7194 (define_insn "lshrdi3_v8plus"
7195 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7196 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7197 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7198 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7200 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7201 [(set_attr "type" "multi")
7202 (set_attr "length" "5,5,6")])
7205 [(set (match_operand:SI 0 "register_operand" "=r")
7206 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7208 (match_operand:SI 2 "small_int_or_double" "n")))]
7210 && ((GET_CODE (operands[2]) == CONST_INT
7211 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7212 || (GET_CODE (operands[2]) == CONST_DOUBLE
7213 && !CONST_DOUBLE_HIGH (operands[2])
7214 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7216 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7218 return "srax\t%1, %2, %0";
7220 [(set_attr "type" "shift")])
7223 [(set (match_operand:SI 0 "register_operand" "=r")
7224 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7226 (match_operand:SI 2 "small_int_or_double" "n")))]
7228 && ((GET_CODE (operands[2]) == CONST_INT
7229 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7230 || (GET_CODE (operands[2]) == CONST_DOUBLE
7231 && !CONST_DOUBLE_HIGH (operands[2])
7232 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7234 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7236 return "srlx\t%1, %2, %0";
7238 [(set_attr "type" "shift")])
7241 [(set (match_operand:SI 0 "register_operand" "=r")
7242 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7243 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7244 (match_operand:SI 3 "small_int_or_double" "n")))]
7246 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7247 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7248 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7249 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7251 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7253 return "srax\t%1, %2, %0";
7255 [(set_attr "type" "shift")])
7258 [(set (match_operand:SI 0 "register_operand" "=r")
7259 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7260 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7261 (match_operand:SI 3 "small_int_or_double" "n")))]
7263 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7264 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7265 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7266 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7268 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7270 return "srlx\t%1, %2, %0";
7272 [(set_attr "type" "shift")])
7274 ;; Unconditional and other jump instructions
7275 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7276 ;; following insn is never executed. This saves us a nop. Dbx does not
7277 ;; handle such branches though, so we only use them when optimizing.
7279 [(set (pc) (label_ref (match_operand 0 "" "")))]
7282 /* TurboSPARC is reported to have problems with
7285 i.e. an empty loop with the annul bit set. The workaround is to use
7289 if (! TARGET_V9 && flag_delayed_branch
7290 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7291 == INSN_ADDRESSES (INSN_UID (insn))))
7294 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7296 [(set_attr "type" "uncond_branch")])
7298 (define_expand "tablejump"
7299 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7300 (use (label_ref (match_operand 1 "" "")))])]
7303 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7306 /* In pic mode, our address differences are against the base of the
7307 table. Add that base value back in; CSE ought to be able to combine
7308 the two address loads. */
7312 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7314 if (CASE_VECTOR_MODE != Pmode)
7315 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7316 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7317 operands[0] = memory_address (Pmode, tmp);
7321 (define_insn "*tablejump_sp32"
7322 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7323 (use (label_ref (match_operand 1 "" "")))]
7326 [(set_attr "type" "uncond_branch")])
7328 (define_insn "*tablejump_sp64"
7329 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7330 (use (label_ref (match_operand 1 "" "")))]
7333 [(set_attr "type" "uncond_branch")])
7335 ;;- jump to subroutine
7336 (define_expand "call"
7337 ;; Note that this expression is not used for generating RTL.
7338 ;; All the RTL is generated explicitly below.
7339 [(call (match_operand 0 "call_operand" "")
7340 (match_operand 3 "" "i"))]
7341 ;; operands[2] is next_arg_register
7342 ;; operands[3] is struct_value_size_rtx.
7347 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7350 if (GET_CODE (operands[3]) != CONST_INT)
7353 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7355 /* This is really a PIC sequence. We want to represent
7356 it as a funny jump so its delay slots can be filled.
7358 ??? But if this really *is* a CALL, will not it clobber the
7359 call-clobbered registers? We lose this if it is a JUMP_INSN.
7360 Why cannot we have delay slots filled if it were a CALL? */
7362 /* We accept negative sizes for untyped calls. */
7363 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7368 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7370 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7376 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7377 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7381 fn_rtx = operands[0];
7383 /* We accept negative sizes for untyped calls. */
7384 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7388 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7390 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7395 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7396 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7403 ;; We can't use the same pattern for these two insns, because then registers
7404 ;; in the address may not be properly reloaded.
7406 (define_insn "*call_address_sp32"
7407 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7408 (match_operand 1 "" ""))
7409 (clobber (reg:SI 15))]
7410 ;;- Do not use operand 1 for most machines.
7413 [(set_attr "type" "call")])
7415 (define_insn "*call_symbolic_sp32"
7416 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7417 (match_operand 1 "" ""))
7418 (clobber (reg:SI 15))]
7419 ;;- Do not use operand 1 for most machines.
7422 [(set_attr "type" "call")])
7424 (define_insn "*call_address_sp64"
7425 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7426 (match_operand 1 "" ""))
7427 (clobber (reg:DI 15))]
7428 ;;- Do not use operand 1 for most machines.
7431 [(set_attr "type" "call")])
7433 (define_insn "*call_symbolic_sp64"
7434 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7435 (match_operand 1 "" ""))
7436 (clobber (reg:DI 15))]
7437 ;;- Do not use operand 1 for most machines.
7440 [(set_attr "type" "call")])
7442 ;; This is a call that wants a structure value.
7443 ;; There is no such critter for v9 (??? we may need one anyway).
7444 (define_insn "*call_address_struct_value_sp32"
7445 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7446 (match_operand 1 "" ""))
7447 (match_operand 2 "immediate_operand" "")
7448 (clobber (reg:SI 15))]
7449 ;;- Do not use operand 1 for most machines.
7450 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7451 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7452 [(set_attr "type" "call_no_delay_slot")
7453 (set_attr "length" "3")])
7455 ;; This is a call that wants a structure value.
7456 ;; There is no such critter for v9 (??? we may need one anyway).
7457 (define_insn "*call_symbolic_struct_value_sp32"
7458 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7459 (match_operand 1 "" ""))
7460 (match_operand 2 "immediate_operand" "")
7461 (clobber (reg:SI 15))]
7462 ;;- Do not use operand 1 for most machines.
7463 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7464 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7465 [(set_attr "type" "call_no_delay_slot")
7466 (set_attr "length" "3")])
7468 ;; This is a call that may want a structure value. This is used for
7470 (define_insn "*call_address_untyped_struct_value_sp32"
7471 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7472 (match_operand 1 "" ""))
7473 (match_operand 2 "immediate_operand" "")
7474 (clobber (reg:SI 15))]
7475 ;;- Do not use operand 1 for most machines.
7476 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7477 "call\t%a0, %1\n\t nop\n\tnop"
7478 [(set_attr "type" "call_no_delay_slot")
7479 (set_attr "length" "3")])
7481 ;; This is a call that may want a structure value. This is used for
7483 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7484 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7485 (match_operand 1 "" ""))
7486 (match_operand 2 "immediate_operand" "")
7487 (clobber (reg:SI 15))]
7488 ;;- Do not use operand 1 for most machines.
7489 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7490 "call\t%a0, %1\n\t nop\n\tnop"
7491 [(set_attr "type" "call_no_delay_slot")
7492 (set_attr "length" "3")])
7494 (define_expand "call_value"
7495 ;; Note that this expression is not used for generating RTL.
7496 ;; All the RTL is generated explicitly below.
7497 [(set (match_operand 0 "register_operand" "=rf")
7498 (call (match_operand 1 "" "")
7499 (match_operand 4 "" "")))]
7500 ;; operand 2 is stack_size_rtx
7501 ;; operand 3 is next_arg_register
7507 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7510 fn_rtx = operands[1];
7513 gen_rtx_SET (VOIDmode, operands[0],
7514 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7515 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7517 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7522 (define_insn "*call_value_address_sp32"
7523 [(set (match_operand 0 "" "=rf")
7524 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7525 (match_operand 2 "" "")))
7526 (clobber (reg:SI 15))]
7527 ;;- Do not use operand 2 for most machines.
7530 [(set_attr "type" "call")])
7532 (define_insn "*call_value_symbolic_sp32"
7533 [(set (match_operand 0 "" "=rf")
7534 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7535 (match_operand 2 "" "")))
7536 (clobber (reg:SI 15))]
7537 ;;- Do not use operand 2 for most machines.
7540 [(set_attr "type" "call")])
7542 (define_insn "*call_value_address_sp64"
7543 [(set (match_operand 0 "" "")
7544 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7545 (match_operand 2 "" "")))
7546 (clobber (reg:DI 15))]
7547 ;;- Do not use operand 2 for most machines.
7550 [(set_attr "type" "call")])
7552 (define_insn "*call_value_symbolic_sp64"
7553 [(set (match_operand 0 "" "")
7554 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7555 (match_operand 2 "" "")))
7556 (clobber (reg:DI 15))]
7557 ;;- Do not use operand 2 for most machines.
7560 [(set_attr "type" "call")])
7562 (define_expand "untyped_call"
7563 [(parallel [(call (match_operand 0 "" "")
7565 (match_operand 1 "" "")
7566 (match_operand 2 "" "")])]
7571 /* Pass constm1 to indicate that it may expect a structure value, but
7572 we don't know what size it is. */
7573 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7575 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7577 rtx set = XVECEXP (operands[2], 0, i);
7578 emit_move_insn (SET_DEST (set), SET_SRC (set));
7581 /* The optimizer does not know that the call sets the function value
7582 registers we stored in the result block. We avoid problems by
7583 claiming that all hard registers are used and clobbered at this
7585 emit_insn (gen_blockage ());
7591 (define_expand "sibcall"
7592 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7597 (define_insn "*sibcall_symbolic_sp32"
7598 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7599 (match_operand 1 "" ""))
7602 "* return output_sibcall(insn, operands[0]);"
7603 [(set_attr "type" "sibcall")])
7605 (define_insn "*sibcall_symbolic_sp64"
7606 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7607 (match_operand 1 "" ""))
7610 "* return output_sibcall(insn, operands[0]);"
7611 [(set_attr "type" "sibcall")])
7613 (define_expand "sibcall_value"
7614 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7615 (call (match_operand 1 "" "") (const_int 0)))
7620 (define_insn "*sibcall_value_symbolic_sp32"
7621 [(set (match_operand 0 "" "=rf")
7622 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7623 (match_operand 2 "" "")))
7626 "* return output_sibcall(insn, operands[1]);"
7627 [(set_attr "type" "sibcall")])
7629 (define_insn "*sibcall_value_symbolic_sp64"
7630 [(set (match_operand 0 "" "")
7631 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7632 (match_operand 2 "" "")))
7635 "* return output_sibcall(insn, operands[1]);"
7636 [(set_attr "type" "sibcall")])
7638 (define_expand "sibcall_epilogue"
7642 sparc_expand_epilogue ();
7646 (define_expand "prologue"
7650 sparc_expand_prologue ();
7654 (define_expand "save_register_window"
7655 [(use (match_operand 0 "arith_operand" ""))]
7661 gen_rtx_SET (VOIDmode,
7663 gen_rtx_PLUS (Pmode,
7664 hard_frame_pointer_rtx,
7666 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7667 gen_rtvec (1, const0_rtx),
7670 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7674 (define_insn "*save_register_windowsi"
7675 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7676 (match_operand:SI 0 "arith_operand" "rI")))
7677 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7679 "save\t%%sp, %0, %%sp"
7680 [(set_attr "type" "savew")])
7682 (define_insn "*save_register_windowdi"
7683 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7684 (match_operand:DI 0 "arith_operand" "rI")))
7685 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7687 "save\t%%sp, %0, %%sp"
7688 [(set_attr "type" "savew")])
7690 (define_expand "epilogue"
7694 sparc_expand_epilogue ();
7697 (define_insn "*return_internal"
7700 "* return output_return (insn);"
7701 [(set_attr "type" "return")
7702 (set_attr "length" "2")])
7704 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7705 ;; all of memory. This blocks insns from being moved across this point.
7707 (define_insn "blockage"
7708 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7711 [(set_attr "length" "0")])
7713 ;; Prepare to return any type including a structure value.
7715 (define_expand "untyped_return"
7716 [(match_operand:BLK 0 "memory_operand" "")
7717 (match_operand 1 "" "")]
7720 rtx valreg1 = gen_rtx_REG (DImode, 24);
7721 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7722 rtx result = operands[0];
7724 if (! TARGET_ARCH64)
7726 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7728 rtx value = gen_reg_rtx (SImode);
7730 /* Fetch the instruction where we will return to and see if it's an unimp
7731 instruction (the most significant 10 bits will be zero). If so,
7732 update the return address to skip the unimp instruction. */
7733 emit_move_insn (value,
7734 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7735 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7736 emit_insn (gen_update_return (rtnreg, value));
7739 /* Reload the function value registers. */
7740 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7741 emit_move_insn (valreg2,
7742 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7744 /* Put USE insns before the return. */
7745 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7746 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7748 /* Construct the return. */
7749 expand_naked_return ();
7754 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7755 ;; and parts of the compiler don't want to believe that the add is needed.
7757 (define_insn "update_return"
7758 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7759 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7762 if (flag_delayed_branch)
7763 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7765 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7767 [(set (attr "type") (const_string "multi"))
7768 (set (attr "length")
7769 (if_then_else (eq_attr "delayed_branch" "true")
7778 (define_expand "indirect_jump"
7779 [(set (pc) (match_operand 0 "address_operand" "p"))]
7783 (define_insn "*branch_sp32"
7784 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7787 [(set_attr "type" "uncond_branch")])
7789 (define_insn "*branch_sp64"
7790 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7793 [(set_attr "type" "uncond_branch")])
7795 (define_expand "nonlocal_goto"
7796 [(match_operand:SI 0 "general_operand" "")
7797 (match_operand:SI 1 "general_operand" "")
7798 (match_operand:SI 2 "general_operand" "")
7799 (match_operand:SI 3 "" "")]
7802 rtx lab = operands[1];
7803 rtx stack = operands[2];
7804 rtx fp = operands[3];
7807 /* Trap instruction to flush all the register windows. */
7808 emit_insn (gen_flush_register_windows ());
7810 /* Load the fp value for the containing fn into %fp. This is needed
7811 because STACK refers to %fp. Note that virtual register instantiation
7812 fails if the virtual %fp isn't set from a register. */
7813 if (GET_CODE (fp) != REG)
7814 fp = force_reg (Pmode, fp);
7815 emit_move_insn (virtual_stack_vars_rtx, fp);
7817 /* Find the containing function's current nonlocal goto handler,
7818 which will do any cleanups and then jump to the label. */
7819 labreg = gen_rtx_REG (Pmode, 8);
7820 emit_move_insn (labreg, lab);
7822 /* Restore %fp from stack pointer value for containing function.
7823 The restore insn that follows will move this to %sp,
7824 and reload the appropriate value into %fp. */
7825 emit_move_insn (hard_frame_pointer_rtx, stack);
7827 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7828 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7830 /* ??? The V9-specific version was disabled in rev 1.65. */
7831 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7836 ;; Special trap insn to flush register windows.
7837 (define_insn "flush_register_windows"
7838 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7840 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7841 [(set_attr "type" "flushw")])
7843 (define_insn "goto_handler_and_restore"
7844 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7845 "GET_MODE (operands[0]) == Pmode"
7847 if (flag_delayed_branch)
7848 return "jmp\t%0\n\t restore";
7850 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7852 [(set (attr "type") (const_string "multi"))
7853 (set (attr "length")
7854 (if_then_else (eq_attr "delayed_branch" "true")
7858 ;; For __builtin_setjmp we need to flush register windows iff the function
7859 ;; calls alloca as well, because otherwise the register window might be
7860 ;; saved after %sp adjustment and thus setjmp would crash
7861 (define_expand "builtin_setjmp_setup"
7862 [(match_operand 0 "register_operand" "r")]
7865 emit_insn (gen_do_builtin_setjmp_setup ());
7869 (define_insn "do_builtin_setjmp_setup"
7870 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7873 if (! current_function_calls_alloca)
7877 fputs ("\tflushw\n", asm_out_file);
7879 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7880 TARGET_ARCH64 ? 'x' : 'w',
7881 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7882 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7883 TARGET_ARCH64 ? 'x' : 'w',
7884 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7885 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7886 TARGET_ARCH64 ? 'x' : 'w',
7887 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7890 [(set_attr "type" "multi")
7891 (set (attr "length")
7892 (cond [(eq_attr "current_function_calls_alloca" "false")
7894 (eq_attr "isa" "!v9")
7896 (eq_attr "pic" "true")
7897 (const_int 4)] (const_int 3)))])
7899 ;; Pattern for use after a setjmp to store FP and the return register
7900 ;; into the stack area.
7902 (define_expand "setjmp"
7907 emit_insn (gen_setjmp_64 ());
7909 emit_insn (gen_setjmp_32 ());
7913 (define_expand "setjmp_32"
7914 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7915 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7917 { operands[0] = frame_pointer_rtx; })
7919 (define_expand "setjmp_64"
7920 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7921 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7923 { operands[0] = frame_pointer_rtx; })
7925 ;; Special pattern for the FLUSH instruction.
7927 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7928 ; of the define_insn otherwise missing a mode. We make "flush", aka
7929 ; gen_flush, the default one since sparc_initialize_trampoline uses
7930 ; it on SImode mem values.
7932 (define_insn "flush"
7933 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7935 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7936 [(set_attr "type" "iflush")])
7938 (define_insn "flushdi"
7939 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7941 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7942 [(set_attr "type" "iflush")])
7947 ;; The scan instruction searches from the most significant bit while ffs
7948 ;; searches from the least significant bit. The bit index and treatment of
7949 ;; zero also differ. It takes at least 7 instructions to get the proper
7950 ;; result. Here is an obvious 8 instruction sequence.
7953 (define_insn "ffssi2"
7954 [(set (match_operand:SI 0 "register_operand" "=&r")
7955 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7956 (clobber (match_scratch:SI 2 "=&r"))]
7957 "TARGET_SPARCLITE || TARGET_SPARCLET"
7959 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";
7961 [(set_attr "type" "multi")
7962 (set_attr "length" "8")])
7964 ;; ??? This should be a define expand, so that the extra instruction have
7965 ;; a chance of being optimized away.
7967 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7968 ;; does, but no one uses that and we don't have a switch for it.
7970 ;(define_insn "ffsdi2"
7971 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7972 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7973 ; (clobber (match_scratch:DI 2 "=&r"))]
7975 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7976 ; [(set_attr "type" "multi")
7977 ; (set_attr "length" "4")])
7981 ;; Peepholes go at the end.
7983 ;; Optimize consecutive loads or stores into ldd and std when possible.
7984 ;; The conditions in which we do this are very restricted and are
7985 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7988 [(set (match_operand:SI 0 "memory_operand" "")
7990 (set (match_operand:SI 1 "memory_operand" "")
7993 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7996 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7999 [(set (match_operand:SI 0 "memory_operand" "")
8001 (set (match_operand:SI 1 "memory_operand" "")
8004 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8007 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8010 [(set (match_operand:SI 0 "register_operand" "")
8011 (match_operand:SI 1 "memory_operand" ""))
8012 (set (match_operand:SI 2 "register_operand" "")
8013 (match_operand:SI 3 "memory_operand" ""))]
8014 "registers_ok_for_ldd_peep (operands[0], operands[2])
8015 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8018 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8019 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8022 [(set (match_operand:SI 0 "memory_operand" "")
8023 (match_operand:SI 1 "register_operand" ""))
8024 (set (match_operand:SI 2 "memory_operand" "")
8025 (match_operand:SI 3 "register_operand" ""))]
8026 "registers_ok_for_ldd_peep (operands[1], operands[3])
8027 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8030 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8031 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8034 [(set (match_operand:SF 0 "register_operand" "")
8035 (match_operand:SF 1 "memory_operand" ""))
8036 (set (match_operand:SF 2 "register_operand" "")
8037 (match_operand:SF 3 "memory_operand" ""))]
8038 "registers_ok_for_ldd_peep (operands[0], operands[2])
8039 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8042 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8043 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8046 [(set (match_operand:SF 0 "memory_operand" "")
8047 (match_operand:SF 1 "register_operand" ""))
8048 (set (match_operand:SF 2 "memory_operand" "")
8049 (match_operand:SF 3 "register_operand" ""))]
8050 "registers_ok_for_ldd_peep (operands[1], operands[3])
8051 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8054 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8055 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8058 [(set (match_operand:SI 0 "register_operand" "")
8059 (match_operand:SI 1 "memory_operand" ""))
8060 (set (match_operand:SI 2 "register_operand" "")
8061 (match_operand:SI 3 "memory_operand" ""))]
8062 "registers_ok_for_ldd_peep (operands[2], operands[0])
8063 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8066 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8067 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8070 [(set (match_operand:SI 0 "memory_operand" "")
8071 (match_operand:SI 1 "register_operand" ""))
8072 (set (match_operand:SI 2 "memory_operand" "")
8073 (match_operand:SI 3 "register_operand" ""))]
8074 "registers_ok_for_ldd_peep (operands[3], operands[1])
8075 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8078 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8079 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8083 [(set (match_operand:SF 0 "register_operand" "")
8084 (match_operand:SF 1 "memory_operand" ""))
8085 (set (match_operand:SF 2 "register_operand" "")
8086 (match_operand:SF 3 "memory_operand" ""))]
8087 "registers_ok_for_ldd_peep (operands[2], operands[0])
8088 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8091 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8092 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8095 [(set (match_operand:SF 0 "memory_operand" "")
8096 (match_operand:SF 1 "register_operand" ""))
8097 (set (match_operand:SF 2 "memory_operand" "")
8098 (match_operand:SF 3 "register_operand" ""))]
8099 "registers_ok_for_ldd_peep (operands[3], operands[1])
8100 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8103 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8104 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8106 ;; Optimize the case of following a reg-reg move with a test
8107 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8108 ;; This can result from a float to fix conversion.
8111 [(set (match_operand:SI 0 "register_operand" "")
8112 (match_operand:SI 1 "register_operand" ""))
8114 (compare:CC (match_operand:SI 2 "register_operand" "")
8116 "(rtx_equal_p (operands[2], operands[0])
8117 || rtx_equal_p (operands[2], operands[1]))
8118 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8119 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8120 [(parallel [(set (match_dup 0) (match_dup 1))
8122 (compare:CC (match_dup 1) (const_int 0)))])]
8126 [(set (match_operand:DI 0 "register_operand" "")
8127 (match_operand:DI 1 "register_operand" ""))
8129 (compare:CCX (match_operand:DI 2 "register_operand" "")
8132 && (rtx_equal_p (operands[2], operands[0])
8133 || rtx_equal_p (operands[2], operands[1]))
8134 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8135 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8136 [(parallel [(set (match_dup 0) (match_dup 1))
8138 (compare:CCX (match_dup 1) (const_int 0)))])]
8141 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8142 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8143 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8145 (define_expand "prefetch"
8146 [(match_operand 0 "address_operand" "")
8147 (match_operand 1 "const_int_operand" "")
8148 (match_operand 2 "const_int_operand" "")]
8152 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8154 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8158 (define_insn "prefetch_64"
8159 [(prefetch (match_operand:DI 0 "address_operand" "p")
8160 (match_operand:DI 1 "const_int_operand" "n")
8161 (match_operand:DI 2 "const_int_operand" "n"))]
8164 static const char * const prefetch_instr[2][2] = {
8166 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8167 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8170 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8171 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8174 int read_or_write = INTVAL (operands[1]);
8175 int locality = INTVAL (operands[2]);
8177 if (read_or_write != 0 && read_or_write != 1)
8179 if (locality < 0 || locality > 3)
8181 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8183 [(set_attr "type" "load")])
8185 (define_insn "prefetch_32"
8186 [(prefetch (match_operand:SI 0 "address_operand" "p")
8187 (match_operand:SI 1 "const_int_operand" "n")
8188 (match_operand:SI 2 "const_int_operand" "n"))]
8191 static const char * const prefetch_instr[2][2] = {
8193 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8194 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8197 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8198 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8201 int read_or_write = INTVAL (operands[1]);
8202 int locality = INTVAL (operands[2]);
8204 if (read_or_write != 0 && read_or_write != 1)
8206 if (locality < 0 || locality > 3)
8208 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8210 [(set_attr "type" "load")])
8213 [(trap_if (const_int 1) (const_int 5))]
8216 [(set_attr "type" "trap")])
8218 (define_expand "conditional_trap"
8219 [(trap_if (match_operator 0 "noov_compare_op"
8220 [(match_dup 2) (match_dup 3)])
8221 (match_operand:SI 1 "arith_operand" ""))]
8223 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8224 sparc_compare_op0, sparc_compare_op1);
8225 operands[3] = const0_rtx;")
8228 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8229 (match_operand:SI 1 "arith_operand" "rM"))]
8232 [(set_attr "type" "trap")])
8235 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8236 (match_operand:SI 1 "arith_operand" "rM"))]
8239 [(set_attr "type" "trap")])
8242 (define_insn "tgd_hi22"
8243 [(set (match_operand:SI 0 "register_operand" "=r")
8244 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8247 "sethi\\t%%tgd_hi22(%a1), %0")
8249 (define_insn "tgd_lo10"
8250 [(set (match_operand:SI 0 "register_operand" "=r")
8251 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8252 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8255 "add\\t%1, %%tgd_lo10(%a2), %0")
8257 (define_insn "tgd_add32"
8258 [(set (match_operand:SI 0 "register_operand" "=r")
8259 (plus:SI (match_operand:SI 1 "register_operand" "r")
8260 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8261 (match_operand 3 "tgd_symbolic_operand" "")]
8263 "TARGET_TLS && TARGET_ARCH32"
8264 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8266 (define_insn "tgd_add64"
8267 [(set (match_operand:DI 0 "register_operand" "=r")
8268 (plus:DI (match_operand:DI 1 "register_operand" "r")
8269 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8270 (match_operand 3 "tgd_symbolic_operand" "")]
8272 "TARGET_TLS && TARGET_ARCH64"
8273 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8275 (define_insn "tgd_call32"
8276 [(set (match_operand 0 "register_operand" "=r")
8277 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8278 (match_operand 2 "tgd_symbolic_operand" "")]
8280 (match_operand 3 "" "")))
8281 (clobber (reg:SI 15))]
8282 "TARGET_TLS && TARGET_ARCH32"
8283 "call\t%a1, %%tgd_call(%a2)%#"
8284 [(set_attr "type" "call")])
8286 (define_insn "tgd_call64"
8287 [(set (match_operand 0 "register_operand" "=r")
8288 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8289 (match_operand 2 "tgd_symbolic_operand" "")]
8291 (match_operand 3 "" "")))
8292 (clobber (reg:DI 15))]
8293 "TARGET_TLS && TARGET_ARCH64"
8294 "call\t%a1, %%tgd_call(%a2)%#"
8295 [(set_attr "type" "call")])
8297 (define_insn "tldm_hi22"
8298 [(set (match_operand:SI 0 "register_operand" "=r")
8299 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8301 "sethi\\t%%tldm_hi22(%&), %0")
8303 (define_insn "tldm_lo10"
8304 [(set (match_operand:SI 0 "register_operand" "=r")
8305 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8306 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8308 "add\\t%1, %%tldm_lo10(%&), %0")
8310 (define_insn "tldm_add32"
8311 [(set (match_operand:SI 0 "register_operand" "=r")
8312 (plus:SI (match_operand:SI 1 "register_operand" "r")
8313 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8315 "TARGET_TLS && TARGET_ARCH32"
8316 "add\\t%1, %2, %0, %%tldm_add(%&)")
8318 (define_insn "tldm_add64"
8319 [(set (match_operand:DI 0 "register_operand" "=r")
8320 (plus:DI (match_operand:DI 1 "register_operand" "r")
8321 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8323 "TARGET_TLS && TARGET_ARCH64"
8324 "add\\t%1, %2, %0, %%tldm_add(%&)")
8326 (define_insn "tldm_call32"
8327 [(set (match_operand 0 "register_operand" "=r")
8328 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8330 (match_operand 2 "" "")))
8331 (clobber (reg:SI 15))]
8332 "TARGET_TLS && TARGET_ARCH32"
8333 "call\t%a1, %%tldm_call(%&)%#"
8334 [(set_attr "type" "call")])
8336 (define_insn "tldm_call64"
8337 [(set (match_operand 0 "register_operand" "=r")
8338 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8340 (match_operand 2 "" "")))
8341 (clobber (reg:DI 15))]
8342 "TARGET_TLS && TARGET_ARCH64"
8343 "call\t%a1, %%tldm_call(%&)%#"
8344 [(set_attr "type" "call")])
8346 (define_insn "tldo_hix22"
8347 [(set (match_operand:SI 0 "register_operand" "=r")
8348 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8351 "sethi\\t%%tldo_hix22(%a1), %0")
8353 (define_insn "tldo_lox10"
8354 [(set (match_operand:SI 0 "register_operand" "=r")
8355 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8356 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8359 "xor\\t%1, %%tldo_lox10(%a2), %0")
8361 (define_insn "tldo_add32"
8362 [(set (match_operand:SI 0 "register_operand" "=r")
8363 (plus:SI (match_operand:SI 1 "register_operand" "r")
8364 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8365 (match_operand 3 "tld_symbolic_operand" "")]
8367 "TARGET_TLS && TARGET_ARCH32"
8368 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8370 (define_insn "tldo_add64"
8371 [(set (match_operand:DI 0 "register_operand" "=r")
8372 (plus:DI (match_operand:DI 1 "register_operand" "r")
8373 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8374 (match_operand 3 "tld_symbolic_operand" "")]
8376 "TARGET_TLS && TARGET_ARCH64"
8377 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8379 (define_insn "tie_hi22"
8380 [(set (match_operand:SI 0 "register_operand" "=r")
8381 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8384 "sethi\\t%%tie_hi22(%a1), %0")
8386 (define_insn "tie_lo10"
8387 [(set (match_operand:SI 0 "register_operand" "=r")
8388 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8389 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8392 "add\\t%1, %%tie_lo10(%a2), %0")
8394 (define_insn "tie_ld32"
8395 [(set (match_operand:SI 0 "register_operand" "=r")
8396 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8397 (match_operand:SI 2 "register_operand" "r")
8398 (match_operand 3 "tie_symbolic_operand" "")]
8400 "TARGET_TLS && TARGET_ARCH32"
8401 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8402 [(set_attr "type" "load")])
8404 (define_insn "tie_ld64"
8405 [(set (match_operand:DI 0 "register_operand" "=r")
8406 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8407 (match_operand:SI 2 "register_operand" "r")
8408 (match_operand 3 "tie_symbolic_operand" "")]
8410 "TARGET_TLS && TARGET_ARCH64"
8411 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8412 [(set_attr "type" "load")])
8414 (define_insn "tie_add32"
8415 [(set (match_operand:SI 0 "register_operand" "=r")
8416 (plus:SI (match_operand:SI 1 "register_operand" "r")
8417 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8418 (match_operand 3 "tie_symbolic_operand" "")]
8420 "TARGET_SUN_TLS && TARGET_ARCH32"
8421 "add\\t%1, %2, %0, %%tie_add(%a3)")
8423 (define_insn "tie_add64"
8424 [(set (match_operand:DI 0 "register_operand" "=r")
8425 (plus:DI (match_operand:DI 1 "register_operand" "r")
8426 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8427 (match_operand 3 "tie_symbolic_operand" "")]
8429 "TARGET_SUN_TLS && TARGET_ARCH64"
8430 "add\\t%1, %2, %0, %%tie_add(%a3)")
8432 (define_insn "tle_hix22_sp32"
8433 [(set (match_operand:SI 0 "register_operand" "=r")
8434 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8436 "TARGET_TLS && TARGET_ARCH32"
8437 "sethi\\t%%tle_hix22(%a1), %0")
8439 (define_insn "tle_lox10_sp32"
8440 [(set (match_operand:SI 0 "register_operand" "=r")
8441 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8442 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8444 "TARGET_TLS && TARGET_ARCH32"
8445 "xor\\t%1, %%tle_lox10(%a2), %0")
8447 (define_insn "tle_hix22_sp64"
8448 [(set (match_operand:DI 0 "register_operand" "=r")
8449 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8451 "TARGET_TLS && TARGET_ARCH64"
8452 "sethi\\t%%tle_hix22(%a1), %0")
8454 (define_insn "tle_lox10_sp64"
8455 [(set (match_operand:DI 0 "register_operand" "=r")
8456 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8457 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8459 "TARGET_TLS && TARGET_ARCH64"
8460 "xor\\t%1, %%tle_lox10(%a2), %0")
8462 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8463 (define_insn "*tldo_ldub_sp32"
8464 [(set (match_operand:QI 0 "register_operand" "=r")
8465 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8466 (match_operand 3 "tld_symbolic_operand" "")]
8468 (match_operand:SI 1 "register_operand" "r"))))]
8469 "TARGET_TLS && TARGET_ARCH32"
8470 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8471 [(set_attr "type" "load")
8472 (set_attr "us3load_type" "3cycle")])
8474 (define_insn "*tldo_ldub1_sp32"
8475 [(set (match_operand:HI 0 "register_operand" "=r")
8476 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8477 (match_operand 3 "tld_symbolic_operand" "")]
8479 (match_operand:SI 1 "register_operand" "r")))))]
8480 "TARGET_TLS && TARGET_ARCH32"
8481 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8482 [(set_attr "type" "load")
8483 (set_attr "us3load_type" "3cycle")])
8485 (define_insn "*tldo_ldub2_sp32"
8486 [(set (match_operand:SI 0 "register_operand" "=r")
8487 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8488 (match_operand 3 "tld_symbolic_operand" "")]
8490 (match_operand:SI 1 "register_operand" "r")))))]
8491 "TARGET_TLS && TARGET_ARCH32"
8492 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8493 [(set_attr "type" "load")
8494 (set_attr "us3load_type" "3cycle")])
8496 (define_insn "*tldo_ldsb1_sp32"
8497 [(set (match_operand:HI 0 "register_operand" "=r")
8498 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8499 (match_operand 3 "tld_symbolic_operand" "")]
8501 (match_operand:SI 1 "register_operand" "r")))))]
8502 "TARGET_TLS && TARGET_ARCH32"
8503 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8504 [(set_attr "type" "sload")
8505 (set_attr "us3load_type" "3cycle")])
8507 (define_insn "*tldo_ldsb2_sp32"
8508 [(set (match_operand:SI 0 "register_operand" "=r")
8509 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8510 (match_operand 3 "tld_symbolic_operand" "")]
8512 (match_operand:SI 1 "register_operand" "r")))))]
8513 "TARGET_TLS && TARGET_ARCH32"
8514 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8515 [(set_attr "type" "sload")
8516 (set_attr "us3load_type" "3cycle")])
8518 (define_insn "*tldo_ldub_sp64"
8519 [(set (match_operand:QI 0 "register_operand" "=r")
8520 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8521 (match_operand 3 "tld_symbolic_operand" "")]
8523 (match_operand:DI 1 "register_operand" "r"))))]
8524 "TARGET_TLS && TARGET_ARCH64"
8525 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8526 [(set_attr "type" "load")
8527 (set_attr "us3load_type" "3cycle")])
8529 (define_insn "*tldo_ldub1_sp64"
8530 [(set (match_operand:HI 0 "register_operand" "=r")
8531 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8532 (match_operand 3 "tld_symbolic_operand" "")]
8534 (match_operand:DI 1 "register_operand" "r")))))]
8535 "TARGET_TLS && TARGET_ARCH64"
8536 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8537 [(set_attr "type" "load")
8538 (set_attr "us3load_type" "3cycle")])
8540 (define_insn "*tldo_ldub2_sp64"
8541 [(set (match_operand:SI 0 "register_operand" "=r")
8542 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8543 (match_operand 3 "tld_symbolic_operand" "")]
8545 (match_operand:DI 1 "register_operand" "r")))))]
8546 "TARGET_TLS && TARGET_ARCH64"
8547 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8548 [(set_attr "type" "load")
8549 (set_attr "us3load_type" "3cycle")])
8551 (define_insn "*tldo_ldub3_sp64"
8552 [(set (match_operand:DI 0 "register_operand" "=r")
8553 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8554 (match_operand 3 "tld_symbolic_operand" "")]
8556 (match_operand:DI 1 "register_operand" "r")))))]
8557 "TARGET_TLS && TARGET_ARCH64"
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_sp64"
8563 [(set (match_operand:HI 0 "register_operand" "=r")
8564 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8565 (match_operand 3 "tld_symbolic_operand" "")]
8567 (match_operand:DI 1 "register_operand" "r")))))]
8568 "TARGET_TLS && TARGET_ARCH64"
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_sp64"
8574 [(set (match_operand:SI 0 "register_operand" "=r")
8575 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8576 (match_operand 3 "tld_symbolic_operand" "")]
8578 (match_operand:DI 1 "register_operand" "r")))))]
8579 "TARGET_TLS && TARGET_ARCH64"
8580 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8581 [(set_attr "type" "sload")
8582 (set_attr "us3load_type" "3cycle")])
8584 (define_insn "*tldo_ldsb3_sp64"
8585 [(set (match_operand:DI 0 "register_operand" "=r")
8586 (sign_extend:DI (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 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8592 [(set_attr "type" "sload")
8593 (set_attr "us3load_type" "3cycle")])
8595 (define_insn "*tldo_lduh_sp32"
8596 [(set (match_operand:HI 0 "register_operand" "=r")
8597 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8598 (match_operand 3 "tld_symbolic_operand" "")]
8600 (match_operand:SI 1 "register_operand" "r"))))]
8601 "TARGET_TLS && TARGET_ARCH32"
8602 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8603 [(set_attr "type" "load")
8604 (set_attr "us3load_type" "3cycle")])
8606 (define_insn "*tldo_lduh1_sp32"
8607 [(set (match_operand:SI 0 "register_operand" "=r")
8608 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8609 (match_operand 3 "tld_symbolic_operand" "")]
8611 (match_operand:SI 1 "register_operand" "r")))))]
8612 "TARGET_TLS && TARGET_ARCH32"
8613 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8614 [(set_attr "type" "load")
8615 (set_attr "us3load_type" "3cycle")])
8617 (define_insn "*tldo_ldsh1_sp32"
8618 [(set (match_operand:SI 0 "register_operand" "=r")
8619 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8620 (match_operand 3 "tld_symbolic_operand" "")]
8622 (match_operand:SI 1 "register_operand" "r")))))]
8623 "TARGET_TLS && TARGET_ARCH32"
8624 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8625 [(set_attr "type" "sload")
8626 (set_attr "us3load_type" "3cycle")])
8628 (define_insn "*tldo_lduh_sp64"
8629 [(set (match_operand:HI 0 "register_operand" "=r")
8630 (mem:HI (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 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8636 [(set_attr "type" "load")
8637 (set_attr "us3load_type" "3cycle")])
8639 (define_insn "*tldo_lduh1_sp64"
8640 [(set (match_operand:SI 0 "register_operand" "=r")
8641 (zero_extend:SI (mem:HI (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 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8647 [(set_attr "type" "load")
8648 (set_attr "us3load_type" "3cycle")])
8650 (define_insn "*tldo_lduh2_sp64"
8651 [(set (match_operand:DI 0 "register_operand" "=r")
8652 (zero_extend:DI (mem:HI (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 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8658 [(set_attr "type" "load")
8659 (set_attr "us3load_type" "3cycle")])
8661 (define_insn "*tldo_ldsh1_sp64"
8662 [(set (match_operand:SI 0 "register_operand" "=r")
8663 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8664 (match_operand 3 "tld_symbolic_operand" "")]
8666 (match_operand:DI 1 "register_operand" "r")))))]
8667 "TARGET_TLS && TARGET_ARCH64"
8668 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8669 [(set_attr "type" "sload")
8670 (set_attr "us3load_type" "3cycle")])
8672 (define_insn "*tldo_ldsh2_sp64"
8673 [(set (match_operand:DI 0 "register_operand" "=r")
8674 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8675 (match_operand 3 "tld_symbolic_operand" "")]
8677 (match_operand:DI 1 "register_operand" "r")))))]
8678 "TARGET_TLS && TARGET_ARCH64"
8679 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8680 [(set_attr "type" "sload")
8681 (set_attr "us3load_type" "3cycle")])
8683 (define_insn "*tldo_lduw_sp32"
8684 [(set (match_operand:SI 0 "register_operand" "=r")
8685 (mem:SI (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 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8691 [(set_attr "type" "load")])
8693 (define_insn "*tldo_lduw_sp64"
8694 [(set (match_operand:SI 0 "register_operand" "=r")
8695 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8696 (match_operand 3 "tld_symbolic_operand" "")]
8698 (match_operand:DI 1 "register_operand" "r"))))]
8699 "TARGET_TLS && TARGET_ARCH64"
8700 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8701 [(set_attr "type" "load")])
8703 (define_insn "*tldo_lduw1_sp64"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8705 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8706 (match_operand 3 "tld_symbolic_operand" "")]
8708 (match_operand:DI 1 "register_operand" "r")))))]
8709 "TARGET_TLS && TARGET_ARCH64"
8710 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8711 [(set_attr "type" "load")])
8713 (define_insn "*tldo_ldsw1_sp64"
8714 [(set (match_operand:DI 0 "register_operand" "=r")
8715 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8716 (match_operand 3 "tld_symbolic_operand" "")]
8718 (match_operand:DI 1 "register_operand" "r")))))]
8719 "TARGET_TLS && TARGET_ARCH64"
8720 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8721 [(set_attr "type" "sload")
8722 (set_attr "us3load_type" "3cycle")])
8724 (define_insn "*tldo_ldx_sp64"
8725 [(set (match_operand:DI 0 "register_operand" "=r")
8726 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8727 (match_operand 3 "tld_symbolic_operand" "")]
8729 (match_operand:DI 1 "register_operand" "r"))))]
8730 "TARGET_TLS && TARGET_ARCH64"
8731 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8732 [(set_attr "type" "load")])
8734 (define_insn "*tldo_stb_sp32"
8735 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8736 (match_operand 3 "tld_symbolic_operand" "")]
8738 (match_operand:SI 1 "register_operand" "r")))
8739 (match_operand:QI 0 "register_operand" "=r"))]
8740 "TARGET_TLS && TARGET_ARCH32"
8741 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8742 [(set_attr "type" "store")])
8744 (define_insn "*tldo_stb_sp64"
8745 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8746 (match_operand 3 "tld_symbolic_operand" "")]
8748 (match_operand:DI 1 "register_operand" "r")))
8749 (match_operand:QI 0 "register_operand" "=r"))]
8750 "TARGET_TLS && TARGET_ARCH64"
8751 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8752 [(set_attr "type" "store")])
8754 (define_insn "*tldo_sth_sp32"
8755 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8756 (match_operand 3 "tld_symbolic_operand" "")]
8758 (match_operand:SI 1 "register_operand" "r")))
8759 (match_operand:HI 0 "register_operand" "=r"))]
8760 "TARGET_TLS && TARGET_ARCH32"
8761 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8762 [(set_attr "type" "store")])
8764 (define_insn "*tldo_sth_sp64"
8765 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8766 (match_operand 3 "tld_symbolic_operand" "")]
8768 (match_operand:DI 1 "register_operand" "r")))
8769 (match_operand:HI 0 "register_operand" "=r"))]
8770 "TARGET_TLS && TARGET_ARCH64"
8771 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8772 [(set_attr "type" "store")])
8774 (define_insn "*tldo_stw_sp32"
8775 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8776 (match_operand 3 "tld_symbolic_operand" "")]
8778 (match_operand:SI 1 "register_operand" "r")))
8779 (match_operand:SI 0 "register_operand" "=r"))]
8780 "TARGET_TLS && TARGET_ARCH32"
8781 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8782 [(set_attr "type" "store")])
8784 (define_insn "*tldo_stw_sp64"
8785 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8786 (match_operand 3 "tld_symbolic_operand" "")]
8788 (match_operand:DI 1 "register_operand" "r")))
8789 (match_operand:SI 0 "register_operand" "=r"))]
8790 "TARGET_TLS && TARGET_ARCH64"
8791 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8792 [(set_attr "type" "store")])
8794 (define_insn "*tldo_stx_sp64"
8795 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8796 (match_operand 3 "tld_symbolic_operand" "")]
8798 (match_operand:DI 1 "register_operand" "r")))
8799 (match_operand:DI 0 "register_operand" "=r"))]
8800 "TARGET_TLS && TARGET_ARCH64"
8801 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8802 [(set_attr "type" "store")])