1 ;; Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002 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 GNU CC.
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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.
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
29 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
34 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
40 ;; 11 embmedany_sethi, embmedany_brsum
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
48 ;; UNSPEC_VOLATILE: 0 blockage
49 ;; 1 flush_register_windows
50 ;; 2 goto_handler_and_restore
51 ;; 3 goto_handler_and_restore_v9*
53 ;; 5 do_builtin_setjmp_setup
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc,ultrasparc3"
65 (const (symbol_ref "sparc_cpu_attr")))
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
78 (define_attr "arch" "arch32bit,arch64bit"
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
86 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcrmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
87 (const_string "ialu"))
89 ;; true if branch/call has empty delay slot and will emit a nop in it
90 (define_attr "empty_delay_slot" "false,true"
91 (symbol_ref "empty_delay_slot (insn)"))
93 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
95 (define_attr "pic" "false,true"
96 (symbol_ref "flag_pic != 0"))
98 ;; Length (in # of insns).
99 (define_attr "length" ""
100 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
101 (if_then_else (eq_attr "empty_delay_slot" "true")
104 (eq_attr "branch_type" "icc")
105 (if_then_else (match_operand 0 "noov_compare64_op" "")
106 (if_then_else (lt (pc) (match_dup 1))
107 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
108 (if_then_else (eq_attr "empty_delay_slot" "true")
111 (if_then_else (eq_attr "empty_delay_slot" "true")
114 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
115 (if_then_else (eq_attr "empty_delay_slot" "true")
118 (if_then_else (eq_attr "empty_delay_slot" "true")
121 (if_then_else (eq_attr "empty_delay_slot" "true")
124 (eq_attr "branch_type" "fcc")
125 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
126 (if_then_else (eq_attr "empty_delay_slot" "true")
129 (if_then_else (lt (pc) (match_dup 2))
130 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
131 (if_then_else (eq_attr "empty_delay_slot" "true")
134 (if_then_else (eq_attr "empty_delay_slot" "true")
137 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
138 (if_then_else (eq_attr "empty_delay_slot" "true")
141 (if_then_else (eq_attr "empty_delay_slot" "true")
144 (eq_attr "branch_type" "reg")
145 (if_then_else (lt (pc) (match_dup 2))
146 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
147 (if_then_else (eq_attr "empty_delay_slot" "true")
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
154 (if_then_else (eq_attr "empty_delay_slot" "true")
157 (if_then_else (eq_attr "empty_delay_slot" "true")
163 (define_attr "fptype" "single,double" (const_string "single"))
165 ;; UltraSPARC-III integer load type.
166 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
168 (define_asm_attributes
169 [(set_attr "length" "2")
170 (set_attr "type" "multi")])
172 ;; Attributes for instruction and branch scheduling
174 (define_attr "in_call_delay" "false,true"
175 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
176 (const_string "false")
177 (eq_attr "type" "load,fpload,store,fpstore")
178 (if_then_else (eq_attr "length" "1")
179 (const_string "true")
180 (const_string "false"))]
181 (if_then_else (eq_attr "length" "1")
182 (const_string "true")
183 (const_string "false"))))
185 (define_delay (eq_attr "type" "call")
186 [(eq_attr "in_call_delay" "true") (nil) (nil)])
188 (define_attr "eligible_for_sibcall_delay" "false,true"
189 (symbol_ref "eligible_for_sibcall_delay (insn)"))
191 (define_delay (eq_attr "type" "sibcall")
192 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
194 (define_attr "leaf_function" "false,true"
195 (const (symbol_ref "current_function_uses_only_leaf_regs")))
197 (define_attr "eligible_for_return_delay" "false,true"
198 (symbol_ref "eligible_for_return_delay (insn)"))
200 (define_attr "in_return_delay" "false,true"
201 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
202 (eq_attr "length" "1"))
203 (eq_attr "leaf_function" "false"))
204 (eq_attr "eligible_for_return_delay" "false"))
205 (const_string "true")
206 (const_string "false")))
208 (define_delay (and (eq_attr "type" "return")
209 (eq_attr "isa" "v9"))
210 [(eq_attr "in_return_delay" "true") (nil) (nil)])
212 ;; ??? Should implement the notion of predelay slots for floating point
213 ;; branches. This would allow us to remove the nop always inserted before
214 ;; a floating point branch.
216 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
217 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
218 ;; This is because doing so will add several pipeline stalls to the path
219 ;; that the load/store did not come from. Unfortunately, there is no way
220 ;; to prevent fill_eager_delay_slots from using load/store without completely
221 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
222 ;; because it prevents us from moving back the final store of inner loops.
224 (define_attr "in_branch_delay" "false,true"
225 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
226 (eq_attr "length" "1"))
227 (const_string "true")
228 (const_string "false")))
230 (define_attr "in_uncond_branch_delay" "false,true"
231 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
232 (eq_attr "length" "1"))
233 (const_string "true")
234 (const_string "false")))
236 (define_attr "in_annul_branch_delay" "false,true"
237 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
238 (eq_attr "length" "1"))
239 (const_string "true")
240 (const_string "false")))
242 (define_delay (eq_attr "type" "branch")
243 [(eq_attr "in_branch_delay" "true")
244 (nil) (eq_attr "in_annul_branch_delay" "true")])
246 (define_delay (eq_attr "type" "uncond_branch")
247 [(eq_attr "in_uncond_branch_delay" "true")
250 ;; Include SPARC DFA schedulers
252 (include "cypress.md")
253 (include "supersparc.md")
254 (include "hypersparc.md")
255 (include "sparclet.md")
256 (include "ultra1_2.md")
257 (include "ultra3.md")
260 ;; Compare instructions.
261 ;; This controls RTL generation and register allocation.
263 ;; We generate RTL for comparisons and branches by having the cmpxx
264 ;; patterns store away the operands. Then, the scc and bcc patterns
265 ;; emit RTL for both the compare and the branch.
267 ;; We do this because we want to generate different code for an sne and
268 ;; seq insn. In those cases, if the second operand of the compare is not
269 ;; const0_rtx, we want to compute the xor of the two operands and test
272 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
273 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
274 ;; insns that actually require more than one machine instruction.
276 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
278 (define_expand "cmpsi"
280 (compare:CC (match_operand:SI 0 "register_operand" "")
281 (match_operand:SI 1 "arith_operand" "")))]
285 sparc_compare_op0 = operands[0];
286 sparc_compare_op1 = operands[1];
290 (define_expand "cmpdi"
292 (compare:CCX (match_operand:DI 0 "register_operand" "")
293 (match_operand:DI 1 "arith_double_operand" "")))]
297 sparc_compare_op0 = operands[0];
298 sparc_compare_op1 = operands[1];
302 (define_expand "cmpsf"
303 ;; The 96 here isn't ever used by anyone.
305 (compare:CCFP (match_operand:SF 0 "register_operand" "")
306 (match_operand:SF 1 "register_operand" "")))]
310 sparc_compare_op0 = operands[0];
311 sparc_compare_op1 = operands[1];
315 (define_expand "cmpdf"
316 ;; The 96 here isn't ever used by anyone.
318 (compare:CCFP (match_operand:DF 0 "register_operand" "")
319 (match_operand:DF 1 "register_operand" "")))]
323 sparc_compare_op0 = operands[0];
324 sparc_compare_op1 = operands[1];
328 (define_expand "cmptf"
329 ;; The 96 here isn't ever used by anyone.
331 (compare:CCFP (match_operand:TF 0 "register_operand" "")
332 (match_operand:TF 1 "register_operand" "")))]
336 sparc_compare_op0 = operands[0];
337 sparc_compare_op1 = operands[1];
341 ;; Now the compare DEFINE_INSNs.
343 (define_insn "*cmpsi_insn"
345 (compare:CC (match_operand:SI 0 "register_operand" "r")
346 (match_operand:SI 1 "arith_operand" "rI")))]
349 [(set_attr "type" "compare")])
351 (define_insn "*cmpdi_sp64"
353 (compare:CCX (match_operand:DI 0 "register_operand" "r")
354 (match_operand:DI 1 "arith_double_operand" "rHI")))]
357 [(set_attr "type" "compare")])
359 (define_insn "*cmpsf_fpe"
360 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
361 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
362 (match_operand:SF 2 "register_operand" "f")))]
367 return \"fcmpes\\t%0, %1, %2\";
368 return \"fcmpes\\t%1, %2\";
370 [(set_attr "type" "fpcmp")])
372 (define_insn "*cmpdf_fpe"
373 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
374 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
375 (match_operand:DF 2 "register_operand" "e")))]
380 return \"fcmped\\t%0, %1, %2\";
381 return \"fcmped\\t%1, %2\";
383 [(set_attr "type" "fpcmp")
384 (set_attr "fptype" "double")])
386 (define_insn "*cmptf_fpe"
387 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
388 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
389 (match_operand:TF 2 "register_operand" "e")))]
390 "TARGET_FPU && TARGET_HARD_QUAD"
394 return \"fcmpeq\\t%0, %1, %2\";
395 return \"fcmpeq\\t%1, %2\";
397 [(set_attr "type" "fpcmp")])
399 (define_insn "*cmpsf_fp"
400 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
401 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
402 (match_operand:SF 2 "register_operand" "f")))]
407 return \"fcmps\\t%0, %1, %2\";
408 return \"fcmps\\t%1, %2\";
410 [(set_attr "type" "fpcmp")])
412 (define_insn "*cmpdf_fp"
413 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
414 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
415 (match_operand:DF 2 "register_operand" "e")))]
420 return \"fcmpd\\t%0, %1, %2\";
421 return \"fcmpd\\t%1, %2\";
423 [(set_attr "type" "fpcmp")
424 (set_attr "fptype" "double")])
426 (define_insn "*cmptf_fp"
427 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
428 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
429 (match_operand:TF 2 "register_operand" "e")))]
430 "TARGET_FPU && TARGET_HARD_QUAD"
434 return \"fcmpq\\t%0, %1, %2\";
435 return \"fcmpq\\t%1, %2\";
437 [(set_attr "type" "fpcmp")])
439 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
440 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
441 ;; the same code as v8 (the addx/subx method has more applications). The
442 ;; exception to this is "reg != 0" which can be done in one instruction on v9
443 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
446 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
447 ;; generate addcc/subcc instructions.
449 (define_expand "seqsi_special"
451 (xor:SI (match_operand:SI 1 "register_operand" "")
452 (match_operand:SI 2 "register_operand" "")))
453 (parallel [(set (match_operand:SI 0 "register_operand" "")
454 (eq:SI (match_dup 3) (const_int 0)))
455 (clobber (reg:CC 100))])]
457 "{ operands[3] = gen_reg_rtx (SImode); }")
459 (define_expand "seqdi_special"
461 (xor:DI (match_operand:DI 1 "register_operand" "")
462 (match_operand:DI 2 "register_operand" "")))
463 (set (match_operand:DI 0 "register_operand" "")
464 (eq:DI (match_dup 3) (const_int 0)))]
466 "{ operands[3] = gen_reg_rtx (DImode); }")
468 (define_expand "snesi_special"
470 (xor:SI (match_operand:SI 1 "register_operand" "")
471 (match_operand:SI 2 "register_operand" "")))
472 (parallel [(set (match_operand:SI 0 "register_operand" "")
473 (ne:SI (match_dup 3) (const_int 0)))
474 (clobber (reg:CC 100))])]
476 "{ operands[3] = gen_reg_rtx (SImode); }")
478 (define_expand "snedi_special"
480 (xor:DI (match_operand:DI 1 "register_operand" "")
481 (match_operand:DI 2 "register_operand" "")))
482 (set (match_operand:DI 0 "register_operand" "")
483 (ne:DI (match_dup 3) (const_int 0)))]
485 "{ operands[3] = gen_reg_rtx (DImode); }")
487 (define_expand "seqdi_special_trunc"
489 (xor:DI (match_operand:DI 1 "register_operand" "")
490 (match_operand:DI 2 "register_operand" "")))
491 (set (match_operand:SI 0 "register_operand" "")
492 (eq:SI (match_dup 3) (const_int 0)))]
494 "{ operands[3] = gen_reg_rtx (DImode); }")
496 (define_expand "snedi_special_trunc"
498 (xor:DI (match_operand:DI 1 "register_operand" "")
499 (match_operand:DI 2 "register_operand" "")))
500 (set (match_operand:SI 0 "register_operand" "")
501 (ne:SI (match_dup 3) (const_int 0)))]
503 "{ operands[3] = gen_reg_rtx (DImode); }")
505 (define_expand "seqsi_special_extend"
507 (xor:SI (match_operand:SI 1 "register_operand" "")
508 (match_operand:SI 2 "register_operand" "")))
509 (parallel [(set (match_operand:DI 0 "register_operand" "")
510 (eq:DI (match_dup 3) (const_int 0)))
511 (clobber (reg:CC 100))])]
513 "{ operands[3] = gen_reg_rtx (SImode); }")
515 (define_expand "snesi_special_extend"
517 (xor:SI (match_operand:SI 1 "register_operand" "")
518 (match_operand:SI 2 "register_operand" "")))
519 (parallel [(set (match_operand:DI 0 "register_operand" "")
520 (ne:DI (match_dup 3) (const_int 0)))
521 (clobber (reg:CC 100))])]
523 "{ operands[3] = gen_reg_rtx (SImode); }")
525 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
526 ;; However, the code handles both SImode and DImode.
528 [(set (match_operand:SI 0 "intreg_operand" "")
529 (eq:SI (match_dup 1) (const_int 0)))]
533 if (GET_MODE (sparc_compare_op0) == SImode)
537 if (GET_MODE (operands[0]) == SImode)
538 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
540 else if (! TARGET_ARCH64)
543 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
548 else if (GET_MODE (sparc_compare_op0) == DImode)
554 else if (GET_MODE (operands[0]) == SImode)
555 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
558 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
563 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
565 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
566 emit_jump_insn (gen_sne (operands[0]));
571 if (gen_v9_scc (EQ, operands))
578 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
579 ;; However, the code handles both SImode and DImode.
581 [(set (match_operand:SI 0 "intreg_operand" "")
582 (ne:SI (match_dup 1) (const_int 0)))]
586 if (GET_MODE (sparc_compare_op0) == SImode)
590 if (GET_MODE (operands[0]) == SImode)
591 pat = gen_snesi_special (operands[0], sparc_compare_op0,
593 else if (! TARGET_ARCH64)
596 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
601 else if (GET_MODE (sparc_compare_op0) == DImode)
607 else if (GET_MODE (operands[0]) == SImode)
608 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
611 pat = gen_snedi_special (operands[0], sparc_compare_op0,
616 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
618 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
619 emit_jump_insn (gen_sne (operands[0]));
624 if (gen_v9_scc (NE, operands))
632 [(set (match_operand:SI 0 "intreg_operand" "")
633 (gt:SI (match_dup 1) (const_int 0)))]
637 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
639 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
640 emit_jump_insn (gen_sne (operands[0]));
645 if (gen_v9_scc (GT, operands))
653 [(set (match_operand:SI 0 "intreg_operand" "")
654 (lt: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, LT);
661 emit_jump_insn (gen_sne (operands[0]));
666 if (gen_v9_scc (LT, operands))
674 [(set (match_operand:SI 0 "intreg_operand" "")
675 (ge:SI (match_dup 1) (const_int 0)))]
679 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
681 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
682 emit_jump_insn (gen_sne (operands[0]));
687 if (gen_v9_scc (GE, operands))
695 [(set (match_operand:SI 0 "intreg_operand" "")
696 (le:SI (match_dup 1) (const_int 0)))]
700 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
702 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
703 emit_jump_insn (gen_sne (operands[0]));
708 if (gen_v9_scc (LE, operands))
715 (define_expand "sgtu"
716 [(set (match_operand:SI 0 "intreg_operand" "")
717 (gtu:SI (match_dup 1) (const_int 0)))]
725 /* We can do ltu easily, so if both operands are registers, swap them and
727 if ((GET_CODE (sparc_compare_op0) == REG
728 || GET_CODE (sparc_compare_op0) == SUBREG)
729 && (GET_CODE (sparc_compare_op1) == REG
730 || GET_CODE (sparc_compare_op1) == SUBREG))
732 tem = sparc_compare_op0;
733 sparc_compare_op0 = sparc_compare_op1;
734 sparc_compare_op1 = tem;
735 pat = gen_sltu (operands[0]);
744 if (gen_v9_scc (GTU, operands))
750 (define_expand "sltu"
751 [(set (match_operand:SI 0 "intreg_operand" "")
752 (ltu:SI (match_dup 1) (const_int 0)))]
758 if (gen_v9_scc (LTU, operands))
761 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
764 (define_expand "sgeu"
765 [(set (match_operand:SI 0 "intreg_operand" "")
766 (geu:SI (match_dup 1) (const_int 0)))]
772 if (gen_v9_scc (GEU, operands))
775 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
778 (define_expand "sleu"
779 [(set (match_operand:SI 0 "intreg_operand" "")
780 (leu:SI (match_dup 1) (const_int 0)))]
788 /* We can do geu easily, so if both operands are registers, swap them and
790 if ((GET_CODE (sparc_compare_op0) == REG
791 || GET_CODE (sparc_compare_op0) == SUBREG)
792 && (GET_CODE (sparc_compare_op1) == REG
793 || GET_CODE (sparc_compare_op1) == SUBREG))
795 tem = sparc_compare_op0;
796 sparc_compare_op0 = sparc_compare_op1;
797 sparc_compare_op1 = tem;
798 pat = gen_sgeu (operands[0]);
807 if (gen_v9_scc (LEU, operands))
813 ;; Now the DEFINE_INSNs for the scc cases.
815 ;; The SEQ and SNE patterns are special because they can be done
816 ;; without any branching and do not involve a COMPARE. We want
817 ;; them to always use the splitz below so the results can be
820 (define_insn "*snesi_zero"
821 [(set (match_operand:SI 0 "register_operand" "=r")
822 (ne:SI (match_operand:SI 1 "register_operand" "r")
824 (clobber (reg:CC 100))]
827 [(set_attr "length" "2")])
830 [(set (match_operand:SI 0 "register_operand" "")
831 (ne:SI (match_operand:SI 1 "register_operand" "")
833 (clobber (reg:CC 100))]
835 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
837 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
840 (define_insn "*neg_snesi_zero"
841 [(set (match_operand:SI 0 "register_operand" "=r")
842 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
844 (clobber (reg:CC 100))]
847 [(set_attr "length" "2")])
850 [(set (match_operand:SI 0 "register_operand" "")
851 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
853 (clobber (reg:CC 100))]
855 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
857 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
860 (define_insn "*snesi_zero_extend"
861 [(set (match_operand:DI 0 "register_operand" "=r")
862 (ne:DI (match_operand:SI 1 "register_operand" "r")
864 (clobber (reg:CC 100))]
867 [(set_attr "length" "2")])
870 [(set (match_operand:DI 0 "register_operand" "")
871 (ne:DI (match_operand:SI 1 "register_operand" "")
873 (clobber (reg:CC 100))]
875 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
877 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
879 (ltu:SI (reg:CC_NOOV 100)
883 (define_insn "*snedi_zero"
884 [(set (match_operand:DI 0 "register_operand" "=&r")
885 (ne:DI (match_operand:DI 1 "register_operand" "r")
889 [(set_attr "length" "2")])
892 [(set (match_operand:DI 0 "register_operand" "")
893 (ne:DI (match_operand:DI 1 "register_operand" "")
896 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
897 [(set (match_dup 0) (const_int 0))
898 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
904 (define_insn "*neg_snedi_zero"
905 [(set (match_operand:DI 0 "register_operand" "=&r")
906 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
910 [(set_attr "length" "2")])
913 [(set (match_operand:DI 0 "register_operand" "")
914 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
917 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
918 [(set (match_dup 0) (const_int 0))
919 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
925 (define_insn "*snedi_zero_trunc"
926 [(set (match_operand:SI 0 "register_operand" "=&r")
927 (ne:SI (match_operand:DI 1 "register_operand" "r")
931 [(set_attr "length" "2")])
934 [(set (match_operand:SI 0 "register_operand" "")
935 (ne:SI (match_operand:DI 1 "register_operand" "")
938 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
939 [(set (match_dup 0) (const_int 0))
940 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
946 (define_insn "*seqsi_zero"
947 [(set (match_operand:SI 0 "register_operand" "=r")
948 (eq:SI (match_operand:SI 1 "register_operand" "r")
950 (clobber (reg:CC 100))]
953 [(set_attr "length" "2")])
956 [(set (match_operand:SI 0 "register_operand" "")
957 (eq:SI (match_operand:SI 1 "register_operand" "")
959 (clobber (reg:CC 100))]
961 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
963 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
966 (define_insn "*neg_seqsi_zero"
967 [(set (match_operand:SI 0 "register_operand" "=r")
968 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
970 (clobber (reg:CC 100))]
973 [(set_attr "length" "2")])
976 [(set (match_operand:SI 0 "register_operand" "")
977 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
979 (clobber (reg:CC 100))]
981 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
983 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
986 (define_insn "*seqsi_zero_extend"
987 [(set (match_operand:DI 0 "register_operand" "=r")
988 (eq:DI (match_operand:SI 1 "register_operand" "r")
990 (clobber (reg:CC 100))]
993 [(set_attr "length" "2")])
996 [(set (match_operand:DI 0 "register_operand" "")
997 (eq:DI (match_operand:SI 1 "register_operand" "")
999 (clobber (reg:CC 100))]
1001 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1003 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1005 (ltu:SI (reg:CC_NOOV 100)
1009 (define_insn "*seqdi_zero"
1010 [(set (match_operand:DI 0 "register_operand" "=&r")
1011 (eq:DI (match_operand:DI 1 "register_operand" "r")
1015 [(set_attr "length" "2")])
1018 [(set (match_operand:DI 0 "register_operand" "")
1019 (eq:DI (match_operand:DI 1 "register_operand" "")
1022 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1023 [(set (match_dup 0) (const_int 0))
1024 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1030 (define_insn "*neg_seqdi_zero"
1031 [(set (match_operand:DI 0 "register_operand" "=&r")
1032 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1036 [(set_attr "length" "2")])
1039 [(set (match_operand:DI 0 "register_operand" "")
1040 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1043 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1044 [(set (match_dup 0) (const_int 0))
1045 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1051 (define_insn "*seqdi_zero_trunc"
1052 [(set (match_operand:SI 0 "register_operand" "=&r")
1053 (eq:SI (match_operand:DI 1 "register_operand" "r")
1057 [(set_attr "length" "2")])
1060 [(set (match_operand:SI 0 "register_operand" "")
1061 (eq:SI (match_operand:DI 1 "register_operand" "")
1064 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1065 [(set (match_dup 0) (const_int 0))
1066 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1072 ;; We can also do (x + (i == 0)) and related, so put them in.
1073 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1076 (define_insn "*x_plus_i_ne_0"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1080 (match_operand:SI 2 "register_operand" "r")))
1081 (clobber (reg:CC 100))]
1084 [(set_attr "length" "2")])
1087 [(set (match_operand:SI 0 "register_operand" "")
1088 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1090 (match_operand:SI 2 "register_operand" "")))
1091 (clobber (reg:CC 100))]
1093 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1095 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1099 (define_insn "*x_minus_i_ne_0"
1100 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (minus:SI (match_operand:SI 2 "register_operand" "r")
1102 (ne:SI (match_operand:SI 1 "register_operand" "r")
1104 (clobber (reg:CC 100))]
1107 [(set_attr "length" "2")])
1110 [(set (match_operand:SI 0 "register_operand" "")
1111 (minus:SI (match_operand:SI 2 "register_operand" "")
1112 (ne:SI (match_operand:SI 1 "register_operand" "")
1114 (clobber (reg:CC 100))]
1116 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1118 (set (match_dup 0) (minus:SI (match_dup 2)
1119 (ltu:SI (reg:CC 100) (const_int 0))))]
1122 (define_insn "*x_plus_i_eq_0"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1126 (match_operand:SI 2 "register_operand" "r")))
1127 (clobber (reg:CC 100))]
1130 [(set_attr "length" "2")])
1133 [(set (match_operand:SI 0 "register_operand" "")
1134 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1136 (match_operand:SI 2 "register_operand" "")))
1137 (clobber (reg:CC 100))]
1139 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1141 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1145 (define_insn "*x_minus_i_eq_0"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (minus:SI (match_operand:SI 2 "register_operand" "r")
1148 (eq:SI (match_operand:SI 1 "register_operand" "r")
1150 (clobber (reg:CC 100))]
1153 [(set_attr "length" "2")])
1156 [(set (match_operand:SI 0 "register_operand" "")
1157 (minus:SI (match_operand:SI 2 "register_operand" "")
1158 (eq:SI (match_operand:SI 1 "register_operand" "")
1160 (clobber (reg:CC 100))]
1162 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1164 (set (match_dup 0) (minus:SI (match_dup 2)
1165 (geu:SI (reg:CC 100) (const_int 0))))]
1168 ;; We can also do GEU and LTU directly, but these operate after a compare.
1169 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1172 (define_insn "*sltu_insn"
1173 [(set (match_operand:SI 0 "register_operand" "=r")
1174 (ltu:SI (reg:CC 100) (const_int 0)))]
1176 "addx\\t%%g0, 0, %0"
1177 [(set_attr "type" "misc")])
1179 (define_insn "*neg_sltu_insn"
1180 [(set (match_operand:SI 0 "register_operand" "=r")
1181 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1183 "subx\\t%%g0, 0, %0"
1184 [(set_attr "type" "misc")])
1186 ;; ??? Combine should canonicalize these next two to the same pattern.
1187 (define_insn "*neg_sltu_minus_x"
1188 [(set (match_operand:SI 0 "register_operand" "=r")
1189 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1190 (match_operand:SI 1 "arith_operand" "rI")))]
1192 "subx\\t%%g0, %1, %0"
1193 [(set_attr "type" "misc")])
1195 (define_insn "*neg_sltu_plus_x"
1196 [(set (match_operand:SI 0 "register_operand" "=r")
1197 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1198 (match_operand:SI 1 "arith_operand" "rI"))))]
1200 "subx\\t%%g0, %1, %0"
1201 [(set_attr "type" "misc")])
1203 (define_insn "*sgeu_insn"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1205 (geu:SI (reg:CC 100) (const_int 0)))]
1207 "subx\\t%%g0, -1, %0"
1208 [(set_attr "type" "misc")])
1210 (define_insn "*neg_sgeu_insn"
1211 [(set (match_operand:SI 0 "register_operand" "=r")
1212 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1214 "addx\\t%%g0, -1, %0"
1215 [(set_attr "type" "misc")])
1217 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1218 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1221 (define_insn "*sltu_plus_x"
1222 [(set (match_operand:SI 0 "register_operand" "=r")
1223 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1224 (match_operand:SI 1 "arith_operand" "rI")))]
1226 "addx\\t%%g0, %1, %0"
1227 [(set_attr "type" "misc")])
1229 (define_insn "*sltu_plus_x_plus_y"
1230 [(set (match_operand:SI 0 "register_operand" "=r")
1231 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1232 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1233 (match_operand:SI 2 "arith_operand" "rI"))))]
1236 [(set_attr "type" "misc")])
1238 (define_insn "*x_minus_sltu"
1239 [(set (match_operand:SI 0 "register_operand" "=r")
1240 (minus:SI (match_operand:SI 1 "register_operand" "r")
1241 (ltu:SI (reg:CC 100) (const_int 0))))]
1244 [(set_attr "type" "misc")])
1246 ;; ??? Combine should canonicalize these next two to the same pattern.
1247 (define_insn "*x_minus_y_minus_sltu"
1248 [(set (match_operand:SI 0 "register_operand" "=r")
1249 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1250 (match_operand:SI 2 "arith_operand" "rI"))
1251 (ltu:SI (reg:CC 100) (const_int 0))))]
1253 "subx\\t%r1, %2, %0"
1254 [(set_attr "type" "misc")])
1256 (define_insn "*x_minus_sltu_plus_y"
1257 [(set (match_operand:SI 0 "register_operand" "=r")
1258 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1259 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1260 (match_operand:SI 2 "arith_operand" "rI"))))]
1262 "subx\\t%r1, %2, %0"
1263 [(set_attr "type" "misc")])
1265 (define_insn "*sgeu_plus_x"
1266 [(set (match_operand:SI 0 "register_operand" "=r")
1267 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1268 (match_operand:SI 1 "register_operand" "r")))]
1271 [(set_attr "type" "misc")])
1273 (define_insn "*x_minus_sgeu"
1274 [(set (match_operand:SI 0 "register_operand" "=r")
1275 (minus:SI (match_operand:SI 1 "register_operand" "r")
1276 (geu:SI (reg:CC 100) (const_int 0))))]
1279 [(set_attr "type" "misc")])
1282 [(set (match_operand:SI 0 "register_operand" "")
1283 (match_operator:SI 2 "noov_compare_op"
1284 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1286 ;; 32 bit LTU/GEU are better implemented using addx/subx
1287 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1288 && (GET_MODE (operands[1]) == CCXmode
1289 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1290 [(set (match_dup 0) (const_int 0))
1292 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1298 ;; These control RTL generation for conditional jump insns
1300 ;; The quad-word fp compare library routines all return nonzero to indicate
1301 ;; true, which is different from the equivalent libgcc routines, so we must
1302 ;; handle them specially here.
1304 (define_expand "beq"
1306 (if_then_else (eq (match_dup 1) (const_int 0))
1307 (label_ref (match_operand 0 "" ""))
1312 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1313 && GET_CODE (sparc_compare_op0) == REG
1314 && GET_MODE (sparc_compare_op0) == DImode)
1316 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1319 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1321 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1322 emit_jump_insn (gen_bne (operands[0]));
1325 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1328 (define_expand "bne"
1330 (if_then_else (ne (match_dup 1) (const_int 0))
1331 (label_ref (match_operand 0 "" ""))
1336 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1337 && GET_CODE (sparc_compare_op0) == REG
1338 && GET_MODE (sparc_compare_op0) == DImode)
1340 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1343 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1345 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1346 emit_jump_insn (gen_bne (operands[0]));
1349 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1352 (define_expand "bgt"
1354 (if_then_else (gt (match_dup 1) (const_int 0))
1355 (label_ref (match_operand 0 "" ""))
1360 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1361 && GET_CODE (sparc_compare_op0) == REG
1362 && GET_MODE (sparc_compare_op0) == DImode)
1364 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1367 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1369 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1370 emit_jump_insn (gen_bne (operands[0]));
1373 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1376 (define_expand "bgtu"
1378 (if_then_else (gtu (match_dup 1) (const_int 0))
1379 (label_ref (match_operand 0 "" ""))
1383 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1386 (define_expand "blt"
1388 (if_then_else (lt (match_dup 1) (const_int 0))
1389 (label_ref (match_operand 0 "" ""))
1394 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1395 && GET_CODE (sparc_compare_op0) == REG
1396 && GET_MODE (sparc_compare_op0) == DImode)
1398 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1401 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1403 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1404 emit_jump_insn (gen_bne (operands[0]));
1407 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1410 (define_expand "bltu"
1412 (if_then_else (ltu (match_dup 1) (const_int 0))
1413 (label_ref (match_operand 0 "" ""))
1417 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1420 (define_expand "bge"
1422 (if_then_else (ge (match_dup 1) (const_int 0))
1423 (label_ref (match_operand 0 "" ""))
1428 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1429 && GET_CODE (sparc_compare_op0) == REG
1430 && GET_MODE (sparc_compare_op0) == DImode)
1432 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1435 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1437 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1438 emit_jump_insn (gen_bne (operands[0]));
1441 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1444 (define_expand "bgeu"
1446 (if_then_else (geu (match_dup 1) (const_int 0))
1447 (label_ref (match_operand 0 "" ""))
1451 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1454 (define_expand "ble"
1456 (if_then_else (le (match_dup 1) (const_int 0))
1457 (label_ref (match_operand 0 "" ""))
1462 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1463 && GET_CODE (sparc_compare_op0) == REG
1464 && GET_MODE (sparc_compare_op0) == DImode)
1466 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1469 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1471 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1472 emit_jump_insn (gen_bne (operands[0]));
1475 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1478 (define_expand "bleu"
1480 (if_then_else (leu (match_dup 1) (const_int 0))
1481 (label_ref (match_operand 0 "" ""))
1485 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1488 (define_expand "bunordered"
1490 (if_then_else (unordered (match_dup 1) (const_int 0))
1491 (label_ref (match_operand 0 "" ""))
1496 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1498 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1500 emit_jump_insn (gen_beq (operands[0]));
1503 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1507 (define_expand "bordered"
1509 (if_then_else (ordered (match_dup 1) (const_int 0))
1510 (label_ref (match_operand 0 "" ""))
1515 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1517 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1518 emit_jump_insn (gen_bne (operands[0]));
1521 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1525 (define_expand "bungt"
1527 (if_then_else (ungt (match_dup 1) (const_int 0))
1528 (label_ref (match_operand 0 "" ""))
1533 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1535 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1536 emit_jump_insn (gen_bgt (operands[0]));
1539 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1542 (define_expand "bunlt"
1544 (if_then_else (unlt (match_dup 1) (const_int 0))
1545 (label_ref (match_operand 0 "" ""))
1550 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1552 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1553 emit_jump_insn (gen_bne (operands[0]));
1556 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1559 (define_expand "buneq"
1561 (if_then_else (uneq (match_dup 1) (const_int 0))
1562 (label_ref (match_operand 0 "" ""))
1567 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1569 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1570 emit_jump_insn (gen_beq (operands[0]));
1573 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1576 (define_expand "bunge"
1578 (if_then_else (unge (match_dup 1) (const_int 0))
1579 (label_ref (match_operand 0 "" ""))
1584 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1586 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1587 emit_jump_insn (gen_bne (operands[0]));
1590 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1593 (define_expand "bunle"
1595 (if_then_else (unle (match_dup 1) (const_int 0))
1596 (label_ref (match_operand 0 "" ""))
1601 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1603 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1604 emit_jump_insn (gen_bne (operands[0]));
1607 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1610 (define_expand "bltgt"
1612 (if_then_else (ltgt (match_dup 1) (const_int 0))
1613 (label_ref (match_operand 0 "" ""))
1618 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1620 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1621 emit_jump_insn (gen_bne (operands[0]));
1624 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1627 ;; Now match both normal and inverted jump.
1629 ;; XXX fpcmp nop braindamage
1630 (define_insn "*normal_branch"
1632 (if_then_else (match_operator 0 "noov_compare_op"
1633 [(reg 100) (const_int 0)])
1634 (label_ref (match_operand 1 "" ""))
1639 return output_cbranch (operands[0], operands[1], 1, 0,
1640 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1641 ! final_sequence, insn);
1643 [(set_attr "type" "branch")
1644 (set_attr "branch_type" "icc")])
1646 ;; XXX fpcmp nop braindamage
1647 (define_insn "*inverted_branch"
1649 (if_then_else (match_operator 0 "noov_compare_op"
1650 [(reg 100) (const_int 0)])
1652 (label_ref (match_operand 1 "" ""))))]
1656 return output_cbranch (operands[0], operands[1], 1, 1,
1657 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1658 ! final_sequence, insn);
1660 [(set_attr "type" "branch")
1661 (set_attr "branch_type" "icc")])
1663 ;; XXX fpcmp nop braindamage
1664 (define_insn "*normal_fp_branch"
1666 (if_then_else (match_operator 1 "comparison_operator"
1667 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1669 (label_ref (match_operand 2 "" ""))
1674 return output_cbranch (operands[1], operands[2], 2, 0,
1675 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1676 ! final_sequence, insn);
1678 [(set_attr "type" "branch")
1679 (set_attr "branch_type" "fcc")])
1681 ;; XXX fpcmp nop braindamage
1682 (define_insn "*inverted_fp_branch"
1684 (if_then_else (match_operator 1 "comparison_operator"
1685 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1688 (label_ref (match_operand 2 "" ""))))]
1692 return output_cbranch (operands[1], operands[2], 2, 1,
1693 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1694 ! final_sequence, insn);
1696 [(set_attr "type" "branch")
1697 (set_attr "branch_type" "fcc")])
1699 ;; XXX fpcmp nop braindamage
1700 (define_insn "*normal_fpe_branch"
1702 (if_then_else (match_operator 1 "comparison_operator"
1703 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1705 (label_ref (match_operand 2 "" ""))
1710 return output_cbranch (operands[1], operands[2], 2, 0,
1711 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1712 ! final_sequence, insn);
1714 [(set_attr "type" "branch")
1715 (set_attr "branch_type" "fcc")])
1717 ;; XXX fpcmp nop braindamage
1718 (define_insn "*inverted_fpe_branch"
1720 (if_then_else (match_operator 1 "comparison_operator"
1721 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1724 (label_ref (match_operand 2 "" ""))))]
1728 return output_cbranch (operands[1], operands[2], 2, 1,
1729 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1730 ! final_sequence, insn);
1732 [(set_attr "type" "branch")
1733 (set_attr "branch_type" "fcc")])
1735 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1736 ;; in the architecture.
1738 ;; There are no 32 bit brreg insns.
1741 (define_insn "*normal_int_branch_sp64"
1743 (if_then_else (match_operator 0 "v9_regcmp_op"
1744 [(match_operand:DI 1 "register_operand" "r")
1746 (label_ref (match_operand 2 "" ""))
1751 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1752 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1753 ! final_sequence, insn);
1755 [(set_attr "type" "branch")
1756 (set_attr "branch_type" "reg")])
1759 (define_insn "*inverted_int_branch_sp64"
1761 (if_then_else (match_operator 0 "v9_regcmp_op"
1762 [(match_operand:DI 1 "register_operand" "r")
1765 (label_ref (match_operand 2 "" ""))))]
1769 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1770 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1771 ! final_sequence, insn);
1773 [(set_attr "type" "branch")
1774 (set_attr "branch_type" "reg")])
1776 ;; Load program counter insns.
1778 (define_insn "get_pc"
1779 [(clobber (reg:SI 15))
1780 (set (match_operand 0 "register_operand" "=r")
1781 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
1782 "flag_pic && REGNO (operands[0]) == 23"
1783 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1784 [(set_attr "type" "multi")
1785 (set_attr "length" "3")])
1787 ;; Currently unused...
1788 ;; (define_insn "get_pc_via_rdpc"
1789 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
1792 ;; [(set_attr "type" "misc")])
1795 ;; Move instructions
1797 (define_expand "movqi"
1798 [(set (match_operand:QI 0 "general_operand" "")
1799 (match_operand:QI 1 "general_operand" ""))]
1803 /* Working with CONST_INTs is easier, so convert
1804 a double if needed. */
1805 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1807 operands[1] = GEN_INT (trunc_int_for_mode
1808 (CONST_DOUBLE_LOW (operands[1]), QImode));
1811 /* Handle sets of MEM first. */
1812 if (GET_CODE (operands[0]) == MEM)
1814 if (reg_or_0_operand (operands[1], QImode))
1817 if (! reload_in_progress)
1819 operands[0] = validize_mem (operands[0]);
1820 operands[1] = force_reg (QImode, operands[1]);
1824 /* Fixup PIC cases. */
1827 if (CONSTANT_P (operands[1])
1828 && pic_address_needs_scratch (operands[1]))
1829 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1831 if (symbolic_operand (operands[1], QImode))
1833 operands[1] = legitimize_pic_address (operands[1],
1835 (reload_in_progress ?
1842 /* All QI constants require only one insn, so proceed. */
1848 (define_insn "*movqi_insn"
1849 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1850 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1851 "(register_operand (operands[0], QImode)
1852 || reg_or_0_operand (operands[1], QImode))"
1857 [(set_attr "type" "*,load,store")
1858 (set_attr "us3load_type" "*,3cycle,*")])
1860 (define_expand "movhi"
1861 [(set (match_operand:HI 0 "general_operand" "")
1862 (match_operand:HI 1 "general_operand" ""))]
1866 /* Working with CONST_INTs is easier, so convert
1867 a double if needed. */
1868 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1869 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1871 /* Handle sets of MEM first. */
1872 if (GET_CODE (operands[0]) == MEM)
1874 if (reg_or_0_operand (operands[1], HImode))
1877 if (! reload_in_progress)
1879 operands[0] = validize_mem (operands[0]);
1880 operands[1] = force_reg (HImode, operands[1]);
1884 /* Fixup PIC cases. */
1887 if (CONSTANT_P (operands[1])
1888 && pic_address_needs_scratch (operands[1]))
1889 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1891 if (symbolic_operand (operands[1], HImode))
1893 operands[1] = legitimize_pic_address (operands[1],
1895 (reload_in_progress ?
1902 /* This makes sure we will not get rematched due to splittage. */
1903 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1905 else if (CONSTANT_P (operands[1])
1906 && GET_CODE (operands[1]) != HIGH
1907 && GET_CODE (operands[1]) != LO_SUM)
1909 sparc_emit_set_const32 (operands[0], operands[1]);
1916 (define_insn "*movhi_const64_special"
1917 [(set (match_operand:HI 0 "register_operand" "=r")
1918 (match_operand:HI 1 "const64_high_operand" ""))]
1920 "sethi\\t%%hi(%a1), %0")
1922 (define_insn "*movhi_insn"
1923 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1924 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1925 "(register_operand (operands[0], HImode)
1926 || reg_or_0_operand (operands[1], HImode))"
1929 sethi\\t%%hi(%a1), %0
1932 [(set_attr "type" "*,*,load,store")
1933 (set_attr "us3load_type" "*,*,3cycle,*")])
1935 ;; We always work with constants here.
1936 (define_insn "*movhi_lo_sum"
1937 [(set (match_operand:HI 0 "register_operand" "=r")
1938 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
1939 (match_operand:HI 2 "arith_operand" "I")))]
1943 (define_expand "movsi"
1944 [(set (match_operand:SI 0 "general_operand" "")
1945 (match_operand:SI 1 "general_operand" ""))]
1949 /* Working with CONST_INTs is easier, so convert
1950 a double if needed. */
1951 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1952 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1954 /* Handle sets of MEM first. */
1955 if (GET_CODE (operands[0]) == MEM)
1957 if (reg_or_0_operand (operands[1], SImode))
1960 if (! reload_in_progress)
1962 operands[0] = validize_mem (operands[0]);
1963 operands[1] = force_reg (SImode, operands[1]);
1967 /* Fixup PIC cases. */
1970 if (CONSTANT_P (operands[1])
1971 && pic_address_needs_scratch (operands[1]))
1972 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1974 if (GET_CODE (operands[1]) == LABEL_REF)
1977 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1981 if (symbolic_operand (operands[1], SImode))
1983 operands[1] = legitimize_pic_address (operands[1],
1985 (reload_in_progress ?
1992 /* If we are trying to toss an integer constant into the
1993 FPU registers, force it into memory. */
1994 if (GET_CODE (operands[0]) == REG
1995 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1996 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1997 && CONSTANT_P (operands[1]))
1998 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2001 /* This makes sure we will not get rematched due to splittage. */
2002 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2004 else if (CONSTANT_P (operands[1])
2005 && GET_CODE (operands[1]) != HIGH
2006 && GET_CODE (operands[1]) != LO_SUM)
2008 sparc_emit_set_const32 (operands[0], operands[1]);
2015 ;; This is needed to show CSE exactly which bits are set
2016 ;; in a 64-bit register by sethi instructions.
2017 (define_insn "*movsi_const64_special"
2018 [(set (match_operand:SI 0 "register_operand" "=r")
2019 (match_operand:SI 1 "const64_high_operand" ""))]
2021 "sethi\\t%%hi(%a1), %0")
2023 (define_insn "*movsi_insn"
2024 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2025 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2026 "(register_operand (operands[0], SImode)
2027 || reg_or_0_operand (operands[1], SImode))"
2031 sethi\\t%%hi(%a1), %0
2038 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2040 (define_insn "*movsi_lo_sum"
2041 [(set (match_operand:SI 0 "register_operand" "=r")
2042 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2043 (match_operand:SI 2 "immediate_operand" "in")))]
2045 "or\\t%1, %%lo(%a2), %0")
2047 (define_insn "*movsi_high"
2048 [(set (match_operand:SI 0 "register_operand" "=r")
2049 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2051 "sethi\\t%%hi(%a1), %0")
2053 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2054 ;; so that CSE won't optimize the address computation away.
2055 (define_insn "movsi_lo_sum_pic"
2056 [(set (match_operand:SI 0 "register_operand" "=r")
2057 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2058 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2060 "or\\t%1, %%lo(%a2), %0")
2062 (define_insn "movsi_high_pic"
2063 [(set (match_operand:SI 0 "register_operand" "=r")
2064 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2065 "flag_pic && check_pic (1)"
2066 "sethi\\t%%hi(%a1), %0")
2068 (define_expand "movsi_pic_label_ref"
2069 [(set (match_dup 3) (high:SI
2070 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2072 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2073 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2074 (set (match_operand:SI 0 "register_operand" "=r")
2075 (minus:SI (match_dup 5) (match_dup 4)))]
2079 current_function_uses_pic_offset_table = 1;
2080 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2083 operands[3] = operands[0];
2084 operands[4] = operands[0];
2088 operands[3] = gen_reg_rtx (SImode);
2089 operands[4] = gen_reg_rtx (SImode);
2091 operands[5] = pic_offset_table_rtx;
2094 (define_insn "*movsi_high_pic_label_ref"
2095 [(set (match_operand:SI 0 "register_operand" "=r")
2097 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2098 (match_operand:SI 2 "" "")] 5)))]
2100 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2102 (define_insn "*movsi_lo_sum_pic_label_ref"
2103 [(set (match_operand:SI 0 "register_operand" "=r")
2104 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2105 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2106 (match_operand:SI 3 "" "")] 5)))]
2108 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2110 (define_expand "movdi"
2111 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2112 (match_operand:DI 1 "general_operand" ""))]
2116 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2117 if (GET_CODE (operands[1]) == CONST_DOUBLE
2118 #if HOST_BITS_PER_WIDE_INT == 32
2119 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2120 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2121 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2122 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2125 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2127 /* Handle MEM cases first. */
2128 if (GET_CODE (operands[0]) == MEM)
2130 /* If it's a REG, we can always do it.
2131 The const zero case is more complex, on v9
2132 we can always perform it. */
2133 if (register_operand (operands[1], DImode)
2135 && (operands[1] == const0_rtx)))
2138 if (! reload_in_progress)
2140 operands[0] = validize_mem (operands[0]);
2141 operands[1] = force_reg (DImode, operands[1]);
2147 if (CONSTANT_P (operands[1])
2148 && pic_address_needs_scratch (operands[1]))
2149 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2151 if (GET_CODE (operands[1]) == LABEL_REF)
2153 if (! TARGET_ARCH64)
2155 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2159 if (symbolic_operand (operands[1], DImode))
2161 operands[1] = legitimize_pic_address (operands[1],
2163 (reload_in_progress ?
2170 /* If we are trying to toss an integer constant into the
2171 FPU registers, force it into memory. */
2172 if (GET_CODE (operands[0]) == REG
2173 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2174 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2175 && CONSTANT_P (operands[1]))
2176 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2179 /* This makes sure we will not get rematched due to splittage. */
2180 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2182 else if (TARGET_ARCH64
2183 && CONSTANT_P (operands[1])
2184 && GET_CODE (operands[1]) != HIGH
2185 && GET_CODE (operands[1]) != LO_SUM)
2187 sparc_emit_set_const64 (operands[0], operands[1]);
2195 ;; Be careful, fmovd does not exist when !arch64.
2196 ;; We match MEM moves directly when we have correct even
2197 ;; numbered registers, but fall into splits otherwise.
2198 ;; The constraint ordering here is really important to
2199 ;; avoid insane problems in reload, especially for patterns
2202 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2203 ;; (const_int -5016)))
2207 (define_insn "*movdi_insn_sp32_v9"
2208 [(set (match_operand:DI 0 "nonimmediate_operand"
2209 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2210 (match_operand:DI 1 "input_operand"
2211 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2212 "! TARGET_ARCH64 && TARGET_V9
2213 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2228 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2229 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2231 (define_insn "*movdi_insn_sp32"
2232 [(set (match_operand:DI 0 "nonimmediate_operand"
2233 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2234 (match_operand:DI 1 "input_operand"
2235 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2237 && (register_operand (operands[0], DImode)
2238 || register_operand (operands[1], DImode))"
2252 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2253 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2255 ;; The following are generated by sparc_emit_set_const64
2256 (define_insn "*movdi_sp64_dbl"
2257 [(set (match_operand:DI 0 "register_operand" "=r")
2258 (match_operand:DI 1 "const64_operand" ""))]
2260 && HOST_BITS_PER_WIDE_INT != 64)"
2263 ;; This is needed to show CSE exactly which bits are set
2264 ;; in a 64-bit register by sethi instructions.
2265 (define_insn "*movdi_const64_special"
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (match_operand:DI 1 "const64_high_operand" ""))]
2269 "sethi\\t%%hi(%a1), %0")
2271 (define_insn "*movdi_insn_sp64_novis"
2272 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2273 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2274 "TARGET_ARCH64 && ! TARGET_VIS
2275 && (register_operand (operands[0], DImode)
2276 || reg_or_0_operand (operands[1], DImode))"
2279 sethi\\t%%hi(%a1), %0
2286 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2287 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2289 (define_insn "*movdi_insn_sp64_vis"
2290 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2291 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2292 "TARGET_ARCH64 && TARGET_VIS &&
2293 (register_operand (operands[0], DImode)
2294 || reg_or_0_operand (operands[1], DImode))"
2297 sethi\\t%%hi(%a1), %0
2305 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2306 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2308 (define_expand "movdi_pic_label_ref"
2309 [(set (match_dup 3) (high:DI
2310 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2312 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2313 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2314 (set (match_operand:DI 0 "register_operand" "=r")
2315 (minus:DI (match_dup 5) (match_dup 4)))]
2316 "TARGET_ARCH64 && flag_pic"
2319 current_function_uses_pic_offset_table = 1;
2320 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2323 operands[3] = operands[0];
2324 operands[4] = operands[0];
2328 operands[3] = gen_reg_rtx (DImode);
2329 operands[4] = gen_reg_rtx (DImode);
2331 operands[5] = pic_offset_table_rtx;
2334 (define_insn "*movdi_high_pic_label_ref"
2335 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2338 (match_operand:DI 2 "" "")] 5)))]
2339 "TARGET_ARCH64 && flag_pic"
2340 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2342 (define_insn "*movdi_lo_sum_pic_label_ref"
2343 [(set (match_operand:DI 0 "register_operand" "=r")
2344 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2345 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2346 (match_operand:DI 3 "" "")] 5)))]
2347 "TARGET_ARCH64 && flag_pic"
2348 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2350 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2351 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2353 (define_insn "movdi_lo_sum_pic"
2354 [(set (match_operand:DI 0 "register_operand" "=r")
2355 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2356 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2357 "TARGET_ARCH64 && flag_pic"
2358 "or\\t%1, %%lo(%a2), %0")
2360 (define_insn "movdi_high_pic"
2361 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2363 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2364 "sethi\\t%%hi(%a1), %0")
2366 (define_insn "*sethi_di_medlow_embmedany_pic"
2367 [(set (match_operand:DI 0 "register_operand" "=r")
2368 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2369 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2370 "sethi\\t%%hi(%a1), %0")
2372 (define_insn "*sethi_di_medlow"
2373 [(set (match_operand:DI 0 "register_operand" "=r")
2374 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2375 "TARGET_CM_MEDLOW && check_pic (1)"
2376 "sethi\\t%%hi(%a1), %0")
2378 (define_insn "*losum_di_medlow"
2379 [(set (match_operand:DI 0 "register_operand" "=r")
2380 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2381 (match_operand:DI 2 "symbolic_operand" "")))]
2383 "or\\t%1, %%lo(%a2), %0")
2385 (define_insn "seth44"
2386 [(set (match_operand:DI 0 "register_operand" "=r")
2387 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2389 "sethi\\t%%h44(%a1), %0")
2391 (define_insn "setm44"
2392 [(set (match_operand:DI 0 "register_operand" "=r")
2393 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2394 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2396 "or\\t%1, %%m44(%a2), %0")
2398 (define_insn "setl44"
2399 [(set (match_operand:DI 0 "register_operand" "=r")
2400 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2401 (match_operand:DI 2 "symbolic_operand" "")))]
2403 "or\\t%1, %%l44(%a2), %0")
2405 (define_insn "sethh"
2406 [(set (match_operand:DI 0 "register_operand" "=r")
2407 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2409 "sethi\\t%%hh(%a1), %0")
2411 (define_insn "setlm"
2412 [(set (match_operand:DI 0 "register_operand" "=r")
2413 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2415 "sethi\\t%%lm(%a1), %0")
2417 (define_insn "sethm"
2418 [(set (match_operand:DI 0 "register_operand" "=r")
2419 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2420 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2422 "or\\t%1, %%hm(%a2), %0")
2424 (define_insn "setlo"
2425 [(set (match_operand:DI 0 "register_operand" "=r")
2426 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2427 (match_operand:DI 2 "symbolic_operand" "")))]
2429 "or\\t%1, %%lo(%a2), %0")
2431 (define_insn "embmedany_sethi"
2432 [(set (match_operand:DI 0 "register_operand" "=r")
2433 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2434 "TARGET_CM_EMBMEDANY && check_pic (1)"
2435 "sethi\\t%%hi(%a1), %0")
2437 (define_insn "embmedany_losum"
2438 [(set (match_operand:DI 0 "register_operand" "=r")
2439 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2440 (match_operand:DI 2 "data_segment_operand" "")))]
2441 "TARGET_CM_EMBMEDANY"
2442 "add\\t%1, %%lo(%a2), %0")
2444 (define_insn "embmedany_brsum"
2445 [(set (match_operand:DI 0 "register_operand" "=r")
2446 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2447 "TARGET_CM_EMBMEDANY"
2450 (define_insn "embmedany_textuhi"
2451 [(set (match_operand:DI 0 "register_operand" "=r")
2452 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2453 "TARGET_CM_EMBMEDANY && check_pic (1)"
2454 "sethi\\t%%uhi(%a1), %0")
2456 (define_insn "embmedany_texthi"
2457 [(set (match_operand:DI 0 "register_operand" "=r")
2458 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2459 "TARGET_CM_EMBMEDANY && check_pic (1)"
2460 "sethi\\t%%hi(%a1), %0")
2462 (define_insn "embmedany_textulo"
2463 [(set (match_operand:DI 0 "register_operand" "=r")
2464 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2465 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2466 "TARGET_CM_EMBMEDANY"
2467 "or\\t%1, %%ulo(%a2), %0")
2469 (define_insn "embmedany_textlo"
2470 [(set (match_operand:DI 0 "register_operand" "=r")
2471 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2472 (match_operand:DI 2 "text_segment_operand" "")))]
2473 "TARGET_CM_EMBMEDANY"
2474 "or\\t%1, %%lo(%a2), %0")
2476 ;; Now some patterns to help reload out a bit.
2477 (define_expand "reload_indi"
2478 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2479 (match_operand:DI 1 "immediate_operand" "")
2480 (match_operand:TI 2 "register_operand" "=&r")])]
2482 || TARGET_CM_EMBMEDANY)
2486 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2490 (define_expand "reload_outdi"
2491 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2492 (match_operand:DI 1 "immediate_operand" "")
2493 (match_operand:TI 2 "register_operand" "=&r")])]
2495 || TARGET_CM_EMBMEDANY)
2499 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2503 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2505 [(set (match_operand:DI 0 "register_operand" "")
2506 (match_operand:DI 1 "const_int_operand" ""))]
2507 "! TARGET_ARCH64 && reload_completed"
2508 [(clobber (const_int 0))]
2511 #if HOST_BITS_PER_WIDE_INT == 32
2512 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2513 (INTVAL (operands[1]) < 0) ?
2516 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2519 unsigned int low, high;
2521 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2522 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2523 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2525 /* Slick... but this trick loses if this subreg constant part
2526 can be done in one insn. */
2527 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2528 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2529 gen_highpart (SImode, operands[0])));
2531 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2537 [(set (match_operand:DI 0 "register_operand" "")
2538 (match_operand:DI 1 "const_double_operand" ""))]
2539 "! TARGET_ARCH64 && reload_completed"
2540 [(clobber (const_int 0))]
2543 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2544 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2546 /* Slick... but this trick loses if this subreg constant part
2547 can be done in one insn. */
2548 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2549 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2550 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2552 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2553 gen_highpart (SImode, operands[0])));
2557 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2558 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2564 [(set (match_operand:DI 0 "register_operand" "")
2565 (match_operand:DI 1 "register_operand" ""))]
2566 "! TARGET_ARCH64 && reload_completed"
2567 [(clobber (const_int 0))]
2570 rtx set_dest = operands[0];
2571 rtx set_src = operands[1];
2575 dest1 = gen_highpart (SImode, set_dest);
2576 dest2 = gen_lowpart (SImode, set_dest);
2577 src1 = gen_highpart (SImode, set_src);
2578 src2 = gen_lowpart (SImode, set_src);
2580 /* Now emit using the real source and destination we found, swapping
2581 the order if we detect overlap. */
2582 if (reg_overlap_mentioned_p (dest1, src2))
2584 emit_insn (gen_movsi (dest2, src2));
2585 emit_insn (gen_movsi (dest1, src1));
2589 emit_insn (gen_movsi (dest1, src1));
2590 emit_insn (gen_movsi (dest2, src2));
2595 ;; Now handle the cases of memory moves from/to non-even
2596 ;; DI mode register pairs.
2598 [(set (match_operand:DI 0 "register_operand" "")
2599 (match_operand:DI 1 "memory_operand" ""))]
2602 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2603 [(clobber (const_int 0))]
2606 rtx word0 = adjust_address (operands[1], SImode, 0);
2607 rtx word1 = adjust_address (operands[1], SImode, 4);
2608 rtx high_part = gen_highpart (SImode, operands[0]);
2609 rtx low_part = gen_lowpart (SImode, operands[0]);
2611 if (reg_overlap_mentioned_p (high_part, word1))
2613 emit_insn (gen_movsi (low_part, word1));
2614 emit_insn (gen_movsi (high_part, word0));
2618 emit_insn (gen_movsi (high_part, word0));
2619 emit_insn (gen_movsi (low_part, word1));
2625 [(set (match_operand:DI 0 "memory_operand" "")
2626 (match_operand:DI 1 "register_operand" ""))]
2629 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2630 [(clobber (const_int 0))]
2633 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2634 gen_highpart (SImode, operands[1])));
2635 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2636 gen_lowpart (SImode, operands[1])));
2641 [(set (match_operand:DI 0 "memory_operand" "")
2646 && ! mem_min_alignment (operands[0], 8)))
2647 && offsettable_memref_p (operands[0])"
2648 [(clobber (const_int 0))]
2651 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2652 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2656 ;; Floating point move insns
2658 (define_insn "*movsf_insn_novis"
2659 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2660 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2661 "(TARGET_FPU && ! TARGET_VIS)
2662 && (register_operand (operands[0], SFmode)
2663 || register_operand (operands[1], SFmode)
2664 || fp_zero_operand (operands[1], SFmode))"
2667 if (GET_CODE (operands[1]) == CONST_DOUBLE
2668 && (which_alternative == 2
2669 || which_alternative == 3
2670 || which_alternative == 4))
2675 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2676 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2677 operands[1] = GEN_INT (i);
2680 switch (which_alternative)
2683 return \"fmovs\\t%1, %0\";
2685 return \"clr\\t%0\";
2687 return \"sethi\\t%%hi(%a1), %0\";
2689 return \"mov\\t%1, %0\";
2694 return \"ld\\t%1, %0\";
2697 return \"st\\t%r1, %0\";
2702 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2704 (define_insn "*movsf_insn_vis"
2705 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2706 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2707 "(TARGET_FPU && TARGET_VIS)
2708 && (register_operand (operands[0], SFmode)
2709 || register_operand (operands[1], SFmode)
2710 || fp_zero_operand (operands[1], SFmode))"
2713 if (GET_CODE (operands[1]) == CONST_DOUBLE
2714 && (which_alternative == 3
2715 || which_alternative == 4
2716 || which_alternative == 5))
2721 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2722 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2723 operands[1] = GEN_INT (i);
2726 switch (which_alternative)
2729 return \"fmovs\\t%1, %0\";
2731 return \"fzeros\\t%0\";
2733 return \"clr\\t%0\";
2735 return \"sethi\\t%%hi(%a1), %0\";
2737 return \"mov\\t%1, %0\";
2742 return \"ld\\t%1, %0\";
2745 return \"st\\t%r1, %0\";
2750 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2752 ;; Exactly the same as above, except that all `f' cases are deleted.
2753 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2756 (define_insn "*movsf_no_f_insn"
2757 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2758 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2760 && (register_operand (operands[0], SFmode)
2761 || register_operand (operands[1], SFmode)
2762 || fp_zero_operand (operands[1], SFmode))"
2765 if (GET_CODE (operands[1]) == CONST_DOUBLE
2766 && (which_alternative == 1
2767 || which_alternative == 2
2768 || which_alternative == 3))
2773 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2774 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2775 operands[1] = GEN_INT (i);
2778 switch (which_alternative)
2781 return \"clr\\t%0\";
2783 return \"sethi\\t%%hi(%a1), %0\";
2785 return \"mov\\t%1, %0\";
2789 return \"ld\\t%1, %0\";
2791 return \"st\\t%r1, %0\";
2796 [(set_attr "type" "*,*,*,*,load,store")])
2798 (define_insn "*movsf_lo_sum"
2799 [(set (match_operand:SF 0 "register_operand" "=r")
2800 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2801 (match_operand:SF 2 "const_double_operand" "S")))]
2802 "fp_high_losum_p (operands[2])"
2808 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2809 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2810 operands[2] = GEN_INT (i);
2811 return \"or\\t%1, %%lo(%a2), %0\";
2814 (define_insn "*movsf_high"
2815 [(set (match_operand:SF 0 "register_operand" "=r")
2816 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2817 "fp_high_losum_p (operands[1])"
2823 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2824 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2825 operands[1] = GEN_INT (i);
2826 return \"sethi\\t%%hi(%1), %0\";
2830 [(set (match_operand:SF 0 "register_operand" "")
2831 (match_operand:SF 1 "const_double_operand" ""))]
2832 "fp_high_losum_p (operands[1])
2833 && (GET_CODE (operands[0]) == REG
2834 && REGNO (operands[0]) < 32)"
2835 [(set (match_dup 0) (high:SF (match_dup 1)))
2836 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2838 (define_expand "movsf"
2839 [(set (match_operand:SF 0 "general_operand" "")
2840 (match_operand:SF 1 "general_operand" ""))]
2844 /* Force SFmode constants into memory. */
2845 if (GET_CODE (operands[0]) == REG
2846 && CONSTANT_P (operands[1]))
2848 /* emit_group_store will send such bogosity to us when it is
2849 not storing directly into memory. So fix this up to avoid
2850 crashes in output_constant_pool. */
2851 if (operands [1] == const0_rtx)
2852 operands[1] = CONST0_RTX (SFmode);
2854 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2857 /* We are able to build any SF constant in integer registers
2858 with at most 2 instructions. */
2859 if (REGNO (operands[0]) < 32)
2862 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2866 /* Handle sets of MEM first. */
2867 if (GET_CODE (operands[0]) == MEM)
2869 if (register_operand (operands[1], SFmode)
2870 || fp_zero_operand (operands[1], SFmode))
2873 if (! reload_in_progress)
2875 operands[0] = validize_mem (operands[0]);
2876 operands[1] = force_reg (SFmode, operands[1]);
2880 /* Fixup PIC cases. */
2883 if (CONSTANT_P (operands[1])
2884 && pic_address_needs_scratch (operands[1]))
2885 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2887 if (symbolic_operand (operands[1], SFmode))
2889 operands[1] = legitimize_pic_address (operands[1],
2891 (reload_in_progress ?
2901 (define_expand "movdf"
2902 [(set (match_operand:DF 0 "general_operand" "")
2903 (match_operand:DF 1 "general_operand" ""))]
2907 /* Force DFmode constants into memory. */
2908 if (GET_CODE (operands[0]) == REG
2909 && CONSTANT_P (operands[1]))
2911 /* emit_group_store will send such bogosity to us when it is
2912 not storing directly into memory. So fix this up to avoid
2913 crashes in output_constant_pool. */
2914 if (operands [1] == const0_rtx)
2915 operands[1] = CONST0_RTX (DFmode);
2917 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2918 && fp_zero_operand (operands[1], DFmode))
2921 /* We are able to build any DF constant in integer registers. */
2922 if (REGNO (operands[0]) < 32
2923 && (reload_completed || reload_in_progress))
2926 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2930 /* Handle MEM cases first. */
2931 if (GET_CODE (operands[0]) == MEM)
2933 if (register_operand (operands[1], DFmode)
2934 || fp_zero_operand (operands[1], DFmode))
2937 if (! reload_in_progress)
2939 operands[0] = validize_mem (operands[0]);
2940 operands[1] = force_reg (DFmode, operands[1]);
2944 /* Fixup PIC cases. */
2947 if (CONSTANT_P (operands[1])
2948 && pic_address_needs_scratch (operands[1]))
2949 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2951 if (symbolic_operand (operands[1], DFmode))
2953 operands[1] = legitimize_pic_address (operands[1],
2955 (reload_in_progress ?
2965 ;; Be careful, fmovd does not exist when !v9.
2966 (define_insn "*movdf_insn_sp32"
2967 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2968 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2971 && (register_operand (operands[0], DFmode)
2972 || register_operand (operands[1], DFmode)
2973 || fp_zero_operand (operands[1], DFmode))"
2985 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2986 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2988 (define_insn "*movdf_no_e_insn_sp32"
2989 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2990 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2994 && (register_operand (operands[0], DFmode)
2995 || register_operand (operands[1], DFmode)
2996 || fp_zero_operand (operands[1], DFmode))"
3003 [(set_attr "type" "load,store,*,*,*")
3004 (set_attr "length" "*,*,2,2,2")])
3006 (define_insn "*movdf_no_e_insn_v9_sp32"
3007 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3008 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3012 && (register_operand (operands[0], DFmode)
3013 || register_operand (operands[1], DFmode)
3014 || fp_zero_operand (operands[1], DFmode))"
3021 [(set_attr "type" "load,store,store,*,*")
3022 (set_attr "length" "*,*,*,2,2")])
3024 ;; We have available v9 double floats but not 64-bit
3025 ;; integer registers and no VIS.
3026 (define_insn "*movdf_insn_v9only_novis"
3027 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
3028 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
3033 && (register_operand (operands[0], DFmode)
3034 || register_operand (operands[1], DFmode)
3035 || fp_zero_operand (operands[1], DFmode))"
3046 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3047 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3048 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3050 ;; We have available v9 double floats but not 64-bit
3051 ;; integer registers but we have VIS.
3052 (define_insn "*movdf_insn_v9only_vis"
3053 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
3054 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
3058 && (register_operand (operands[0], DFmode)
3059 || register_operand (operands[1], DFmode)
3060 || fp_zero_operand (operands[1], DFmode))"
3072 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3073 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3074 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3076 ;; We have available both v9 double floats and 64-bit
3077 ;; integer registers. No VIS though.
3078 (define_insn "*movdf_insn_sp64_novis"
3079 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3080 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3084 && (register_operand (operands[0], DFmode)
3085 || register_operand (operands[1], DFmode)
3086 || fp_zero_operand (operands[1], DFmode))"
3095 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3096 (set_attr "length" "*,*,*,*,*,*,2")
3097 (set_attr "fptype" "double,*,*,*,*,*,*")])
3099 ;; We have available both v9 double floats and 64-bit
3100 ;; integer registers. And we have VIS.
3101 (define_insn "*movdf_insn_sp64_vis"
3102 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3103 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3107 && (register_operand (operands[0], DFmode)
3108 || register_operand (operands[1], DFmode)
3109 || fp_zero_operand (operands[1], DFmode))"
3119 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3120 (set_attr "length" "*,*,*,*,*,*,*,2")
3121 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3123 (define_insn "*movdf_no_e_insn_sp64"
3124 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3125 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3128 && (register_operand (operands[0], DFmode)
3129 || register_operand (operands[1], DFmode)
3130 || fp_zero_operand (operands[1], DFmode))"
3135 [(set_attr "type" "*,load,store")])
3138 [(set (match_operand:DF 0 "register_operand" "")
3139 (match_operand:DF 1 "const_double_operand" ""))]
3141 && (GET_CODE (operands[0]) == REG
3142 && REGNO (operands[0]) < 32)
3143 && ! fp_zero_operand(operands[1], DFmode)
3144 && reload_completed"
3145 [(clobber (const_int 0))]
3151 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3152 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3153 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3157 #if HOST_BITS_PER_WIDE_INT == 64
3160 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3161 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3162 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3164 emit_insn (gen_movdi (operands[0],
3165 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3170 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3173 /* Slick... but this trick loses if this subreg constant part
3174 can be done in one insn. */
3176 && !(SPARC_SETHI32_P (l[0])
3177 || SPARC_SIMM13_P (l[0])))
3179 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3180 gen_highpart (SImode, operands[0])));
3184 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3191 ;; Ok, now the splits to handle all the multi insn and
3192 ;; mis-aligned memory address cases.
3193 ;; In these splits please take note that we must be
3194 ;; careful when V9 but not ARCH64 because the integer
3195 ;; register DFmode cases must be handled.
3197 [(set (match_operand:DF 0 "register_operand" "")
3198 (match_operand:DF 1 "register_operand" ""))]
3201 && ((GET_CODE (operands[0]) == REG
3202 && REGNO (operands[0]) < 32)
3203 || (GET_CODE (operands[0]) == SUBREG
3204 && GET_CODE (SUBREG_REG (operands[0])) == REG
3205 && REGNO (SUBREG_REG (operands[0])) < 32))))
3206 && reload_completed"
3207 [(clobber (const_int 0))]
3210 rtx set_dest = operands[0];
3211 rtx set_src = operands[1];
3215 dest1 = gen_highpart (SFmode, set_dest);
3216 dest2 = gen_lowpart (SFmode, set_dest);
3217 src1 = gen_highpart (SFmode, set_src);
3218 src2 = gen_lowpart (SFmode, set_src);
3220 /* Now emit using the real source and destination we found, swapping
3221 the order if we detect overlap. */
3222 if (reg_overlap_mentioned_p (dest1, src2))
3224 emit_insn (gen_movsf (dest2, src2));
3225 emit_insn (gen_movsf (dest1, src1));
3229 emit_insn (gen_movsf (dest1, src1));
3230 emit_insn (gen_movsf (dest2, src2));
3236 [(set (match_operand:DF 0 "register_operand" "")
3237 (match_operand:DF 1 "memory_operand" ""))]
3240 && (((REGNO (operands[0]) % 2) != 0)
3241 || ! mem_min_alignment (operands[1], 8))
3242 && offsettable_memref_p (operands[1])"
3243 [(clobber (const_int 0))]
3246 rtx word0 = adjust_address (operands[1], SFmode, 0);
3247 rtx word1 = adjust_address (operands[1], SFmode, 4);
3249 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3251 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3253 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3258 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3260 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3267 [(set (match_operand:DF 0 "memory_operand" "")
3268 (match_operand:DF 1 "register_operand" ""))]
3271 && (((REGNO (operands[1]) % 2) != 0)
3272 || ! mem_min_alignment (operands[0], 8))
3273 && offsettable_memref_p (operands[0])"
3274 [(clobber (const_int 0))]
3277 rtx word0 = adjust_address (operands[0], SFmode, 0);
3278 rtx word1 = adjust_address (operands[0], SFmode, 4);
3280 emit_insn (gen_movsf (word0,
3281 gen_highpart (SFmode, operands[1])));
3282 emit_insn (gen_movsf (word1,
3283 gen_lowpart (SFmode, operands[1])));
3288 [(set (match_operand:DF 0 "memory_operand" "")
3289 (match_operand:DF 1 "fp_zero_operand" ""))]
3293 && ! mem_min_alignment (operands[0], 8)))
3294 && offsettable_memref_p (operands[0])"
3295 [(clobber (const_int 0))]
3300 dest1 = adjust_address (operands[0], SFmode, 0);
3301 dest2 = adjust_address (operands[0], SFmode, 4);
3303 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3304 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3309 [(set (match_operand:DF 0 "register_operand" "")
3310 (match_operand:DF 1 "fp_zero_operand" ""))]
3313 && ((GET_CODE (operands[0]) == REG
3314 && REGNO (operands[0]) < 32)
3315 || (GET_CODE (operands[0]) == SUBREG
3316 && GET_CODE (SUBREG_REG (operands[0])) == REG
3317 && REGNO (SUBREG_REG (operands[0])) < 32))"
3318 [(clobber (const_int 0))]
3321 rtx set_dest = operands[0];
3324 dest1 = gen_highpart (SFmode, set_dest);
3325 dest2 = gen_lowpart (SFmode, set_dest);
3326 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3327 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3331 (define_expand "movtf"
3332 [(set (match_operand:TF 0 "general_operand" "")
3333 (match_operand:TF 1 "general_operand" ""))]
3337 /* Force TFmode constants into memory. */
3338 if (GET_CODE (operands[0]) == REG
3339 && CONSTANT_P (operands[1]))
3341 /* emit_group_store will send such bogosity to us when it is
3342 not storing directly into memory. So fix this up to avoid
3343 crashes in output_constant_pool. */
3344 if (operands [1] == const0_rtx)
3345 operands[1] = CONST0_RTX (TFmode);
3347 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3350 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3354 /* Handle MEM cases first, note that only v9 guarentees
3355 full 16-byte alignment for quads. */
3356 if (GET_CODE (operands[0]) == MEM)
3358 if (register_operand (operands[1], TFmode)
3359 || fp_zero_operand (operands[1], TFmode))
3362 if (! reload_in_progress)
3364 operands[0] = validize_mem (operands[0]);
3365 operands[1] = force_reg (TFmode, operands[1]);
3369 /* Fixup PIC cases. */
3372 if (CONSTANT_P (operands[1])
3373 && pic_address_needs_scratch (operands[1]))
3374 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3376 if (symbolic_operand (operands[1], TFmode))
3378 operands[1] = legitimize_pic_address (operands[1],
3380 (reload_in_progress ?
3390 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3391 ;; we must split them all. :-(
3392 (define_insn "*movtf_insn_sp32"
3393 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3394 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3398 && (register_operand (operands[0], TFmode)
3399 || register_operand (operands[1], TFmode)
3400 || fp_zero_operand (operands[1], TFmode))"
3402 [(set_attr "length" "4")])
3404 (define_insn "*movtf_insn_vis_sp32"
3405 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3406 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3410 && (register_operand (operands[0], TFmode)
3411 || register_operand (operands[1], TFmode)
3412 || fp_zero_operand (operands[1], TFmode))"
3414 [(set_attr "length" "4")])
3416 ;; Exactly the same as above, except that all `e' cases are deleted.
3417 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3420 (define_insn "*movtf_no_e_insn_sp32"
3421 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3422 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3425 && (register_operand (operands[0], TFmode)
3426 || register_operand (operands[1], TFmode)
3427 || fp_zero_operand (operands[1], TFmode))"
3429 [(set_attr "length" "4")])
3431 ;; Now handle the float reg cases directly when arch64,
3432 ;; hard_quad, and proper reg number alignment are all true.
3433 (define_insn "*movtf_insn_hq_sp64"
3434 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3435 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3440 && (register_operand (operands[0], TFmode)
3441 || register_operand (operands[1], TFmode)
3442 || fp_zero_operand (operands[1], TFmode))"
3449 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3450 (set_attr "length" "*,*,*,2,2")])
3452 (define_insn "*movtf_insn_hq_vis_sp64"
3453 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3454 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3459 && (register_operand (operands[0], TFmode)
3460 || register_operand (operands[1], TFmode)
3461 || fp_zero_operand (operands[1], TFmode))"
3469 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3470 (set_attr "length" "*,*,*,2,2,2")])
3472 ;; Now we allow the integer register cases even when
3473 ;; only arch64 is true.
3474 (define_insn "*movtf_insn_sp64"
3475 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3476 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3480 && ! TARGET_HARD_QUAD
3481 && (register_operand (operands[0], TFmode)
3482 || register_operand (operands[1], TFmode)
3483 || fp_zero_operand (operands[1], TFmode))"
3485 [(set_attr "length" "2")])
3487 (define_insn "*movtf_insn_vis_sp64"
3488 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3489 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3493 && ! TARGET_HARD_QUAD
3494 && (register_operand (operands[0], TFmode)
3495 || register_operand (operands[1], TFmode)
3496 || fp_zero_operand (operands[1], TFmode))"
3498 [(set_attr "length" "2")])
3500 (define_insn "*movtf_no_e_insn_sp64"
3501 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3502 (match_operand:TF 1 "input_operand" "orG,rG"))]
3505 && (register_operand (operands[0], TFmode)
3506 || register_operand (operands[1], TFmode)
3507 || fp_zero_operand (operands[1], TFmode))"
3509 [(set_attr "length" "2")])
3511 ;; Now all the splits to handle multi-insn TF mode moves.
3513 [(set (match_operand:TF 0 "register_operand" "")
3514 (match_operand:TF 1 "register_operand" ""))]
3518 && ! TARGET_HARD_QUAD)
3519 || ! fp_register_operand (operands[0], TFmode))"
3520 [(clobber (const_int 0))]
3523 rtx set_dest = operands[0];
3524 rtx set_src = operands[1];
3528 dest1 = gen_df_reg (set_dest, 0);
3529 dest2 = gen_df_reg (set_dest, 1);
3530 src1 = gen_df_reg (set_src, 0);
3531 src2 = gen_df_reg (set_src, 1);
3533 /* Now emit using the real source and destination we found, swapping
3534 the order if we detect overlap. */
3535 if (reg_overlap_mentioned_p (dest1, src2))
3537 emit_insn (gen_movdf (dest2, src2));
3538 emit_insn (gen_movdf (dest1, src1));
3542 emit_insn (gen_movdf (dest1, src1));
3543 emit_insn (gen_movdf (dest2, src2));
3549 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3550 (match_operand:TF 1 "fp_zero_operand" ""))]
3552 [(clobber (const_int 0))]
3555 rtx set_dest = operands[0];
3558 switch (GET_CODE (set_dest))
3561 dest1 = gen_df_reg (set_dest, 0);
3562 dest2 = gen_df_reg (set_dest, 1);
3565 dest1 = adjust_address (set_dest, DFmode, 0);
3566 dest2 = adjust_address (set_dest, DFmode, 8);
3572 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3573 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3578 [(set (match_operand:TF 0 "register_operand" "")
3579 (match_operand:TF 1 "memory_operand" ""))]
3581 && offsettable_memref_p (operands[1])
3583 || ! TARGET_HARD_QUAD
3584 || ! fp_register_operand (operands[0], TFmode)))"
3585 [(clobber (const_int 0))]
3588 rtx word0 = adjust_address (operands[1], DFmode, 0);
3589 rtx word1 = adjust_address (operands[1], DFmode, 8);
3590 rtx set_dest, dest1, dest2;
3592 set_dest = operands[0];
3594 dest1 = gen_df_reg (set_dest, 0);
3595 dest2 = gen_df_reg (set_dest, 1);
3597 /* Now output, ordering such that we don't clobber any registers
3598 mentioned in the address. */
3599 if (reg_overlap_mentioned_p (dest1, word1))
3602 emit_insn (gen_movdf (dest2, word1));
3603 emit_insn (gen_movdf (dest1, word0));
3607 emit_insn (gen_movdf (dest1, word0));
3608 emit_insn (gen_movdf (dest2, word1));
3614 [(set (match_operand:TF 0 "memory_operand" "")
3615 (match_operand:TF 1 "register_operand" ""))]
3617 && offsettable_memref_p (operands[0])
3619 || ! TARGET_HARD_QUAD
3620 || ! fp_register_operand (operands[1], TFmode)))"
3621 [(clobber (const_int 0))]
3624 rtx set_src = operands[1];
3626 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3627 gen_df_reg (set_src, 0)));
3628 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3629 gen_df_reg (set_src, 1)));
3633 ;; Sparc V9 conditional move instructions.
3635 ;; We can handle larger constants here for some flavors, but for now we keep
3636 ;; it simple and only allow those constants supported by all flavours.
3637 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3638 ;; 3 contains the constant if one is present, but we handle either for
3639 ;; generality (sparc.c puts a constant in operand 2).
3641 (define_expand "movqicc"
3642 [(set (match_operand:QI 0 "register_operand" "")
3643 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3644 (match_operand:QI 2 "arith10_operand" "")
3645 (match_operand:QI 3 "arith10_operand" "")))]
3649 enum rtx_code code = GET_CODE (operands[1]);
3651 if (GET_MODE (sparc_compare_op0) == DImode
3655 if (sparc_compare_op1 == const0_rtx
3656 && GET_CODE (sparc_compare_op0) == REG
3657 && GET_MODE (sparc_compare_op0) == DImode
3658 && v9_regcmp_p (code))
3660 operands[1] = gen_rtx_fmt_ee (code, DImode,
3661 sparc_compare_op0, sparc_compare_op1);
3665 rtx cc_reg = gen_compare_reg (code,
3666 sparc_compare_op0, sparc_compare_op1);
3667 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3671 (define_expand "movhicc"
3672 [(set (match_operand:HI 0 "register_operand" "")
3673 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3674 (match_operand:HI 2 "arith10_operand" "")
3675 (match_operand:HI 3 "arith10_operand" "")))]
3679 enum rtx_code code = GET_CODE (operands[1]);
3681 if (GET_MODE (sparc_compare_op0) == DImode
3685 if (sparc_compare_op1 == const0_rtx
3686 && GET_CODE (sparc_compare_op0) == REG
3687 && GET_MODE (sparc_compare_op0) == DImode
3688 && v9_regcmp_p (code))
3690 operands[1] = gen_rtx_fmt_ee (code, DImode,
3691 sparc_compare_op0, sparc_compare_op1);
3695 rtx cc_reg = gen_compare_reg (code,
3696 sparc_compare_op0, sparc_compare_op1);
3697 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3701 (define_expand "movsicc"
3702 [(set (match_operand:SI 0 "register_operand" "")
3703 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3704 (match_operand:SI 2 "arith10_operand" "")
3705 (match_operand:SI 3 "arith10_operand" "")))]
3709 enum rtx_code code = GET_CODE (operands[1]);
3710 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3712 if (sparc_compare_op1 == const0_rtx
3713 && GET_CODE (sparc_compare_op0) == REG
3714 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3716 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3717 sparc_compare_op0, sparc_compare_op1);
3721 rtx cc_reg = gen_compare_reg (code,
3722 sparc_compare_op0, sparc_compare_op1);
3723 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3724 cc_reg, const0_rtx);
3728 (define_expand "movdicc"
3729 [(set (match_operand:DI 0 "register_operand" "")
3730 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3731 (match_operand:DI 2 "arith10_double_operand" "")
3732 (match_operand:DI 3 "arith10_double_operand" "")))]
3736 enum rtx_code code = GET_CODE (operands[1]);
3738 if (sparc_compare_op1 == const0_rtx
3739 && GET_CODE (sparc_compare_op0) == REG
3740 && GET_MODE (sparc_compare_op0) == DImode
3741 && v9_regcmp_p (code))
3743 operands[1] = gen_rtx_fmt_ee (code, DImode,
3744 sparc_compare_op0, sparc_compare_op1);
3748 rtx cc_reg = gen_compare_reg (code,
3749 sparc_compare_op0, sparc_compare_op1);
3750 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3751 cc_reg, const0_rtx);
3755 (define_expand "movsfcc"
3756 [(set (match_operand:SF 0 "register_operand" "")
3757 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3758 (match_operand:SF 2 "register_operand" "")
3759 (match_operand:SF 3 "register_operand" "")))]
3760 "TARGET_V9 && TARGET_FPU"
3763 enum rtx_code code = GET_CODE (operands[1]);
3765 if (GET_MODE (sparc_compare_op0) == DImode
3769 if (sparc_compare_op1 == const0_rtx
3770 && GET_CODE (sparc_compare_op0) == REG
3771 && GET_MODE (sparc_compare_op0) == DImode
3772 && v9_regcmp_p (code))
3774 operands[1] = gen_rtx_fmt_ee (code, DImode,
3775 sparc_compare_op0, sparc_compare_op1);
3779 rtx cc_reg = gen_compare_reg (code,
3780 sparc_compare_op0, sparc_compare_op1);
3781 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3785 (define_expand "movdfcc"
3786 [(set (match_operand:DF 0 "register_operand" "")
3787 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3788 (match_operand:DF 2 "register_operand" "")
3789 (match_operand:DF 3 "register_operand" "")))]
3790 "TARGET_V9 && TARGET_FPU"
3793 enum rtx_code code = GET_CODE (operands[1]);
3795 if (GET_MODE (sparc_compare_op0) == DImode
3799 if (sparc_compare_op1 == const0_rtx
3800 && GET_CODE (sparc_compare_op0) == REG
3801 && GET_MODE (sparc_compare_op0) == DImode
3802 && v9_regcmp_p (code))
3804 operands[1] = gen_rtx_fmt_ee (code, DImode,
3805 sparc_compare_op0, sparc_compare_op1);
3809 rtx cc_reg = gen_compare_reg (code,
3810 sparc_compare_op0, sparc_compare_op1);
3811 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3815 (define_expand "movtfcc"
3816 [(set (match_operand:TF 0 "register_operand" "")
3817 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3818 (match_operand:TF 2 "register_operand" "")
3819 (match_operand:TF 3 "register_operand" "")))]
3820 "TARGET_V9 && TARGET_FPU"
3823 enum rtx_code code = GET_CODE (operands[1]);
3825 if (GET_MODE (sparc_compare_op0) == DImode
3829 if (sparc_compare_op1 == const0_rtx
3830 && GET_CODE (sparc_compare_op0) == REG
3831 && GET_MODE (sparc_compare_op0) == DImode
3832 && v9_regcmp_p (code))
3834 operands[1] = gen_rtx_fmt_ee (code, DImode,
3835 sparc_compare_op0, sparc_compare_op1);
3839 rtx cc_reg = gen_compare_reg (code,
3840 sparc_compare_op0, sparc_compare_op1);
3841 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3845 ;; Conditional move define_insns.
3847 (define_insn "*movqi_cc_sp64"
3848 [(set (match_operand:QI 0 "register_operand" "=r,r")
3849 (if_then_else:QI (match_operator 1 "comparison_operator"
3850 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3852 (match_operand:QI 3 "arith11_operand" "rL,0")
3853 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3856 mov%C1\\t%x2, %3, %0
3857 mov%c1\\t%x2, %4, %0"
3858 [(set_attr "type" "cmove")])
3860 (define_insn "*movhi_cc_sp64"
3861 [(set (match_operand:HI 0 "register_operand" "=r,r")
3862 (if_then_else:HI (match_operator 1 "comparison_operator"
3863 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3865 (match_operand:HI 3 "arith11_operand" "rL,0")
3866 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3869 mov%C1\\t%x2, %3, %0
3870 mov%c1\\t%x2, %4, %0"
3871 [(set_attr "type" "cmove")])
3873 (define_insn "*movsi_cc_sp64"
3874 [(set (match_operand:SI 0 "register_operand" "=r,r")
3875 (if_then_else:SI (match_operator 1 "comparison_operator"
3876 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3878 (match_operand:SI 3 "arith11_operand" "rL,0")
3879 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3882 mov%C1\\t%x2, %3, %0
3883 mov%c1\\t%x2, %4, %0"
3884 [(set_attr "type" "cmove")])
3886 ;; ??? The constraints of operands 3,4 need work.
3887 (define_insn "*movdi_cc_sp64"
3888 [(set (match_operand:DI 0 "register_operand" "=r,r")
3889 (if_then_else:DI (match_operator 1 "comparison_operator"
3890 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3892 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3893 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3896 mov%C1\\t%x2, %3, %0
3897 mov%c1\\t%x2, %4, %0"
3898 [(set_attr "type" "cmove")])
3900 (define_insn "*movdi_cc_sp64_trunc"
3901 [(set (match_operand:SI 0 "register_operand" "=r,r")
3902 (if_then_else:SI (match_operator 1 "comparison_operator"
3903 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3905 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3906 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3909 mov%C1\\t%x2, %3, %0
3910 mov%c1\\t%x2, %4, %0"
3911 [(set_attr "type" "cmove")])
3913 (define_insn "*movsf_cc_sp64"
3914 [(set (match_operand:SF 0 "register_operand" "=f,f")
3915 (if_then_else:SF (match_operator 1 "comparison_operator"
3916 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3918 (match_operand:SF 3 "register_operand" "f,0")
3919 (match_operand:SF 4 "register_operand" "0,f")))]
3920 "TARGET_V9 && TARGET_FPU"
3922 fmovs%C1\\t%x2, %3, %0
3923 fmovs%c1\\t%x2, %4, %0"
3924 [(set_attr "type" "fpcmove")])
3926 (define_insn "movdf_cc_sp64"
3927 [(set (match_operand:DF 0 "register_operand" "=e,e")
3928 (if_then_else:DF (match_operator 1 "comparison_operator"
3929 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3931 (match_operand:DF 3 "register_operand" "e,0")
3932 (match_operand:DF 4 "register_operand" "0,e")))]
3933 "TARGET_V9 && TARGET_FPU"
3935 fmovd%C1\\t%x2, %3, %0
3936 fmovd%c1\\t%x2, %4, %0"
3937 [(set_attr "type" "fpcmove")
3938 (set_attr "fptype" "double")])
3940 (define_insn "*movtf_cc_hq_sp64"
3941 [(set (match_operand:TF 0 "register_operand" "=e,e")
3942 (if_then_else:TF (match_operator 1 "comparison_operator"
3943 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3945 (match_operand:TF 3 "register_operand" "e,0")
3946 (match_operand:TF 4 "register_operand" "0,e")))]
3947 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3949 fmovq%C1\\t%x2, %3, %0
3950 fmovq%c1\\t%x2, %4, %0"
3951 [(set_attr "type" "fpcmove")])
3953 (define_insn "*movtf_cc_sp64"
3954 [(set (match_operand:TF 0 "register_operand" "=e,e")
3955 (if_then_else:TF (match_operator 1 "comparison_operator"
3956 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3958 (match_operand:TF 3 "register_operand" "e,0")
3959 (match_operand:TF 4 "register_operand" "0,e")))]
3960 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3962 [(set_attr "length" "2")])
3965 [(set (match_operand:TF 0 "register_operand" "")
3966 (if_then_else:TF (match_operator 1 "comparison_operator"
3967 [(match_operand 2 "icc_or_fcc_reg_operand" "")
3969 (match_operand:TF 3 "register_operand" "")
3970 (match_operand:TF 4 "register_operand" "")))]
3971 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3972 [(clobber (const_int 0))]
3975 rtx set_dest = operands[0];
3976 rtx set_srca = operands[3];
3977 rtx set_srcb = operands[4];
3978 int third = rtx_equal_p (set_dest, set_srca);
3980 rtx srca1, srca2, srcb1, srcb2;
3982 dest1 = gen_df_reg (set_dest, 0);
3983 dest2 = gen_df_reg (set_dest, 1);
3984 srca1 = gen_df_reg (set_srca, 0);
3985 srca2 = gen_df_reg (set_srca, 1);
3986 srcb1 = gen_df_reg (set_srcb, 0);
3987 srcb2 = gen_df_reg (set_srcb, 1);
3989 /* Now emit using the real source and destination we found, swapping
3990 the order if we detect overlap. */
3991 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3992 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3994 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3995 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3999 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4000 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4005 (define_insn "*movqi_cc_reg_sp64"
4006 [(set (match_operand:QI 0 "register_operand" "=r,r")
4007 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4008 [(match_operand:DI 2 "register_operand" "r,r")
4010 (match_operand:QI 3 "arith10_operand" "rM,0")
4011 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4014 movr%D1\\t%2, %r3, %0
4015 movr%d1\\t%2, %r4, %0"
4016 [(set_attr "type" "cmove")])
4018 (define_insn "*movhi_cc_reg_sp64"
4019 [(set (match_operand:HI 0 "register_operand" "=r,r")
4020 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4021 [(match_operand:DI 2 "register_operand" "r,r")
4023 (match_operand:HI 3 "arith10_operand" "rM,0")
4024 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4027 movr%D1\\t%2, %r3, %0
4028 movr%d1\\t%2, %r4, %0"
4029 [(set_attr "type" "cmove")])
4031 (define_insn "*movsi_cc_reg_sp64"
4032 [(set (match_operand:SI 0 "register_operand" "=r,r")
4033 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4034 [(match_operand:DI 2 "register_operand" "r,r")
4036 (match_operand:SI 3 "arith10_operand" "rM,0")
4037 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4040 movr%D1\\t%2, %r3, %0
4041 movr%d1\\t%2, %r4, %0"
4042 [(set_attr "type" "cmove")])
4044 ;; ??? The constraints of operands 3,4 need work.
4045 (define_insn "*movdi_cc_reg_sp64"
4046 [(set (match_operand:DI 0 "register_operand" "=r,r")
4047 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4048 [(match_operand:DI 2 "register_operand" "r,r")
4050 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4051 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4054 movr%D1\\t%2, %r3, %0
4055 movr%d1\\t%2, %r4, %0"
4056 [(set_attr "type" "cmove")])
4058 (define_insn "*movdi_cc_reg_sp64_trunc"
4059 [(set (match_operand:SI 0 "register_operand" "=r,r")
4060 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4061 [(match_operand:DI 2 "register_operand" "r,r")
4063 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4064 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4067 movr%D1\\t%2, %r3, %0
4068 movr%d1\\t%2, %r4, %0"
4069 [(set_attr "type" "cmove")])
4071 (define_insn "*movsf_cc_reg_sp64"
4072 [(set (match_operand:SF 0 "register_operand" "=f,f")
4073 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4074 [(match_operand:DI 2 "register_operand" "r,r")
4076 (match_operand:SF 3 "register_operand" "f,0")
4077 (match_operand:SF 4 "register_operand" "0,f")))]
4078 "TARGET_ARCH64 && TARGET_FPU"
4080 fmovrs%D1\\t%2, %3, %0
4081 fmovrs%d1\\t%2, %4, %0"
4082 [(set_attr "type" "fpcrmove")])
4084 (define_insn "movdf_cc_reg_sp64"
4085 [(set (match_operand:DF 0 "register_operand" "=e,e")
4086 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4087 [(match_operand:DI 2 "register_operand" "r,r")
4089 (match_operand:DF 3 "register_operand" "e,0")
4090 (match_operand:DF 4 "register_operand" "0,e")))]
4091 "TARGET_ARCH64 && TARGET_FPU"
4093 fmovrd%D1\\t%2, %3, %0
4094 fmovrd%d1\\t%2, %4, %0"
4095 [(set_attr "type" "fpcrmove")
4096 (set_attr "fptype" "double")])
4098 (define_insn "*movtf_cc_reg_hq_sp64"
4099 [(set (match_operand:TF 0 "register_operand" "=e,e")
4100 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4101 [(match_operand:DI 2 "register_operand" "r,r")
4103 (match_operand:TF 3 "register_operand" "e,0")
4104 (match_operand:TF 4 "register_operand" "0,e")))]
4105 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4107 fmovrq%D1\\t%2, %3, %0
4108 fmovrq%d1\\t%2, %4, %0"
4109 [(set_attr "type" "fpcrmove")])
4111 (define_insn "*movtf_cc_reg_sp64"
4112 [(set (match_operand:TF 0 "register_operand" "=e,e")
4113 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4114 [(match_operand:DI 2 "register_operand" "r,r")
4116 (match_operand:TF 3 "register_operand" "e,0")
4117 (match_operand:TF 4 "register_operand" "0,e")))]
4118 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4120 [(set_attr "length" "2")])
4123 [(set (match_operand:TF 0 "register_operand" "")
4124 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4125 [(match_operand:DI 2 "register_operand" "")
4127 (match_operand:TF 3 "register_operand" "")
4128 (match_operand:TF 4 "register_operand" "")))]
4129 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4130 [(clobber (const_int 0))]
4133 rtx set_dest = operands[0];
4134 rtx set_srca = operands[3];
4135 rtx set_srcb = operands[4];
4136 int third = rtx_equal_p (set_dest, set_srca);
4138 rtx srca1, srca2, srcb1, srcb2;
4140 dest1 = gen_df_reg (set_dest, 0);
4141 dest2 = gen_df_reg (set_dest, 1);
4142 srca1 = gen_df_reg (set_srca, 0);
4143 srca2 = gen_df_reg (set_srca, 1);
4144 srcb1 = gen_df_reg (set_srcb, 0);
4145 srcb2 = gen_df_reg (set_srcb, 1);
4147 /* Now emit using the real source and destination we found, swapping
4148 the order if we detect overlap. */
4149 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4150 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4152 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4153 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4157 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4158 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4164 ;;- zero extension instructions
4166 ;; These patterns originally accepted general_operands, however, slightly
4167 ;; better code is generated by only accepting register_operands, and then
4168 ;; letting combine generate the ldu[hb] insns.
4170 (define_expand "zero_extendhisi2"
4171 [(set (match_operand:SI 0 "register_operand" "")
4172 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4176 rtx temp = gen_reg_rtx (SImode);
4177 rtx shift_16 = GEN_INT (16);
4178 int op1_subbyte = 0;
4180 if (GET_CODE (operand1) == SUBREG)
4182 op1_subbyte = SUBREG_BYTE (operand1);
4183 op1_subbyte /= GET_MODE_SIZE (SImode);
4184 op1_subbyte *= GET_MODE_SIZE (SImode);
4185 operand1 = XEXP (operand1, 0);
4188 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4190 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4194 (define_insn "*zero_extendhisi2_insn"
4195 [(set (match_operand:SI 0 "register_operand" "=r")
4196 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4199 [(set_attr "type" "load")
4200 (set_attr "us3load_type" "3cycle")])
4202 (define_expand "zero_extendqihi2"
4203 [(set (match_operand:HI 0 "register_operand" "")
4204 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4208 (define_insn "*zero_extendqihi2_insn"
4209 [(set (match_operand:HI 0 "register_operand" "=r,r")
4210 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4211 "GET_CODE (operands[1]) != CONST_INT"
4215 [(set_attr "type" "*,load")
4216 (set_attr "us3load_type" "*,3cycle")])
4218 (define_expand "zero_extendqisi2"
4219 [(set (match_operand:SI 0 "register_operand" "")
4220 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4224 (define_insn "*zero_extendqisi2_insn"
4225 [(set (match_operand:SI 0 "register_operand" "=r,r")
4226 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4227 "GET_CODE (operands[1]) != CONST_INT"
4231 [(set_attr "type" "*,load")
4232 (set_attr "us3load_type" "*,3cycle")])
4234 (define_expand "zero_extendqidi2"
4235 [(set (match_operand:DI 0 "register_operand" "")
4236 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4240 (define_insn "*zero_extendqidi2_insn"
4241 [(set (match_operand:DI 0 "register_operand" "=r,r")
4242 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4243 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4247 [(set_attr "type" "*,load")
4248 (set_attr "us3load_type" "*,3cycle")])
4250 (define_expand "zero_extendhidi2"
4251 [(set (match_operand:DI 0 "register_operand" "")
4252 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4256 rtx temp = gen_reg_rtx (DImode);
4257 rtx shift_48 = GEN_INT (48);
4258 int op1_subbyte = 0;
4260 if (GET_CODE (operand1) == SUBREG)
4262 op1_subbyte = SUBREG_BYTE (operand1);
4263 op1_subbyte /= GET_MODE_SIZE (DImode);
4264 op1_subbyte *= GET_MODE_SIZE (DImode);
4265 operand1 = XEXP (operand1, 0);
4268 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4270 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4274 (define_insn "*zero_extendhidi2_insn"
4275 [(set (match_operand:DI 0 "register_operand" "=r")
4276 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4279 [(set_attr "type" "load")
4280 (set_attr "us3load_type" "3cycle")])
4283 ;; ??? Write truncdisi pattern using sra?
4285 (define_expand "zero_extendsidi2"
4286 [(set (match_operand:DI 0 "register_operand" "")
4287 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4291 (define_insn "*zero_extendsidi2_insn_sp64"
4292 [(set (match_operand:DI 0 "register_operand" "=r,r")
4293 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4294 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4298 [(set_attr "type" "shift,load")])
4300 (define_insn "*zero_extendsidi2_insn_sp32"
4301 [(set (match_operand:DI 0 "register_operand" "=r")
4302 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4305 [(set_attr "length" "2")])
4308 [(set (match_operand:DI 0 "register_operand" "")
4309 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4310 "! TARGET_ARCH64 && reload_completed"
4311 [(set (match_dup 2) (match_dup 3))
4312 (set (match_dup 4) (match_dup 5))]
4317 dest1 = gen_highpart (SImode, operands[0]);
4318 dest2 = gen_lowpart (SImode, operands[0]);
4320 /* Swap the order in case of overlap. */
4321 if (REGNO (dest1) == REGNO (operands[1]))
4323 operands[2] = dest2;
4324 operands[3] = operands[1];
4325 operands[4] = dest1;
4326 operands[5] = const0_rtx;
4330 operands[2] = dest1;
4331 operands[3] = const0_rtx;
4332 operands[4] = dest2;
4333 operands[5] = operands[1];
4337 ;; Simplify comparisons of extended values.
4339 (define_insn "*cmp_zero_extendqisi2"
4341 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4344 "andcc\\t%0, 0xff, %%g0"
4345 [(set_attr "type" "compare")])
4347 (define_insn "*cmp_zero_qi"
4349 (compare:CC (match_operand:QI 0 "register_operand" "r")
4352 "andcc\\t%0, 0xff, %%g0"
4353 [(set_attr "type" "compare")])
4355 (define_insn "*cmp_zero_extendqisi2_set"
4357 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4359 (set (match_operand:SI 0 "register_operand" "=r")
4360 (zero_extend:SI (match_dup 1)))]
4362 "andcc\\t%1, 0xff, %0"
4363 [(set_attr "type" "compare")])
4365 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4367 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4370 (set (match_operand:SI 0 "register_operand" "=r")
4371 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4373 "andcc\\t%1, 0xff, %0"
4374 [(set_attr "type" "compare")])
4376 (define_insn "*cmp_zero_extendqidi2"
4378 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4381 "andcc\\t%0, 0xff, %%g0"
4382 [(set_attr "type" "compare")])
4384 (define_insn "*cmp_zero_qi_sp64"
4386 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4389 "andcc\\t%0, 0xff, %%g0"
4390 [(set_attr "type" "compare")])
4392 (define_insn "*cmp_zero_extendqidi2_set"
4394 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4396 (set (match_operand:DI 0 "register_operand" "=r")
4397 (zero_extend:DI (match_dup 1)))]
4399 "andcc\\t%1, 0xff, %0"
4400 [(set_attr "type" "compare")])
4402 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4404 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4407 (set (match_operand:DI 0 "register_operand" "=r")
4408 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4410 "andcc\\t%1, 0xff, %0"
4411 [(set_attr "type" "compare")])
4413 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4415 (define_insn "*cmp_siqi_trunc"
4417 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4420 "andcc\\t%0, 0xff, %%g0"
4421 [(set_attr "type" "compare")])
4423 (define_insn "*cmp_siqi_trunc_set"
4425 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4427 (set (match_operand:QI 0 "register_operand" "=r")
4428 (subreg:QI (match_dup 1) 3))]
4430 "andcc\\t%1, 0xff, %0"
4431 [(set_attr "type" "compare")])
4433 (define_insn "*cmp_diqi_trunc"
4435 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4438 "andcc\\t%0, 0xff, %%g0"
4439 [(set_attr "type" "compare")])
4441 (define_insn "*cmp_diqi_trunc_set"
4443 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4445 (set (match_operand:QI 0 "register_operand" "=r")
4446 (subreg:QI (match_dup 1) 7))]
4448 "andcc\\t%1, 0xff, %0"
4449 [(set_attr "type" "compare")])
4451 ;;- sign extension instructions
4453 ;; These patterns originally accepted general_operands, however, slightly
4454 ;; better code is generated by only accepting register_operands, and then
4455 ;; letting combine generate the lds[hb] insns.
4457 (define_expand "extendhisi2"
4458 [(set (match_operand:SI 0 "register_operand" "")
4459 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4463 rtx temp = gen_reg_rtx (SImode);
4464 rtx shift_16 = GEN_INT (16);
4465 int op1_subbyte = 0;
4467 if (GET_CODE (operand1) == SUBREG)
4469 op1_subbyte = SUBREG_BYTE (operand1);
4470 op1_subbyte /= GET_MODE_SIZE (SImode);
4471 op1_subbyte *= GET_MODE_SIZE (SImode);
4472 operand1 = XEXP (operand1, 0);
4475 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4477 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4481 (define_insn "*sign_extendhisi2_insn"
4482 [(set (match_operand:SI 0 "register_operand" "=r")
4483 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4486 [(set_attr "type" "sload")
4487 (set_attr "us3load_type" "3cycle")])
4489 (define_expand "extendqihi2"
4490 [(set (match_operand:HI 0 "register_operand" "")
4491 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4495 rtx temp = gen_reg_rtx (SImode);
4496 rtx shift_24 = GEN_INT (24);
4497 int op1_subbyte = 0;
4498 int op0_subbyte = 0;
4500 if (GET_CODE (operand1) == SUBREG)
4502 op1_subbyte = SUBREG_BYTE (operand1);
4503 op1_subbyte /= GET_MODE_SIZE (SImode);
4504 op1_subbyte *= GET_MODE_SIZE (SImode);
4505 operand1 = XEXP (operand1, 0);
4507 if (GET_CODE (operand0) == SUBREG)
4509 op0_subbyte = SUBREG_BYTE (operand0);
4510 op0_subbyte /= GET_MODE_SIZE (SImode);
4511 op0_subbyte *= GET_MODE_SIZE (SImode);
4512 operand0 = XEXP (operand0, 0);
4514 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4516 if (GET_MODE (operand0) != SImode)
4517 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4518 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4522 (define_insn "*sign_extendqihi2_insn"
4523 [(set (match_operand:HI 0 "register_operand" "=r")
4524 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4527 [(set_attr "type" "sload")
4528 (set_attr "us3load_type" "3cycle")])
4530 (define_expand "extendqisi2"
4531 [(set (match_operand:SI 0 "register_operand" "")
4532 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4536 rtx temp = gen_reg_rtx (SImode);
4537 rtx shift_24 = GEN_INT (24);
4538 int op1_subbyte = 0;
4540 if (GET_CODE (operand1) == SUBREG)
4542 op1_subbyte = SUBREG_BYTE (operand1);
4543 op1_subbyte /= GET_MODE_SIZE (SImode);
4544 op1_subbyte *= GET_MODE_SIZE (SImode);
4545 operand1 = XEXP (operand1, 0);
4548 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4550 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4554 (define_insn "*sign_extendqisi2_insn"
4555 [(set (match_operand:SI 0 "register_operand" "=r")
4556 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4559 [(set_attr "type" "sload")
4560 (set_attr "us3load_type" "3cycle")])
4562 (define_expand "extendqidi2"
4563 [(set (match_operand:DI 0 "register_operand" "")
4564 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4568 rtx temp = gen_reg_rtx (DImode);
4569 rtx shift_56 = GEN_INT (56);
4570 int op1_subbyte = 0;
4572 if (GET_CODE (operand1) == SUBREG)
4574 op1_subbyte = SUBREG_BYTE (operand1);
4575 op1_subbyte /= GET_MODE_SIZE (DImode);
4576 op1_subbyte *= GET_MODE_SIZE (DImode);
4577 operand1 = XEXP (operand1, 0);
4580 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4582 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4586 (define_insn "*sign_extendqidi2_insn"
4587 [(set (match_operand:DI 0 "register_operand" "=r")
4588 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4591 [(set_attr "type" "sload")
4592 (set_attr "us3load_type" "3cycle")])
4594 (define_expand "extendhidi2"
4595 [(set (match_operand:DI 0 "register_operand" "")
4596 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4600 rtx temp = gen_reg_rtx (DImode);
4601 rtx shift_48 = GEN_INT (48);
4602 int op1_subbyte = 0;
4604 if (GET_CODE (operand1) == SUBREG)
4606 op1_subbyte = SUBREG_BYTE (operand1);
4607 op1_subbyte /= GET_MODE_SIZE (DImode);
4608 op1_subbyte *= GET_MODE_SIZE (DImode);
4609 operand1 = XEXP (operand1, 0);
4612 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4614 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4618 (define_insn "*sign_extendhidi2_insn"
4619 [(set (match_operand:DI 0 "register_operand" "=r")
4620 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4623 [(set_attr "type" "sload")
4624 (set_attr "us3load_type" "3cycle")])
4626 (define_expand "extendsidi2"
4627 [(set (match_operand:DI 0 "register_operand" "")
4628 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4632 (define_insn "*sign_extendsidi2_insn"
4633 [(set (match_operand:DI 0 "register_operand" "=r,r")
4634 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4639 [(set_attr "type" "shift,sload")
4640 (set_attr "us3load_type" "*,3cycle")])
4642 ;; Special pattern for optimizing bit-field compares. This is needed
4643 ;; because combine uses this as a canonical form.
4645 (define_insn "*cmp_zero_extract"
4648 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4649 (match_operand:SI 1 "small_int_or_double" "n")
4650 (match_operand:SI 2 "small_int_or_double" "n"))
4652 "(GET_CODE (operands[2]) == CONST_INT
4653 && INTVAL (operands[2]) > 19)
4654 || (GET_CODE (operands[2]) == CONST_DOUBLE
4655 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4658 int len = (GET_CODE (operands[1]) == CONST_INT
4659 ? INTVAL (operands[1])
4660 : CONST_DOUBLE_LOW (operands[1]));
4662 (GET_CODE (operands[2]) == CONST_INT
4663 ? INTVAL (operands[2])
4664 : CONST_DOUBLE_LOW (operands[2])) - len;
4665 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4667 operands[1] = GEN_INT (mask);
4668 return \"andcc\\t%0, %1, %%g0\";
4670 [(set_attr "type" "compare")])
4672 (define_insn "*cmp_zero_extract_sp64"
4675 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4676 (match_operand:SI 1 "small_int_or_double" "n")
4677 (match_operand:SI 2 "small_int_or_double" "n"))
4680 && ((GET_CODE (operands[2]) == CONST_INT
4681 && INTVAL (operands[2]) > 51)
4682 || (GET_CODE (operands[2]) == CONST_DOUBLE
4683 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4686 int len = (GET_CODE (operands[1]) == CONST_INT
4687 ? INTVAL (operands[1])
4688 : CONST_DOUBLE_LOW (operands[1]));
4690 (GET_CODE (operands[2]) == CONST_INT
4691 ? INTVAL (operands[2])
4692 : CONST_DOUBLE_LOW (operands[2])) - len;
4693 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4695 operands[1] = GEN_INT (mask);
4696 return \"andcc\\t%0, %1, %%g0\";
4698 [(set_attr "type" "compare")])
4700 ;; Conversions between float, double and long double.
4702 (define_insn "extendsfdf2"
4703 [(set (match_operand:DF 0 "register_operand" "=e")
4705 (match_operand:SF 1 "register_operand" "f")))]
4708 [(set_attr "type" "fp")
4709 (set_attr "fptype" "double")])
4711 (define_expand "extendsftf2"
4712 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4714 (match_operand:SF 1 "register_operand" "")))]
4715 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4716 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4718 (define_insn "*extendsftf2_hq"
4719 [(set (match_operand:TF 0 "register_operand" "=e")
4721 (match_operand:SF 1 "register_operand" "f")))]
4722 "TARGET_FPU && TARGET_HARD_QUAD"
4724 [(set_attr "type" "fp")])
4726 (define_expand "extenddftf2"
4727 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4729 (match_operand:DF 1 "register_operand" "")))]
4730 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4731 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4733 (define_insn "*extenddftf2_hq"
4734 [(set (match_operand:TF 0 "register_operand" "=e")
4736 (match_operand:DF 1 "register_operand" "e")))]
4737 "TARGET_FPU && TARGET_HARD_QUAD"
4739 [(set_attr "type" "fp")])
4741 (define_insn "truncdfsf2"
4742 [(set (match_operand:SF 0 "register_operand" "=f")
4744 (match_operand:DF 1 "register_operand" "e")))]
4747 [(set_attr "type" "fp")
4748 (set_attr "fptype" "double")])
4750 (define_expand "trunctfsf2"
4751 [(set (match_operand:SF 0 "register_operand" "")
4753 (match_operand:TF 1 "general_operand" "")))]
4754 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4755 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4757 (define_insn "*trunctfsf2_hq"
4758 [(set (match_operand:SF 0 "register_operand" "=f")
4760 (match_operand:TF 1 "register_operand" "e")))]
4761 "TARGET_FPU && TARGET_HARD_QUAD"
4763 [(set_attr "type" "fp")])
4765 (define_expand "trunctfdf2"
4766 [(set (match_operand:DF 0 "register_operand" "")
4768 (match_operand:TF 1 "general_operand" "")))]
4769 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4770 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4772 (define_insn "*trunctfdf2_hq"
4773 [(set (match_operand:DF 0 "register_operand" "=e")
4775 (match_operand:TF 1 "register_operand" "e")))]
4776 "TARGET_FPU && TARGET_HARD_QUAD"
4778 [(set_attr "type" "fp")])
4780 ;; Conversion between fixed point and floating point.
4782 (define_insn "floatsisf2"
4783 [(set (match_operand:SF 0 "register_operand" "=f")
4784 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4787 [(set_attr "type" "fp")
4788 (set_attr "fptype" "double")])
4790 (define_insn "floatsidf2"
4791 [(set (match_operand:DF 0 "register_operand" "=e")
4792 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4795 [(set_attr "type" "fp")
4796 (set_attr "fptype" "double")])
4798 (define_expand "floatsitf2"
4799 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4800 (float:TF (match_operand:SI 1 "register_operand" "")))]
4801 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4802 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4804 (define_insn "*floatsitf2_hq"
4805 [(set (match_operand:TF 0 "register_operand" "=e")
4806 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4807 "TARGET_FPU && TARGET_HARD_QUAD"
4809 [(set_attr "type" "fp")])
4811 (define_expand "floatunssitf2"
4812 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4813 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4814 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4815 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4817 ;; Now the same for 64 bit sources.
4819 (define_insn "floatdisf2"
4820 [(set (match_operand:SF 0 "register_operand" "=f")
4821 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4822 "TARGET_V9 && TARGET_FPU"
4824 [(set_attr "type" "fp")
4825 (set_attr "fptype" "double")])
4827 (define_expand "floatunsdisf2"
4828 [(use (match_operand:SF 0 "register_operand" ""))
4829 (use (match_operand:DI 1 "register_operand" ""))]
4830 "TARGET_ARCH64 && TARGET_FPU"
4831 "sparc_emit_floatunsdi (operands); DONE;")
4833 (define_insn "floatdidf2"
4834 [(set (match_operand:DF 0 "register_operand" "=e")
4835 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4836 "TARGET_V9 && TARGET_FPU"
4838 [(set_attr "type" "fp")
4839 (set_attr "fptype" "double")])
4841 (define_expand "floatunsdidf2"
4842 [(use (match_operand:DF 0 "register_operand" ""))
4843 (use (match_operand:DI 1 "register_operand" ""))]
4844 "TARGET_ARCH64 && TARGET_FPU"
4845 "sparc_emit_floatunsdi (operands); DONE;")
4847 (define_expand "floatditf2"
4848 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4849 (float:TF (match_operand:DI 1 "register_operand" "")))]
4850 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4851 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4853 (define_insn "*floatditf2_hq"
4854 [(set (match_operand:TF 0 "register_operand" "=e")
4855 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4856 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4858 [(set_attr "type" "fp")])
4860 (define_expand "floatunsditf2"
4861 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4862 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4863 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4864 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4866 ;; Convert a float to an actual integer.
4867 ;; Truncation is performed as part of the conversion.
4869 (define_insn "fix_truncsfsi2"
4870 [(set (match_operand:SI 0 "register_operand" "=f")
4871 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4874 [(set_attr "type" "fp")
4875 (set_attr "fptype" "double")])
4877 (define_insn "fix_truncdfsi2"
4878 [(set (match_operand:SI 0 "register_operand" "=f")
4879 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4882 [(set_attr "type" "fp")
4883 (set_attr "fptype" "double")])
4885 (define_expand "fix_trunctfsi2"
4886 [(set (match_operand:SI 0 "register_operand" "")
4887 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4888 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4889 "emit_tfmode_cvt (FIX, operands); DONE;")
4891 (define_insn "*fix_trunctfsi2_hq"
4892 [(set (match_operand:SI 0 "register_operand" "=f")
4893 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4894 "TARGET_FPU && TARGET_HARD_QUAD"
4896 [(set_attr "type" "fp")])
4898 (define_expand "fixuns_trunctfsi2"
4899 [(set (match_operand:SI 0 "register_operand" "")
4900 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4901 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4902 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4904 ;; Now the same, for V9 targets
4906 (define_insn "fix_truncsfdi2"
4907 [(set (match_operand:DI 0 "register_operand" "=e")
4908 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4909 "TARGET_V9 && TARGET_FPU"
4911 [(set_attr "type" "fp")
4912 (set_attr "fptype" "double")])
4914 (define_insn "fix_truncdfdi2"
4915 [(set (match_operand:DI 0 "register_operand" "=e")
4916 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4917 "TARGET_V9 && TARGET_FPU"
4919 [(set_attr "type" "fp")
4920 (set_attr "fptype" "double")])
4922 (define_expand "fix_trunctfdi2"
4923 [(set (match_operand:DI 0 "register_operand" "")
4924 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4925 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4926 "emit_tfmode_cvt (FIX, operands); DONE;")
4928 (define_insn "*fix_trunctfdi2_hq"
4929 [(set (match_operand:DI 0 "register_operand" "=e")
4930 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4931 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4933 [(set_attr "type" "fp")])
4935 (define_expand "fixuns_trunctfdi2"
4936 [(set (match_operand:DI 0 "register_operand" "")
4937 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4938 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4939 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4941 ;;- arithmetic instructions
4943 (define_expand "adddi3"
4944 [(set (match_operand:DI 0 "register_operand" "=r")
4945 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4946 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4952 if (! TARGET_ARCH64)
4954 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4955 gen_rtx_SET (VOIDmode, operands[0],
4956 gen_rtx_PLUS (DImode, operands[1],
4958 gen_rtx_CLOBBER (VOIDmode,
4959 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4962 if (arith_double_4096_operand(operands[2], DImode))
4964 switch (GET_CODE (operands[1]))
4966 case CONST_INT: i = INTVAL (operands[1]); break;
4967 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4969 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4970 gen_rtx_MINUS (DImode, operands[1],
4974 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4979 (define_insn "adddi3_insn_sp32"
4980 [(set (match_operand:DI 0 "register_operand" "=r")
4981 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4982 (match_operand:DI 2 "arith_double_operand" "rHI")))
4983 (clobber (reg:CC 100))]
4986 [(set_attr "length" "2")])
4989 [(set (match_operand:DI 0 "register_operand" "")
4990 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
4991 (match_operand:DI 2 "arith_double_operand" "")))
4992 (clobber (reg:CC 100))]
4993 "! TARGET_ARCH64 && reload_completed"
4994 [(parallel [(set (reg:CC_NOOV 100)
4995 (compare:CC_NOOV (plus:SI (match_dup 4)
4999 (plus:SI (match_dup 4) (match_dup 5)))])
5001 (plus:SI (plus:SI (match_dup 7)
5003 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5006 operands[3] = gen_lowpart (SImode, operands[0]);
5007 operands[4] = gen_lowpart (SImode, operands[1]);
5008 operands[5] = gen_lowpart (SImode, operands[2]);
5009 operands[6] = gen_highpart (SImode, operands[0]);
5010 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5011 #if HOST_BITS_PER_WIDE_INT == 32
5012 if (GET_CODE (operands[2]) == CONST_INT)
5014 if (INTVAL (operands[2]) < 0)
5015 operands[8] = constm1_rtx;
5017 operands[8] = const0_rtx;
5021 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5025 [(set (match_operand:DI 0 "register_operand" "")
5026 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5027 (match_operand:DI 2 "arith_double_operand" "")))
5028 (clobber (reg:CC 100))]
5029 "! TARGET_ARCH64 && reload_completed"
5030 [(parallel [(set (reg:CC_NOOV 100)
5031 (compare:CC_NOOV (minus:SI (match_dup 4)
5035 (minus:SI (match_dup 4) (match_dup 5)))])
5037 (minus:SI (minus:SI (match_dup 7)
5039 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5042 operands[3] = gen_lowpart (SImode, operands[0]);
5043 operands[4] = gen_lowpart (SImode, operands[1]);
5044 operands[5] = gen_lowpart (SImode, operands[2]);
5045 operands[6] = gen_highpart (SImode, operands[0]);
5046 operands[7] = gen_highpart (SImode, operands[1]);
5047 #if HOST_BITS_PER_WIDE_INT == 32
5048 if (GET_CODE (operands[2]) == CONST_INT)
5050 if (INTVAL (operands[2]) < 0)
5051 operands[8] = constm1_rtx;
5053 operands[8] = const0_rtx;
5057 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5060 ;; LTU here means "carry set"
5062 [(set (match_operand:SI 0 "register_operand" "=r")
5063 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5064 (match_operand:SI 2 "arith_operand" "rI"))
5065 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5068 [(set_attr "type" "misc")])
5070 (define_insn "*addx_extend_sp32"
5071 [(set (match_operand:DI 0 "register_operand" "=r")
5072 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5073 (match_operand:SI 2 "arith_operand" "rI"))
5074 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5077 [(set_attr "length" "2")])
5080 [(set (match_operand:DI 0 "register_operand" "")
5081 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5082 (match_operand:SI 2 "arith_operand" ""))
5083 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5084 "! TARGET_ARCH64 && reload_completed"
5085 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5086 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5087 (set (match_dup 4) (const_int 0))]
5088 "operands[3] = gen_lowpart (SImode, operands[0]);
5089 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5091 (define_insn "*addx_extend_sp64"
5092 [(set (match_operand:DI 0 "register_operand" "=r")
5093 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5094 (match_operand:SI 2 "arith_operand" "rI"))
5095 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5097 "addx\\t%r1, %2, %0"
5098 [(set_attr "type" "misc")])
5101 [(set (match_operand:SI 0 "register_operand" "=r")
5102 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5103 (match_operand:SI 2 "arith_operand" "rI"))
5104 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5106 "subx\\t%r1, %2, %0"
5107 [(set_attr "type" "misc")])
5109 (define_insn "*subx_extend_sp64"
5110 [(set (match_operand:DI 0 "register_operand" "=r")
5111 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5112 (match_operand:SI 2 "arith_operand" "rI"))
5113 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5115 "subx\\t%r1, %2, %0"
5116 [(set_attr "type" "misc")])
5118 (define_insn "*subx_extend"
5119 [(set (match_operand:DI 0 "register_operand" "=r")
5120 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5121 (match_operand:SI 2 "arith_operand" "rI"))
5122 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5125 [(set_attr "length" "2")])
5128 [(set (match_operand:DI 0 "register_operand" "")
5129 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5130 (match_operand:SI 2 "arith_operand" ""))
5131 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5132 "! TARGET_ARCH64 && reload_completed"
5133 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5134 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5135 (set (match_dup 4) (const_int 0))]
5136 "operands[3] = gen_lowpart (SImode, operands[0]);
5137 operands[4] = gen_highpart (SImode, operands[0]);")
5140 [(set (match_operand:DI 0 "register_operand" "=r")
5141 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5142 (match_operand:DI 2 "register_operand" "r")))
5143 (clobber (reg:CC 100))]
5146 [(set_attr "length" "2")])
5149 [(set (match_operand:DI 0 "register_operand" "")
5150 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5151 (match_operand:DI 2 "register_operand" "")))
5152 (clobber (reg:CC 100))]
5153 "! TARGET_ARCH64 && reload_completed"
5154 [(parallel [(set (reg:CC_NOOV 100)
5155 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5157 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5159 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5160 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5161 "operands[3] = gen_lowpart (SImode, operands[2]);
5162 operands[4] = gen_highpart (SImode, operands[2]);
5163 operands[5] = gen_lowpart (SImode, operands[0]);
5164 operands[6] = gen_highpart (SImode, operands[0]);")
5166 (define_insn "*adddi3_sp64"
5167 [(set (match_operand:DI 0 "register_operand" "=r")
5168 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5169 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5173 (define_expand "addsi3"
5174 [(set (match_operand:SI 0 "register_operand" "=r,d")
5175 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5176 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5180 if (arith_4096_operand(operands[2], SImode))
5182 if (GET_CODE (operands[1]) == CONST_INT)
5183 emit_insn (gen_movsi (operands[0],
5184 GEN_INT (INTVAL (operands[1]) + 4096)));
5186 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5187 gen_rtx_MINUS (SImode, operands[1],
5193 (define_insn "*addsi3"
5194 [(set (match_operand:SI 0 "register_operand" "=r,d")
5195 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5196 (match_operand:SI 2 "arith_operand" "rI,d")))]
5200 fpadd32s\\t%1, %2, %0"
5201 [(set_attr "type" "*,fp")])
5203 (define_insn "*cmp_cc_plus"
5204 [(set (reg:CC_NOOV 100)
5205 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5206 (match_operand:SI 1 "arith_operand" "rI"))
5209 "addcc\\t%0, %1, %%g0"
5210 [(set_attr "type" "compare")])
5212 (define_insn "*cmp_ccx_plus"
5213 [(set (reg:CCX_NOOV 100)
5214 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5215 (match_operand:DI 1 "arith_double_operand" "rHI"))
5218 "addcc\\t%0, %1, %%g0"
5219 [(set_attr "type" "compare")])
5221 (define_insn "*cmp_cc_plus_set"
5222 [(set (reg:CC_NOOV 100)
5223 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5224 (match_operand:SI 2 "arith_operand" "rI"))
5226 (set (match_operand:SI 0 "register_operand" "=r")
5227 (plus:SI (match_dup 1) (match_dup 2)))]
5229 "addcc\\t%1, %2, %0"
5230 [(set_attr "type" "compare")])
5232 (define_insn "*cmp_ccx_plus_set"
5233 [(set (reg:CCX_NOOV 100)
5234 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5235 (match_operand:DI 2 "arith_double_operand" "rHI"))
5237 (set (match_operand:DI 0 "register_operand" "=r")
5238 (plus:DI (match_dup 1) (match_dup 2)))]
5240 "addcc\\t%1, %2, %0"
5241 [(set_attr "type" "compare")])
5243 (define_expand "subdi3"
5244 [(set (match_operand:DI 0 "register_operand" "=r")
5245 (minus:DI (match_operand:DI 1 "register_operand" "r")
5246 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5250 if (! TARGET_ARCH64)
5252 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5253 gen_rtx_SET (VOIDmode, operands[0],
5254 gen_rtx_MINUS (DImode, operands[1],
5256 gen_rtx_CLOBBER (VOIDmode,
5257 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5260 if (arith_double_4096_operand(operands[2], DImode))
5262 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5263 gen_rtx_PLUS (DImode, operands[1],
5269 (define_insn "*subdi3_sp32"
5270 [(set (match_operand:DI 0 "register_operand" "=r")
5271 (minus:DI (match_operand:DI 1 "register_operand" "r")
5272 (match_operand:DI 2 "arith_double_operand" "rHI")))
5273 (clobber (reg:CC 100))]
5276 [(set_attr "length" "2")])
5279 [(set (match_operand:DI 0 "register_operand" "")
5280 (minus:DI (match_operand:DI 1 "register_operand" "")
5281 (match_operand:DI 2 "arith_double_operand" "")))
5282 (clobber (reg:CC 100))]
5285 && (GET_CODE (operands[2]) == CONST_INT
5286 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5287 [(clobber (const_int 0))]
5292 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5293 lowp = gen_lowpart (SImode, operands[2]);
5294 if ((lowp == const0_rtx)
5295 && (operands[0] == operands[1]))
5297 emit_insn (gen_rtx_SET (VOIDmode,
5298 gen_highpart (SImode, operands[0]),
5299 gen_rtx_MINUS (SImode,
5300 gen_highpart_mode (SImode, DImode,
5306 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5307 gen_lowpart (SImode, operands[1]),
5309 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5310 gen_highpart_mode (SImode, DImode, operands[1]),
5317 [(set (match_operand:DI 0 "register_operand" "")
5318 (minus:DI (match_operand:DI 1 "register_operand" "")
5319 (match_operand:DI 2 "register_operand" "")))
5320 (clobber (reg:CC 100))]
5322 && reload_completed"
5323 [(clobber (const_int 0))]
5326 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5327 gen_lowpart (SImode, operands[1]),
5328 gen_lowpart (SImode, operands[2])));
5329 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5330 gen_highpart (SImode, operands[1]),
5331 gen_highpart (SImode, operands[2])));
5336 [(set (match_operand:DI 0 "register_operand" "=r")
5337 (minus:DI (match_operand:DI 1 "register_operand" "r")
5338 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5339 (clobber (reg:CC 100))]
5342 [(set_attr "length" "2")])
5345 [(set (match_operand:DI 0 "register_operand" "")
5346 (minus:DI (match_operand:DI 1 "register_operand" "")
5347 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5348 (clobber (reg:CC 100))]
5349 "! TARGET_ARCH64 && reload_completed"
5350 [(parallel [(set (reg:CC_NOOV 100)
5351 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5353 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5355 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5356 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5357 "operands[3] = gen_lowpart (SImode, operands[1]);
5358 operands[4] = gen_highpart (SImode, operands[1]);
5359 operands[5] = gen_lowpart (SImode, operands[0]);
5360 operands[6] = gen_highpart (SImode, operands[0]);")
5362 (define_insn "*subdi3_sp64"
5363 [(set (match_operand:DI 0 "register_operand" "=r")
5364 (minus:DI (match_operand:DI 1 "register_operand" "r")
5365 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5369 (define_expand "subsi3"
5370 [(set (match_operand:SI 0 "register_operand" "=r,d")
5371 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5372 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5376 if (arith_4096_operand(operands[2], SImode))
5378 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5379 gen_rtx_PLUS (SImode, operands[1],
5385 (define_insn "*subsi3"
5386 [(set (match_operand:SI 0 "register_operand" "=r,d")
5387 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5388 (match_operand:SI 2 "arith_operand" "rI,d")))]
5392 fpsub32s\\t%1, %2, %0"
5393 [(set_attr "type" "*,fp")])
5395 (define_insn "*cmp_minus_cc"
5396 [(set (reg:CC_NOOV 100)
5397 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5398 (match_operand:SI 1 "arith_operand" "rI"))
5401 "subcc\\t%r0, %1, %%g0"
5402 [(set_attr "type" "compare")])
5404 (define_insn "*cmp_minus_ccx"
5405 [(set (reg:CCX_NOOV 100)
5406 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5407 (match_operand:DI 1 "arith_double_operand" "rHI"))
5410 "subcc\\t%0, %1, %%g0"
5411 [(set_attr "type" "compare")])
5413 (define_insn "cmp_minus_cc_set"
5414 [(set (reg:CC_NOOV 100)
5415 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5416 (match_operand:SI 2 "arith_operand" "rI"))
5418 (set (match_operand:SI 0 "register_operand" "=r")
5419 (minus:SI (match_dup 1) (match_dup 2)))]
5421 "subcc\\t%r1, %2, %0"
5422 [(set_attr "type" "compare")])
5424 (define_insn "*cmp_minus_ccx_set"
5425 [(set (reg:CCX_NOOV 100)
5426 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5427 (match_operand:DI 2 "arith_double_operand" "rHI"))
5429 (set (match_operand:DI 0 "register_operand" "=r")
5430 (minus:DI (match_dup 1) (match_dup 2)))]
5432 "subcc\\t%1, %2, %0"
5433 [(set_attr "type" "compare")])
5435 ;; Integer Multiply/Divide.
5437 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5438 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5440 (define_insn "mulsi3"
5441 [(set (match_operand:SI 0 "register_operand" "=r")
5442 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5443 (match_operand:SI 2 "arith_operand" "rI")))]
5446 [(set_attr "type" "imul")])
5448 (define_expand "muldi3"
5449 [(set (match_operand:DI 0 "register_operand" "=r")
5450 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5451 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5452 "TARGET_ARCH64 || TARGET_V8PLUS"
5457 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5462 (define_insn "*muldi3_sp64"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5464 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5465 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5468 [(set_attr "type" "imul")])
5470 ;; V8plus wide multiply.
5472 (define_insn "muldi3_v8plus"
5473 [(set (match_operand:DI 0 "register_operand" "=r,h")
5474 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5475 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5476 (clobber (match_scratch:SI 3 "=&h,X"))
5477 (clobber (match_scratch:SI 4 "=&h,X"))]
5481 if (sparc_check_64 (operands[1], insn) <= 0)
5482 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5483 if (which_alternative == 1)
5484 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5485 if (GET_CODE (operands[2]) == CONST_INT)
5487 if (which_alternative == 1)
5488 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5490 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\";
5492 else if (rtx_equal_p (operands[1], operands[2]))
5494 if (which_alternative == 1)
5495 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %H1, %L0\;srlx\\t%L0, 32, %H0\";
5497 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\";
5499 if (sparc_check_64 (operands[2], insn) <= 0)
5500 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5501 if (which_alternative == 1)
5502 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\";
5504 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\";
5506 [(set_attr "type" "multi")
5507 (set_attr "length" "9,8")])
5509 (define_insn "*cmp_mul_set"
5511 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5512 (match_operand:SI 2 "arith_operand" "rI"))
5514 (set (match_operand:SI 0 "register_operand" "=r")
5515 (mult:SI (match_dup 1) (match_dup 2)))]
5516 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5517 "smulcc\\t%1, %2, %0"
5518 [(set_attr "type" "imul")])
5520 (define_expand "mulsidi3"
5521 [(set (match_operand:DI 0 "register_operand" "")
5522 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5523 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5527 if (CONSTANT_P (operands[2]))
5530 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5533 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5539 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5544 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5545 ;; registers can hold 64 bit values in the V8plus environment.
5547 (define_insn "mulsidi3_v8plus"
5548 [(set (match_operand:DI 0 "register_operand" "=h,r")
5549 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5550 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5551 (clobber (match_scratch:SI 3 "=X,&h"))]
5554 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5555 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5556 [(set_attr "type" "multi")
5557 (set_attr "length" "2,3")])
5560 (define_insn "const_mulsidi3_v8plus"
5561 [(set (match_operand:DI 0 "register_operand" "=h,r")
5562 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5563 (match_operand:SI 2 "small_int" "I,I")))
5564 (clobber (match_scratch:SI 3 "=X,&h"))]
5567 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5568 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5569 [(set_attr "type" "multi")
5570 (set_attr "length" "2,3")])
5573 (define_insn "*mulsidi3_sp32"
5574 [(set (match_operand:DI 0 "register_operand" "=r")
5575 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5576 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5580 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5583 (if_then_else (eq_attr "isa" "sparclet")
5584 (const_string "imul") (const_string "multi")))
5585 (set (attr "length")
5586 (if_then_else (eq_attr "isa" "sparclet")
5587 (const_int 1) (const_int 2)))])
5589 (define_insn "*mulsidi3_sp64"
5590 [(set (match_operand:DI 0 "register_operand" "=r")
5591 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5592 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5593 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5595 [(set_attr "type" "imul")])
5597 ;; Extra pattern, because sign_extend of a constant isn't valid.
5600 (define_insn "const_mulsidi3_sp32"
5601 [(set (match_operand:DI 0 "register_operand" "=r")
5602 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5603 (match_operand:SI 2 "small_int" "I")))]
5607 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5610 (if_then_else (eq_attr "isa" "sparclet")
5611 (const_string "imul") (const_string "multi")))
5612 (set (attr "length")
5613 (if_then_else (eq_attr "isa" "sparclet")
5614 (const_int 1) (const_int 2)))])
5616 (define_insn "const_mulsidi3_sp64"
5617 [(set (match_operand:DI 0 "register_operand" "=r")
5618 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5619 (match_operand:SI 2 "small_int" "I")))]
5620 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5622 [(set_attr "type" "imul")])
5624 (define_expand "smulsi3_highpart"
5625 [(set (match_operand:SI 0 "register_operand" "")
5627 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5628 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5630 "TARGET_HARD_MUL && TARGET_ARCH32"
5633 if (CONSTANT_P (operands[2]))
5637 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5643 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5648 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5649 operands[2], GEN_INT (32)));
5655 (define_insn "smulsi3_highpart_v8plus"
5656 [(set (match_operand:SI 0 "register_operand" "=h,r")
5658 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5659 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5660 (match_operand:SI 3 "const_int_operand" "i,i"))))
5661 (clobber (match_scratch:SI 4 "=X,&h"))]
5664 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
5665 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
5666 [(set_attr "type" "multi")
5667 (set_attr "length" "2")])
5669 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5672 [(set (match_operand:SI 0 "register_operand" "=h,r")
5675 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5676 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5677 (match_operand:SI 3 "const_int_operand" "i,i"))
5679 (clobber (match_scratch:SI 4 "=X,&h"))]
5682 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5683 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5684 [(set_attr "type" "multi")
5685 (set_attr "length" "2")])
5688 (define_insn "const_smulsi3_highpart_v8plus"
5689 [(set (match_operand:SI 0 "register_operand" "=h,r")
5691 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5692 (match_operand 2 "small_int" "i,i"))
5693 (match_operand:SI 3 "const_int_operand" "i,i"))))
5694 (clobber (match_scratch:SI 4 "=X,&h"))]
5697 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5698 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5699 [(set_attr "type" "multi")
5700 (set_attr "length" "2")])
5703 (define_insn "*smulsi3_highpart_sp32"
5704 [(set (match_operand:SI 0 "register_operand" "=r")
5706 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5707 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5710 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5711 [(set_attr "type" "multi")
5712 (set_attr "length" "2")])
5715 (define_insn "const_smulsi3_highpart"
5716 [(set (match_operand:SI 0 "register_operand" "=r")
5718 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5719 (match_operand:SI 2 "register_operand" "r"))
5722 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5723 [(set_attr "type" "multi")
5724 (set_attr "length" "2")])
5726 (define_expand "umulsidi3"
5727 [(set (match_operand:DI 0 "register_operand" "")
5728 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5729 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5733 if (CONSTANT_P (operands[2]))
5736 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5739 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5745 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5751 (define_insn "umulsidi3_v8plus"
5752 [(set (match_operand:DI 0 "register_operand" "=h,r")
5753 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5754 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5755 (clobber (match_scratch:SI 3 "=X,&h"))]
5758 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5759 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5760 [(set_attr "type" "multi")
5761 (set_attr "length" "2,3")])
5764 (define_insn "*umulsidi3_sp32"
5765 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5767 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5771 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5774 (if_then_else (eq_attr "isa" "sparclet")
5775 (const_string "imul") (const_string "multi")))
5776 (set (attr "length")
5777 (if_then_else (eq_attr "isa" "sparclet")
5778 (const_int 1) (const_int 2)))])
5780 (define_insn "*umulsidi3_sp64"
5781 [(set (match_operand:DI 0 "register_operand" "=r")
5782 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5783 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5784 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5786 [(set_attr "type" "imul")])
5788 ;; Extra pattern, because sign_extend of a constant isn't valid.
5791 (define_insn "const_umulsidi3_sp32"
5792 [(set (match_operand:DI 0 "register_operand" "=r")
5793 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5794 (match_operand:SI 2 "uns_small_int" "")))]
5798 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5801 (if_then_else (eq_attr "isa" "sparclet")
5802 (const_string "imul") (const_string "multi")))
5803 (set (attr "length")
5804 (if_then_else (eq_attr "isa" "sparclet")
5805 (const_int 1) (const_int 2)))])
5807 (define_insn "const_umulsidi3_sp64"
5808 [(set (match_operand:DI 0 "register_operand" "=r")
5809 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5810 (match_operand:SI 2 "uns_small_int" "")))]
5811 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5813 [(set_attr "type" "imul")])
5816 (define_insn "const_umulsidi3_v8plus"
5817 [(set (match_operand:DI 0 "register_operand" "=h,r")
5818 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5819 (match_operand:SI 2 "uns_small_int" "")))
5820 (clobber (match_scratch:SI 3 "=X,h"))]
5823 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5824 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5825 [(set_attr "type" "multi")
5826 (set_attr "length" "2,3")])
5828 (define_expand "umulsi3_highpart"
5829 [(set (match_operand:SI 0 "register_operand" "")
5831 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5832 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5834 "TARGET_HARD_MUL && TARGET_ARCH32"
5837 if (CONSTANT_P (operands[2]))
5841 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5847 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5852 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5853 operands[2], GEN_INT (32)));
5859 (define_insn "umulsi3_highpart_v8plus"
5860 [(set (match_operand:SI 0 "register_operand" "=h,r")
5862 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5863 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5864 (match_operand:SI 3 "const_int_operand" "i,i"))))
5865 (clobber (match_scratch:SI 4 "=X,h"))]
5868 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5869 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5870 [(set_attr "type" "multi")
5871 (set_attr "length" "2")])
5874 (define_insn "const_umulsi3_highpart_v8plus"
5875 [(set (match_operand:SI 0 "register_operand" "=h,r")
5877 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5878 (match_operand:SI 2 "uns_small_int" ""))
5879 (match_operand:SI 3 "const_int_operand" "i,i"))))
5880 (clobber (match_scratch:SI 4 "=X,h"))]
5883 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5884 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5885 [(set_attr "type" "multi")
5886 (set_attr "length" "2")])
5889 (define_insn "*umulsi3_highpart_sp32"
5890 [(set (match_operand:SI 0 "register_operand" "=r")
5892 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5893 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5896 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5897 [(set_attr "type" "multi")
5898 (set_attr "length" "2")])
5901 (define_insn "const_umulsi3_highpart"
5902 [(set (match_operand:SI 0 "register_operand" "=r")
5904 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5905 (match_operand:SI 2 "uns_small_int" ""))
5908 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5909 [(set_attr "type" "multi")
5910 (set_attr "length" "2")])
5912 ;; The v8 architecture specifies that there must be 3 instructions between
5913 ;; a y register write and a use of it for correct results.
5915 (define_expand "divsi3"
5916 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5917 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5918 (match_operand:SI 2 "input_operand" "rI,m")))
5919 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5920 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5925 operands[3] = gen_reg_rtx(SImode);
5926 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5927 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5933 (define_insn "divsi3_sp32"
5934 [(set (match_operand:SI 0 "register_operand" "=r,r")
5935 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5936 (match_operand:SI 2 "input_operand" "rI,m")))
5937 (clobber (match_scratch:SI 3 "=&r,&r"))]
5938 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5942 if (which_alternative == 0)
5944 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5946 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5949 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5951 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\";
5953 [(set_attr "type" "multi")
5954 (set (attr "length")
5955 (if_then_else (eq_attr "isa" "v9")
5956 (const_int 4) (const_int 6)))])
5958 (define_insn "divsi3_sp64"
5959 [(set (match_operand:SI 0 "register_operand" "=r")
5960 (div:SI (match_operand:SI 1 "register_operand" "r")
5961 (match_operand:SI 2 "input_operand" "rI")))
5962 (use (match_operand:SI 3 "register_operand" "r"))]
5963 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5964 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5965 [(set_attr "type" "multi")
5966 (set_attr "length" "2")])
5968 (define_insn "divdi3"
5969 [(set (match_operand:DI 0 "register_operand" "=r")
5970 (div:DI (match_operand:DI 1 "register_operand" "r")
5971 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5973 "sdivx\\t%1, %2, %0"
5974 [(set_attr "type" "idiv")])
5976 (define_insn "*cmp_sdiv_cc_set"
5978 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5979 (match_operand:SI 2 "arith_operand" "rI"))
5981 (set (match_operand:SI 0 "register_operand" "=r")
5982 (div:SI (match_dup 1) (match_dup 2)))
5983 (clobber (match_scratch:SI 3 "=&r"))]
5984 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5988 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5990 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5992 [(set_attr "type" "multi")
5993 (set (attr "length")
5994 (if_then_else (eq_attr "isa" "v9")
5995 (const_int 3) (const_int 6)))])
5998 (define_expand "udivsi3"
5999 [(set (match_operand:SI 0 "register_operand" "")
6000 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6001 (match_operand:SI 2 "input_operand" "")))]
6002 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6005 (define_insn "udivsi3_sp32"
6006 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6007 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6008 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6010 || TARGET_DEPRECATED_V8_INSNS)
6014 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6015 switch (which_alternative)
6018 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6020 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6022 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6025 [(set_attr "type" "multi")
6026 (set_attr "length" "5")])
6028 (define_insn "udivsi3_sp64"
6029 [(set (match_operand:SI 0 "register_operand" "=r")
6030 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6031 (match_operand:SI 2 "input_operand" "rI")))]
6032 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6033 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6034 [(set_attr "type" "multi")
6035 (set_attr "length" "2")])
6037 (define_insn "udivdi3"
6038 [(set (match_operand:DI 0 "register_operand" "=r")
6039 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6040 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6042 "udivx\\t%1, %2, %0"
6043 [(set_attr "type" "idiv")])
6045 (define_insn "*cmp_udiv_cc_set"
6047 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6048 (match_operand:SI 2 "arith_operand" "rI"))
6050 (set (match_operand:SI 0 "register_operand" "=r")
6051 (udiv:SI (match_dup 1) (match_dup 2)))]
6053 || TARGET_DEPRECATED_V8_INSNS"
6057 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6059 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6061 [(set_attr "type" "multi")
6062 (set (attr "length")
6063 (if_then_else (eq_attr "isa" "v9")
6064 (const_int 2) (const_int 5)))])
6066 ; sparclet multiply/accumulate insns
6068 (define_insn "*smacsi"
6069 [(set (match_operand:SI 0 "register_operand" "=r")
6070 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6071 (match_operand:SI 2 "arith_operand" "rI"))
6072 (match_operand:SI 3 "register_operand" "0")))]
6075 [(set_attr "type" "imul")])
6077 (define_insn "*smacdi"
6078 [(set (match_operand:DI 0 "register_operand" "=r")
6079 (plus:DI (mult:DI (sign_extend:DI
6080 (match_operand:SI 1 "register_operand" "%r"))
6082 (match_operand:SI 2 "register_operand" "r")))
6083 (match_operand:DI 3 "register_operand" "0")))]
6085 "smacd\\t%1, %2, %L0"
6086 [(set_attr "type" "imul")])
6088 (define_insn "*umacdi"
6089 [(set (match_operand:DI 0 "register_operand" "=r")
6090 (plus:DI (mult:DI (zero_extend:DI
6091 (match_operand:SI 1 "register_operand" "%r"))
6093 (match_operand:SI 2 "register_operand" "r")))
6094 (match_operand:DI 3 "register_operand" "0")))]
6096 "umacd\\t%1, %2, %L0"
6097 [(set_attr "type" "imul")])
6099 ;;- Boolean instructions
6100 ;; We define DImode `and' so with DImode `not' we can get
6101 ;; DImode `andn'. Other combinations are possible.
6103 (define_expand "anddi3"
6104 [(set (match_operand:DI 0 "register_operand" "")
6105 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6106 (match_operand:DI 2 "arith_double_operand" "")))]
6110 (define_insn "*anddi3_sp32"
6111 [(set (match_operand:DI 0 "register_operand" "=r,b")
6112 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6113 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6118 [(set_attr "type" "*,fp")
6119 (set_attr "length" "2,*")
6120 (set_attr "fptype" "double")])
6122 (define_insn "*anddi3_sp64"
6123 [(set (match_operand:DI 0 "register_operand" "=r,b")
6124 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6125 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6130 [(set_attr "type" "*,fp")
6131 (set_attr "fptype" "double")])
6133 (define_insn "andsi3"
6134 [(set (match_operand:SI 0 "register_operand" "=r,d")
6135 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6136 (match_operand:SI 2 "arith_operand" "rI,d")))]
6141 [(set_attr "type" "*,fp")])
6144 [(set (match_operand:SI 0 "register_operand" "")
6145 (and:SI (match_operand:SI 1 "register_operand" "")
6146 (match_operand:SI 2 "" "")))
6147 (clobber (match_operand:SI 3 "register_operand" ""))]
6148 "GET_CODE (operands[2]) == CONST_INT
6149 && !SMALL_INT32 (operands[2])
6150 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6151 [(set (match_dup 3) (match_dup 4))
6152 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6155 operands[4] = GEN_INT (~INTVAL (operands[2]));
6158 ;; Split DImode logical operations requiring two instructions.
6160 [(set (match_operand:DI 0 "register_operand" "")
6161 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6162 [(match_operand:DI 2 "register_operand" "")
6163 (match_operand:DI 3 "arith_double_operand" "")]))]
6166 && ((GET_CODE (operands[0]) == REG
6167 && REGNO (operands[0]) < 32)
6168 || (GET_CODE (operands[0]) == SUBREG
6169 && GET_CODE (SUBREG_REG (operands[0])) == REG
6170 && REGNO (SUBREG_REG (operands[0])) < 32))"
6171 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6172 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6175 operands[4] = gen_highpart (SImode, operands[0]);
6176 operands[5] = gen_lowpart (SImode, operands[0]);
6177 operands[6] = gen_highpart (SImode, operands[2]);
6178 operands[7] = gen_lowpart (SImode, operands[2]);
6179 #if HOST_BITS_PER_WIDE_INT == 32
6180 if (GET_CODE (operands[3]) == CONST_INT)
6182 if (INTVAL (operands[3]) < 0)
6183 operands[8] = constm1_rtx;
6185 operands[8] = const0_rtx;
6189 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6190 operands[9] = gen_lowpart (SImode, operands[3]);
6193 (define_insn "*and_not_di_sp32"
6194 [(set (match_operand:DI 0 "register_operand" "=r,b")
6195 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6196 (match_operand:DI 2 "register_operand" "r,b")))]
6200 fandnot1\\t%1, %2, %0"
6201 [(set_attr "type" "*,fp")
6202 (set_attr "length" "2,*")
6203 (set_attr "fptype" "double")])
6206 [(set (match_operand:DI 0 "register_operand" "")
6207 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6208 (match_operand:DI 2 "register_operand" "")))]
6211 && ((GET_CODE (operands[0]) == REG
6212 && REGNO (operands[0]) < 32)
6213 || (GET_CODE (operands[0]) == SUBREG
6214 && GET_CODE (SUBREG_REG (operands[0])) == REG
6215 && REGNO (SUBREG_REG (operands[0])) < 32))"
6216 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6217 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6218 "operands[3] = gen_highpart (SImode, operands[0]);
6219 operands[4] = gen_highpart (SImode, operands[1]);
6220 operands[5] = gen_highpart (SImode, operands[2]);
6221 operands[6] = gen_lowpart (SImode, operands[0]);
6222 operands[7] = gen_lowpart (SImode, operands[1]);
6223 operands[8] = gen_lowpart (SImode, operands[2]);")
6225 (define_insn "*and_not_di_sp64"
6226 [(set (match_operand:DI 0 "register_operand" "=r,b")
6227 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6228 (match_operand:DI 2 "register_operand" "r,b")))]
6232 fandnot1\\t%1, %2, %0"
6233 [(set_attr "type" "*,fp")
6234 (set_attr "fptype" "double")])
6236 (define_insn "*and_not_si"
6237 [(set (match_operand:SI 0 "register_operand" "=r,d")
6238 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6239 (match_operand:SI 2 "register_operand" "r,d")))]
6243 fandnot1s\\t%1, %2, %0"
6244 [(set_attr "type" "*,fp")])
6246 (define_expand "iordi3"
6247 [(set (match_operand:DI 0 "register_operand" "")
6248 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6249 (match_operand:DI 2 "arith_double_operand" "")))]
6253 (define_insn "*iordi3_sp32"
6254 [(set (match_operand:DI 0 "register_operand" "=r,b")
6255 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6256 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6261 [(set_attr "type" "*,fp")
6262 (set_attr "length" "2,*")
6263 (set_attr "fptype" "double")])
6265 (define_insn "*iordi3_sp64"
6266 [(set (match_operand:DI 0 "register_operand" "=r,b")
6267 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6268 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6273 [(set_attr "type" "*,fp")
6274 (set_attr "fptype" "double")])
6276 (define_insn "iorsi3"
6277 [(set (match_operand:SI 0 "register_operand" "=r,d")
6278 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6279 (match_operand:SI 2 "arith_operand" "rI,d")))]
6284 [(set_attr "type" "*,fp")])
6287 [(set (match_operand:SI 0 "register_operand" "")
6288 (ior:SI (match_operand:SI 1 "register_operand" "")
6289 (match_operand:SI 2 "" "")))
6290 (clobber (match_operand:SI 3 "register_operand" ""))]
6291 "GET_CODE (operands[2]) == CONST_INT
6292 && !SMALL_INT32 (operands[2])
6293 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6294 [(set (match_dup 3) (match_dup 4))
6295 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6298 operands[4] = GEN_INT (~INTVAL (operands[2]));
6301 (define_insn "*or_not_di_sp32"
6302 [(set (match_operand:DI 0 "register_operand" "=r,b")
6303 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6304 (match_operand:DI 2 "register_operand" "r,b")))]
6308 fornot1\\t%1, %2, %0"
6309 [(set_attr "type" "*,fp")
6310 (set_attr "length" "2,*")
6311 (set_attr "fptype" "double")])
6314 [(set (match_operand:DI 0 "register_operand" "")
6315 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6316 (match_operand:DI 2 "register_operand" "")))]
6319 && ((GET_CODE (operands[0]) == REG
6320 && REGNO (operands[0]) < 32)
6321 || (GET_CODE (operands[0]) == SUBREG
6322 && GET_CODE (SUBREG_REG (operands[0])) == REG
6323 && REGNO (SUBREG_REG (operands[0])) < 32))"
6324 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6325 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6326 "operands[3] = gen_highpart (SImode, operands[0]);
6327 operands[4] = gen_highpart (SImode, operands[1]);
6328 operands[5] = gen_highpart (SImode, operands[2]);
6329 operands[6] = gen_lowpart (SImode, operands[0]);
6330 operands[7] = gen_lowpart (SImode, operands[1]);
6331 operands[8] = gen_lowpart (SImode, operands[2]);")
6333 (define_insn "*or_not_di_sp64"
6334 [(set (match_operand:DI 0 "register_operand" "=r,b")
6335 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6336 (match_operand:DI 2 "register_operand" "r,b")))]
6340 fornot1\\t%1, %2, %0"
6341 [(set_attr "type" "*,fp")
6342 (set_attr "fptype" "double")])
6344 (define_insn "*or_not_si"
6345 [(set (match_operand:SI 0 "register_operand" "=r,d")
6346 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6347 (match_operand:SI 2 "register_operand" "r,d")))]
6351 fornot1s\\t%1, %2, %0"
6352 [(set_attr "type" "*,fp")])
6354 (define_expand "xordi3"
6355 [(set (match_operand:DI 0 "register_operand" "")
6356 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6357 (match_operand:DI 2 "arith_double_operand" "")))]
6361 (define_insn "*xordi3_sp32"
6362 [(set (match_operand:DI 0 "register_operand" "=r,b")
6363 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6364 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6369 [(set_attr "type" "*,fp")
6370 (set_attr "length" "2,*")
6371 (set_attr "fptype" "double")])
6373 (define_insn "*xordi3_sp64"
6374 [(set (match_operand:DI 0 "register_operand" "=r,b")
6375 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6376 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6381 [(set_attr "type" "*,fp")
6382 (set_attr "fptype" "double")])
6384 (define_insn "*xordi3_sp64_dbl"
6385 [(set (match_operand:DI 0 "register_operand" "=r")
6386 (xor:DI (match_operand:DI 1 "register_operand" "r")
6387 (match_operand:DI 2 "const64_operand" "")))]
6389 && HOST_BITS_PER_WIDE_INT != 64)"
6392 (define_insn "xorsi3"
6393 [(set (match_operand:SI 0 "register_operand" "=r,d")
6394 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6395 (match_operand:SI 2 "arith_operand" "rI,d")))]
6400 [(set_attr "type" "*,fp")])
6403 [(set (match_operand:SI 0 "register_operand" "")
6404 (xor:SI (match_operand:SI 1 "register_operand" "")
6405 (match_operand:SI 2 "" "")))
6406 (clobber (match_operand:SI 3 "register_operand" ""))]
6407 "GET_CODE (operands[2]) == CONST_INT
6408 && !SMALL_INT32 (operands[2])
6409 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6410 [(set (match_dup 3) (match_dup 4))
6411 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6414 operands[4] = GEN_INT (~INTVAL (operands[2]));
6418 [(set (match_operand:SI 0 "register_operand" "")
6419 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6420 (match_operand:SI 2 "" ""))))
6421 (clobber (match_operand:SI 3 "register_operand" ""))]
6422 "GET_CODE (operands[2]) == CONST_INT
6423 && !SMALL_INT32 (operands[2])
6424 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6425 [(set (match_dup 3) (match_dup 4))
6426 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6429 operands[4] = GEN_INT (~INTVAL (operands[2]));
6432 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6433 ;; Combine now canonicalizes to the rightmost expression.
6434 (define_insn "*xor_not_di_sp32"
6435 [(set (match_operand:DI 0 "register_operand" "=r,b")
6436 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6437 (match_operand:DI 2 "register_operand" "r,b"))))]
6442 [(set_attr "type" "*,fp")
6443 (set_attr "length" "2,*")
6444 (set_attr "fptype" "double")])
6447 [(set (match_operand:DI 0 "register_operand" "")
6448 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6449 (match_operand:DI 2 "register_operand" ""))))]
6452 && ((GET_CODE (operands[0]) == REG
6453 && REGNO (operands[0]) < 32)
6454 || (GET_CODE (operands[0]) == SUBREG
6455 && GET_CODE (SUBREG_REG (operands[0])) == REG
6456 && REGNO (SUBREG_REG (operands[0])) < 32))"
6457 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6458 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6459 "operands[3] = gen_highpart (SImode, operands[0]);
6460 operands[4] = gen_highpart (SImode, operands[1]);
6461 operands[5] = gen_highpart (SImode, operands[2]);
6462 operands[6] = gen_lowpart (SImode, operands[0]);
6463 operands[7] = gen_lowpart (SImode, operands[1]);
6464 operands[8] = gen_lowpart (SImode, operands[2]);")
6466 (define_insn "*xor_not_di_sp64"
6467 [(set (match_operand:DI 0 "register_operand" "=r,b")
6468 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6469 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6474 [(set_attr "type" "*,fp")
6475 (set_attr "fptype" "double")])
6477 (define_insn "*xor_not_si"
6478 [(set (match_operand:SI 0 "register_operand" "=r,d")
6479 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6480 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6484 fxnors\\t%1, %2, %0"
6485 [(set_attr "type" "*,fp")])
6487 ;; These correspond to the above in the case where we also (or only)
6488 ;; want to set the condition code.
6490 (define_insn "*cmp_cc_arith_op"
6493 (match_operator:SI 2 "cc_arithop"
6494 [(match_operand:SI 0 "arith_operand" "%r")
6495 (match_operand:SI 1 "arith_operand" "rI")])
6498 "%A2cc\\t%0, %1, %%g0"
6499 [(set_attr "type" "compare")])
6501 (define_insn "*cmp_ccx_arith_op"
6504 (match_operator:DI 2 "cc_arithop"
6505 [(match_operand:DI 0 "arith_double_operand" "%r")
6506 (match_operand:DI 1 "arith_double_operand" "rHI")])
6509 "%A2cc\\t%0, %1, %%g0"
6510 [(set_attr "type" "compare")])
6512 (define_insn "*cmp_cc_arith_op_set"
6515 (match_operator:SI 3 "cc_arithop"
6516 [(match_operand:SI 1 "arith_operand" "%r")
6517 (match_operand:SI 2 "arith_operand" "rI")])
6519 (set (match_operand:SI 0 "register_operand" "=r")
6520 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6521 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6522 "%A3cc\\t%1, %2, %0"
6523 [(set_attr "type" "compare")])
6525 (define_insn "*cmp_ccx_arith_op_set"
6528 (match_operator:DI 3 "cc_arithop"
6529 [(match_operand:DI 1 "arith_double_operand" "%r")
6530 (match_operand:DI 2 "arith_double_operand" "rHI")])
6532 (set (match_operand:DI 0 "register_operand" "=r")
6533 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6534 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6535 "%A3cc\\t%1, %2, %0"
6536 [(set_attr "type" "compare")])
6538 (define_insn "*cmp_cc_xor_not"
6541 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6542 (match_operand:SI 1 "arith_operand" "rI")))
6545 "xnorcc\\t%r0, %1, %%g0"
6546 [(set_attr "type" "compare")])
6548 (define_insn "*cmp_ccx_xor_not"
6551 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6552 (match_operand:DI 1 "arith_double_operand" "rHI")))
6555 "xnorcc\\t%r0, %1, %%g0"
6556 [(set_attr "type" "compare")])
6558 (define_insn "*cmp_cc_xor_not_set"
6561 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6562 (match_operand:SI 2 "arith_operand" "rI")))
6564 (set (match_operand:SI 0 "register_operand" "=r")
6565 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6567 "xnorcc\\t%r1, %2, %0"
6568 [(set_attr "type" "compare")])
6570 (define_insn "*cmp_ccx_xor_not_set"
6573 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6574 (match_operand:DI 2 "arith_double_operand" "rHI")))
6576 (set (match_operand:DI 0 "register_operand" "=r")
6577 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6579 "xnorcc\\t%r1, %2, %0"
6580 [(set_attr "type" "compare")])
6582 (define_insn "*cmp_cc_arith_op_not"
6585 (match_operator:SI 2 "cc_arithopn"
6586 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6587 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6590 "%B2cc\\t%r1, %0, %%g0"
6591 [(set_attr "type" "compare")])
6593 (define_insn "*cmp_ccx_arith_op_not"
6596 (match_operator:DI 2 "cc_arithopn"
6597 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6598 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6601 "%B2cc\\t%r1, %0, %%g0"
6602 [(set_attr "type" "compare")])
6604 (define_insn "*cmp_cc_arith_op_not_set"
6607 (match_operator:SI 3 "cc_arithopn"
6608 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6609 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6611 (set (match_operand:SI 0 "register_operand" "=r")
6612 (match_operator:SI 4 "cc_arithopn"
6613 [(not:SI (match_dup 1)) (match_dup 2)]))]
6614 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6615 "%B3cc\\t%r2, %1, %0"
6616 [(set_attr "type" "compare")])
6618 (define_insn "*cmp_ccx_arith_op_not_set"
6621 (match_operator:DI 3 "cc_arithopn"
6622 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6623 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6625 (set (match_operand:DI 0 "register_operand" "=r")
6626 (match_operator:DI 4 "cc_arithopn"
6627 [(not:DI (match_dup 1)) (match_dup 2)]))]
6628 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6629 "%B3cc\\t%r2, %1, %0"
6630 [(set_attr "type" "compare")])
6632 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6633 ;; does not know how to make it work for constants.
6635 (define_expand "negdi2"
6636 [(set (match_operand:DI 0 "register_operand" "=r")
6637 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6641 if (! TARGET_ARCH64)
6643 emit_insn (gen_rtx_PARALLEL
6646 gen_rtx_SET (VOIDmode, operand0,
6647 gen_rtx_NEG (DImode, operand1)),
6648 gen_rtx_CLOBBER (VOIDmode,
6649 gen_rtx_REG (CCmode,
6655 (define_insn "*negdi2_sp32"
6656 [(set (match_operand:DI 0 "register_operand" "=r")
6657 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6658 (clobber (reg:CC 100))]
6661 [(set_attr "length" "2")])
6664 [(set (match_operand:DI 0 "register_operand" "")
6665 (neg:DI (match_operand:DI 1 "register_operand" "")))
6666 (clobber (reg:CC 100))]
6668 && reload_completed"
6669 [(parallel [(set (reg:CC_NOOV 100)
6670 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6672 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6673 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6674 (ltu:SI (reg:CC 100) (const_int 0))))]
6675 "operands[2] = gen_highpart (SImode, operands[0]);
6676 operands[3] = gen_highpart (SImode, operands[1]);
6677 operands[4] = gen_lowpart (SImode, operands[0]);
6678 operands[5] = gen_lowpart (SImode, operands[1]);")
6680 (define_insn "*negdi2_sp64"
6681 [(set (match_operand:DI 0 "register_operand" "=r")
6682 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6684 "sub\\t%%g0, %1, %0")
6686 (define_insn "negsi2"
6687 [(set (match_operand:SI 0 "register_operand" "=r")
6688 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6690 "sub\\t%%g0, %1, %0")
6692 (define_insn "*cmp_cc_neg"
6693 [(set (reg:CC_NOOV 100)
6694 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6697 "subcc\\t%%g0, %0, %%g0"
6698 [(set_attr "type" "compare")])
6700 (define_insn "*cmp_ccx_neg"
6701 [(set (reg:CCX_NOOV 100)
6702 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6705 "subcc\\t%%g0, %0, %%g0"
6706 [(set_attr "type" "compare")])
6708 (define_insn "*cmp_cc_set_neg"
6709 [(set (reg:CC_NOOV 100)
6710 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6712 (set (match_operand:SI 0 "register_operand" "=r")
6713 (neg:SI (match_dup 1)))]
6715 "subcc\\t%%g0, %1, %0"
6716 [(set_attr "type" "compare")])
6718 (define_insn "*cmp_ccx_set_neg"
6719 [(set (reg:CCX_NOOV 100)
6720 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6722 (set (match_operand:DI 0 "register_operand" "=r")
6723 (neg:DI (match_dup 1)))]
6725 "subcc\\t%%g0, %1, %0"
6726 [(set_attr "type" "compare")])
6728 ;; We cannot use the "not" pseudo insn because the Sun assembler
6729 ;; does not know how to make it work for constants.
6730 (define_expand "one_cmpldi2"
6731 [(set (match_operand:DI 0 "register_operand" "")
6732 (not:DI (match_operand:DI 1 "register_operand" "")))]
6736 (define_insn "*one_cmpldi2_sp32"
6737 [(set (match_operand:DI 0 "register_operand" "=r,b")
6738 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6743 [(set_attr "type" "*,fp")
6744 (set_attr "length" "2,*")
6745 (set_attr "fptype" "double")])
6748 [(set (match_operand:DI 0 "register_operand" "")
6749 (not:DI (match_operand:DI 1 "register_operand" "")))]
6752 && ((GET_CODE (operands[0]) == REG
6753 && REGNO (operands[0]) < 32)
6754 || (GET_CODE (operands[0]) == SUBREG
6755 && GET_CODE (SUBREG_REG (operands[0])) == REG
6756 && REGNO (SUBREG_REG (operands[0])) < 32))"
6757 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6758 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6759 "operands[2] = gen_highpart (SImode, operands[0]);
6760 operands[3] = gen_highpart (SImode, operands[1]);
6761 operands[4] = gen_lowpart (SImode, operands[0]);
6762 operands[5] = gen_lowpart (SImode, operands[1]);")
6764 (define_insn "*one_cmpldi2_sp64"
6765 [(set (match_operand:DI 0 "register_operand" "=r,b")
6766 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6771 [(set_attr "type" "*,fp")
6772 (set_attr "fptype" "double")])
6774 (define_insn "one_cmplsi2"
6775 [(set (match_operand:SI 0 "register_operand" "=r,d")
6776 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6781 [(set_attr "type" "*,fp")])
6783 (define_insn "*cmp_cc_not"
6785 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6788 "xnorcc\\t%%g0, %0, %%g0"
6789 [(set_attr "type" "compare")])
6791 (define_insn "*cmp_ccx_not"
6793 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6796 "xnorcc\\t%%g0, %0, %%g0"
6797 [(set_attr "type" "compare")])
6799 (define_insn "*cmp_cc_set_not"
6801 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6803 (set (match_operand:SI 0 "register_operand" "=r")
6804 (not:SI (match_dup 1)))]
6806 "xnorcc\\t%%g0, %1, %0"
6807 [(set_attr "type" "compare")])
6809 (define_insn "*cmp_ccx_set_not"
6811 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6813 (set (match_operand:DI 0 "register_operand" "=r")
6814 (not:DI (match_dup 1)))]
6816 "xnorcc\\t%%g0, %1, %0"
6817 [(set_attr "type" "compare")])
6819 (define_insn "*cmp_cc_set"
6820 [(set (match_operand:SI 0 "register_operand" "=r")
6821 (match_operand:SI 1 "register_operand" "r"))
6823 (compare:CC (match_dup 1)
6827 [(set_attr "type" "compare")])
6829 (define_insn "*cmp_ccx_set64"
6830 [(set (match_operand:DI 0 "register_operand" "=r")
6831 (match_operand:DI 1 "register_operand" "r"))
6833 (compare:CCX (match_dup 1)
6837 [(set_attr "type" "compare")])
6839 ;; Floating point arithmetic instructions.
6841 (define_expand "addtf3"
6842 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6843 (plus:TF (match_operand:TF 1 "general_operand" "")
6844 (match_operand:TF 2 "general_operand" "")))]
6845 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6846 "emit_tfmode_binop (PLUS, operands); DONE;")
6848 (define_insn "*addtf3_hq"
6849 [(set (match_operand:TF 0 "register_operand" "=e")
6850 (plus:TF (match_operand:TF 1 "register_operand" "e")
6851 (match_operand:TF 2 "register_operand" "e")))]
6852 "TARGET_FPU && TARGET_HARD_QUAD"
6853 "faddq\\t%1, %2, %0"
6854 [(set_attr "type" "fp")])
6856 (define_insn "adddf3"
6857 [(set (match_operand:DF 0 "register_operand" "=e")
6858 (plus:DF (match_operand:DF 1 "register_operand" "e")
6859 (match_operand:DF 2 "register_operand" "e")))]
6861 "faddd\\t%1, %2, %0"
6862 [(set_attr "type" "fp")
6863 (set_attr "fptype" "double")])
6865 (define_insn "addsf3"
6866 [(set (match_operand:SF 0 "register_operand" "=f")
6867 (plus:SF (match_operand:SF 1 "register_operand" "f")
6868 (match_operand:SF 2 "register_operand" "f")))]
6870 "fadds\\t%1, %2, %0"
6871 [(set_attr "type" "fp")])
6873 (define_expand "subtf3"
6874 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6875 (minus:TF (match_operand:TF 1 "general_operand" "")
6876 (match_operand:TF 2 "general_operand" "")))]
6877 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6878 "emit_tfmode_binop (MINUS, operands); DONE;")
6880 (define_insn "*subtf3_hq"
6881 [(set (match_operand:TF 0 "register_operand" "=e")
6882 (minus:TF (match_operand:TF 1 "register_operand" "e")
6883 (match_operand:TF 2 "register_operand" "e")))]
6884 "TARGET_FPU && TARGET_HARD_QUAD"
6885 "fsubq\\t%1, %2, %0"
6886 [(set_attr "type" "fp")])
6888 (define_insn "subdf3"
6889 [(set (match_operand:DF 0 "register_operand" "=e")
6890 (minus:DF (match_operand:DF 1 "register_operand" "e")
6891 (match_operand:DF 2 "register_operand" "e")))]
6893 "fsubd\\t%1, %2, %0"
6894 [(set_attr "type" "fp")
6895 (set_attr "fptype" "double")])
6897 (define_insn "subsf3"
6898 [(set (match_operand:SF 0 "register_operand" "=f")
6899 (minus:SF (match_operand:SF 1 "register_operand" "f")
6900 (match_operand:SF 2 "register_operand" "f")))]
6902 "fsubs\\t%1, %2, %0"
6903 [(set_attr "type" "fp")])
6905 (define_expand "multf3"
6906 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6907 (mult:TF (match_operand:TF 1 "general_operand" "")
6908 (match_operand:TF 2 "general_operand" "")))]
6909 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6910 "emit_tfmode_binop (MULT, operands); DONE;")
6912 (define_insn "*multf3_hq"
6913 [(set (match_operand:TF 0 "register_operand" "=e")
6914 (mult:TF (match_operand:TF 1 "register_operand" "e")
6915 (match_operand:TF 2 "register_operand" "e")))]
6916 "TARGET_FPU && TARGET_HARD_QUAD"
6917 "fmulq\\t%1, %2, %0"
6918 [(set_attr "type" "fpmul")])
6920 (define_insn "muldf3"
6921 [(set (match_operand:DF 0 "register_operand" "=e")
6922 (mult:DF (match_operand:DF 1 "register_operand" "e")
6923 (match_operand:DF 2 "register_operand" "e")))]
6925 "fmuld\\t%1, %2, %0"
6926 [(set_attr "type" "fpmul")
6927 (set_attr "fptype" "double")])
6929 (define_insn "mulsf3"
6930 [(set (match_operand:SF 0 "register_operand" "=f")
6931 (mult:SF (match_operand:SF 1 "register_operand" "f")
6932 (match_operand:SF 2 "register_operand" "f")))]
6934 "fmuls\\t%1, %2, %0"
6935 [(set_attr "type" "fpmul")])
6937 (define_insn "*muldf3_extend"
6938 [(set (match_operand:DF 0 "register_operand" "=e")
6939 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6940 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6941 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6942 "fsmuld\\t%1, %2, %0"
6943 [(set_attr "type" "fpmul")
6944 (set_attr "fptype" "double")])
6946 (define_insn "*multf3_extend"
6947 [(set (match_operand:TF 0 "register_operand" "=e")
6948 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6949 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6950 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6951 "fdmulq\\t%1, %2, %0"
6952 [(set_attr "type" "fpmul")])
6954 (define_expand "divtf3"
6955 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6956 (div:TF (match_operand:TF 1 "general_operand" "")
6957 (match_operand:TF 2 "general_operand" "")))]
6958 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6959 "emit_tfmode_binop (DIV, operands); DONE;")
6961 ;; don't have timing for quad-prec. divide.
6962 (define_insn "*divtf3_hq"
6963 [(set (match_operand:TF 0 "register_operand" "=e")
6964 (div:TF (match_operand:TF 1 "register_operand" "e")
6965 (match_operand:TF 2 "register_operand" "e")))]
6966 "TARGET_FPU && TARGET_HARD_QUAD"
6967 "fdivq\\t%1, %2, %0"
6968 [(set_attr "type" "fpdivd")])
6970 (define_insn "divdf3"
6971 [(set (match_operand:DF 0 "register_operand" "=e")
6972 (div:DF (match_operand:DF 1 "register_operand" "e")
6973 (match_operand:DF 2 "register_operand" "e")))]
6975 "fdivd\\t%1, %2, %0"
6976 [(set_attr "type" "fpdivd")
6977 (set_attr "fptype" "double")])
6979 (define_insn "divsf3"
6980 [(set (match_operand:SF 0 "register_operand" "=f")
6981 (div:SF (match_operand:SF 1 "register_operand" "f")
6982 (match_operand:SF 2 "register_operand" "f")))]
6984 "fdivs\\t%1, %2, %0"
6985 [(set_attr "type" "fpdivs")])
6987 (define_expand "negtf2"
6988 [(set (match_operand:TF 0 "register_operand" "=e,e")
6989 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6993 (define_insn "*negtf2_notv9"
6994 [(set (match_operand:TF 0 "register_operand" "=e,e")
6995 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6996 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7002 [(set_attr "type" "fpmove,*")
7003 (set_attr "length" "*,2")])
7006 [(set (match_operand:TF 0 "register_operand" "")
7007 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7011 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7012 [(set (match_dup 2) (neg:SF (match_dup 3)))
7013 (set (match_dup 4) (match_dup 5))
7014 (set (match_dup 6) (match_dup 7))]
7015 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7016 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7017 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7018 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7019 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7020 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7022 (define_insn "*negtf2_v9"
7023 [(set (match_operand:TF 0 "register_operand" "=e,e")
7024 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7025 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7026 "TARGET_FPU && TARGET_V9"
7030 [(set_attr "type" "fpmove,*")
7031 (set_attr "length" "*,2")
7032 (set_attr "fptype" "double")])
7035 [(set (match_operand:TF 0 "register_operand" "")
7036 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7040 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7041 [(set (match_dup 2) (neg:DF (match_dup 3)))
7042 (set (match_dup 4) (match_dup 5))]
7043 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7044 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7045 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7046 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7048 (define_expand "negdf2"
7049 [(set (match_operand:DF 0 "register_operand" "")
7050 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7054 (define_insn "*negdf2_notv9"
7055 [(set (match_operand:DF 0 "register_operand" "=e,e")
7056 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7057 "TARGET_FPU && ! TARGET_V9"
7061 [(set_attr "type" "fpmove,*")
7062 (set_attr "length" "*,2")])
7065 [(set (match_operand:DF 0 "register_operand" "")
7066 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7070 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7071 [(set (match_dup 2) (neg:SF (match_dup 3)))
7072 (set (match_dup 4) (match_dup 5))]
7073 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7074 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7075 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7076 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7078 (define_insn "*negdf2_v9"
7079 [(set (match_operand:DF 0 "register_operand" "=e")
7080 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7081 "TARGET_FPU && TARGET_V9"
7083 [(set_attr "type" "fpmove")
7084 (set_attr "fptype" "double")])
7086 (define_insn "negsf2"
7087 [(set (match_operand:SF 0 "register_operand" "=f")
7088 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7091 [(set_attr "type" "fpmove")])
7093 (define_expand "abstf2"
7094 [(set (match_operand:TF 0 "register_operand" "")
7095 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7099 (define_insn "*abstf2_notv9"
7100 [(set (match_operand:TF 0 "register_operand" "=e,e")
7101 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7102 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7103 "TARGET_FPU && ! TARGET_V9"
7107 [(set_attr "type" "fpmove,*")
7108 (set_attr "length" "*,2")])
7111 [(set (match_operand:TF 0 "register_operand" "")
7112 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7116 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7117 [(set (match_dup 2) (abs:SF (match_dup 3)))
7118 (set (match_dup 4) (match_dup 5))
7119 (set (match_dup 6) (match_dup 7))]
7120 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7121 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7122 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7123 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7124 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7125 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7127 (define_insn "*abstf2_hq_v9"
7128 [(set (match_operand:TF 0 "register_operand" "=e,e")
7129 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7130 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7134 [(set_attr "type" "fpmove")
7135 (set_attr "fptype" "double,*")])
7137 (define_insn "*abstf2_v9"
7138 [(set (match_operand:TF 0 "register_operand" "=e,e")
7139 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7140 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7144 [(set_attr "type" "fpmove,*")
7145 (set_attr "length" "*,2")
7146 (set_attr "fptype" "double,*")])
7149 [(set (match_operand:TF 0 "register_operand" "")
7150 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7154 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7155 [(set (match_dup 2) (abs:DF (match_dup 3)))
7156 (set (match_dup 4) (match_dup 5))]
7157 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7158 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7159 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7160 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7162 (define_expand "absdf2"
7163 [(set (match_operand:DF 0 "register_operand" "")
7164 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7168 (define_insn "*absdf2_notv9"
7169 [(set (match_operand:DF 0 "register_operand" "=e,e")
7170 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7171 "TARGET_FPU && ! TARGET_V9"
7175 [(set_attr "type" "fpmove,*")
7176 (set_attr "length" "*,2")])
7179 [(set (match_operand:DF 0 "register_operand" "")
7180 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7184 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7185 [(set (match_dup 2) (abs:SF (match_dup 3)))
7186 (set (match_dup 4) (match_dup 5))]
7187 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7188 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7189 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7190 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7192 (define_insn "*absdf2_v9"
7193 [(set (match_operand:DF 0 "register_operand" "=e")
7194 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7195 "TARGET_FPU && TARGET_V9"
7197 [(set_attr "type" "fpmove")
7198 (set_attr "fptype" "double")])
7200 (define_insn "abssf2"
7201 [(set (match_operand:SF 0 "register_operand" "=f")
7202 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7205 [(set_attr "type" "fpmove")])
7207 (define_expand "sqrttf2"
7208 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7209 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
7210 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7211 "emit_tfmode_unop (SQRT, operands); DONE;")
7213 (define_insn "*sqrttf2_hq"
7214 [(set (match_operand:TF 0 "register_operand" "=e")
7215 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7216 "TARGET_FPU && TARGET_HARD_QUAD"
7218 [(set_attr "type" "fpsqrtd")])
7220 (define_insn "sqrtdf2"
7221 [(set (match_operand:DF 0 "register_operand" "=e")
7222 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7225 [(set_attr "type" "fpsqrtd")
7226 (set_attr "fptype" "double")])
7228 (define_insn "sqrtsf2"
7229 [(set (match_operand:SF 0 "register_operand" "=f")
7230 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7233 [(set_attr "type" "fpsqrts")])
7235 ;;- arithmetic shift instructions
7237 (define_insn "ashlsi3"
7238 [(set (match_operand:SI 0 "register_operand" "=r")
7239 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7240 (match_operand:SI 2 "arith_operand" "rI")))]
7244 if (GET_CODE (operands[2]) == CONST_INT
7245 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7246 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7248 if (operands[2] == const1_rtx)
7249 return \"add\\t%1, %1, %0\";
7250 return \"sll\\t%1, %2, %0\";
7253 (if_then_else (match_operand 2 "const1_operand" "")
7254 (const_string "ialu") (const_string "shift")))])
7256 (define_expand "ashldi3"
7257 [(set (match_operand:DI 0 "register_operand" "=r")
7258 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7259 (match_operand:SI 2 "arith_operand" "rI")))]
7260 "TARGET_ARCH64 || TARGET_V8PLUS"
7263 if (! TARGET_ARCH64)
7265 if (GET_CODE (operands[2]) == CONST_INT)
7267 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7272 (define_insn "*ashldi3_sp64"
7273 [(set (match_operand:DI 0 "register_operand" "=r")
7274 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7275 (match_operand:SI 2 "arith_operand" "rI")))]
7279 if (GET_CODE (operands[2]) == CONST_INT
7280 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7281 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7283 if (operands[2] == const1_rtx)
7284 return \"add\\t%1, %1, %0\";
7285 return \"sllx\\t%1, %2, %0\";
7288 (if_then_else (match_operand 2 "const1_operand" "")
7289 (const_string "ialu") (const_string "shift")))])
7292 (define_insn "ashldi3_v8plus"
7293 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7294 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7295 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7296 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7298 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7299 [(set_attr "type" "multi")
7300 (set_attr "length" "5,5,6")])
7302 ;; Optimize (1LL<<x)-1
7303 ;; XXX this also needs to be fixed to handle equal subregs
7304 ;; XXX first before we could re-enable it.
7306 ; [(set (match_operand:DI 0 "register_operand" "=h")
7307 ; (plus:DI (ashift:DI (const_int 1)
7308 ; (match_operand:SI 1 "arith_operand" "rI"))
7310 ; "0 && TARGET_V8PLUS"
7313 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7314 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7315 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7317 ; [(set_attr "type" "multi")
7318 ; (set_attr "length" "4")])
7320 (define_insn "*cmp_cc_ashift_1"
7321 [(set (reg:CC_NOOV 100)
7322 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7326 "addcc\\t%0, %0, %%g0"
7327 [(set_attr "type" "compare")])
7329 (define_insn "*cmp_cc_set_ashift_1"
7330 [(set (reg:CC_NOOV 100)
7331 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7334 (set (match_operand:SI 0 "register_operand" "=r")
7335 (ashift:SI (match_dup 1) (const_int 1)))]
7337 "addcc\\t%1, %1, %0"
7338 [(set_attr "type" "compare")])
7340 (define_insn "ashrsi3"
7341 [(set (match_operand:SI 0 "register_operand" "=r")
7342 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7343 (match_operand:SI 2 "arith_operand" "rI")))]
7347 if (GET_CODE (operands[2]) == CONST_INT
7348 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7349 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7351 return \"sra\\t%1, %2, %0\";
7353 [(set_attr "type" "shift")])
7355 (define_insn "*ashrsi3_extend"
7356 [(set (match_operand:DI 0 "register_operand" "=r")
7357 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7358 (match_operand:SI 2 "arith_operand" "r"))))]
7361 [(set_attr "type" "shift")])
7363 ;; This handles the case as above, but with constant shift instead of
7364 ;; register. Combiner "simplifies" it for us a little bit though.
7365 (define_insn "*ashrsi3_extend2"
7366 [(set (match_operand:DI 0 "register_operand" "=r")
7367 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7369 (match_operand:SI 2 "small_int_or_double" "n")))]
7371 && ((GET_CODE (operands[2]) == CONST_INT
7372 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7373 || (GET_CODE (operands[2]) == CONST_DOUBLE
7374 && !CONST_DOUBLE_HIGH (operands[2])
7375 && CONST_DOUBLE_LOW (operands[2]) >= 32
7376 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7379 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7381 return \"sra\\t%1, %2, %0\";
7383 [(set_attr "type" "shift")])
7385 (define_expand "ashrdi3"
7386 [(set (match_operand:DI 0 "register_operand" "=r")
7387 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7388 (match_operand:SI 2 "arith_operand" "rI")))]
7389 "TARGET_ARCH64 || TARGET_V8PLUS"
7392 if (! TARGET_ARCH64)
7394 if (GET_CODE (operands[2]) == CONST_INT)
7395 FAIL; /* prefer generic code in this case */
7396 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7402 [(set (match_operand:DI 0 "register_operand" "=r")
7403 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7404 (match_operand:SI 2 "arith_operand" "rI")))]
7408 if (GET_CODE (operands[2]) == CONST_INT
7409 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7410 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7412 return \"srax\\t%1, %2, %0\";
7414 [(set_attr "type" "shift")])
7417 (define_insn "ashrdi3_v8plus"
7418 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7419 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7420 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7421 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7423 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7424 [(set_attr "type" "multi")
7425 (set_attr "length" "5,5,6")])
7427 (define_insn "lshrsi3"
7428 [(set (match_operand:SI 0 "register_operand" "=r")
7429 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7430 (match_operand:SI 2 "arith_operand" "rI")))]
7434 if (GET_CODE (operands[2]) == CONST_INT
7435 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7436 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7438 return \"srl\\t%1, %2, %0\";
7440 [(set_attr "type" "shift")])
7442 ;; This handles the case where
7443 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7444 ;; but combiner "simplifies" it for us.
7445 (define_insn "*lshrsi3_extend"
7446 [(set (match_operand:DI 0 "register_operand" "=r")
7447 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7448 (match_operand:SI 2 "arith_operand" "r")) 0)
7449 (match_operand 3 "" "")))]
7451 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7452 && CONST_DOUBLE_HIGH (operands[3]) == 0
7453 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7454 || (HOST_BITS_PER_WIDE_INT >= 64
7455 && GET_CODE (operands[3]) == CONST_INT
7456 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7458 [(set_attr "type" "shift")])
7460 ;; This handles the case where
7461 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7462 ;; but combiner "simplifies" it for us.
7463 (define_insn "*lshrsi3_extend2"
7464 [(set (match_operand:DI 0 "register_operand" "=r")
7465 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7466 (match_operand 2 "small_int_or_double" "n")
7469 && ((GET_CODE (operands[2]) == CONST_INT
7470 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7471 || (GET_CODE (operands[2]) == CONST_DOUBLE
7472 && CONST_DOUBLE_HIGH (operands[2]) == 0
7473 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7476 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7478 return \"srl\\t%1, %2, %0\";
7480 [(set_attr "type" "shift")])
7482 (define_expand "lshrdi3"
7483 [(set (match_operand:DI 0 "register_operand" "=r")
7484 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7485 (match_operand:SI 2 "arith_operand" "rI")))]
7486 "TARGET_ARCH64 || TARGET_V8PLUS"
7489 if (! TARGET_ARCH64)
7491 if (GET_CODE (operands[2]) == CONST_INT)
7493 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7500 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7501 (match_operand:SI 2 "arith_operand" "rI")))]
7505 if (GET_CODE (operands[2]) == CONST_INT
7506 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7507 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7509 return \"srlx\\t%1, %2, %0\";
7511 [(set_attr "type" "shift")])
7514 (define_insn "lshrdi3_v8plus"
7515 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7516 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7517 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7518 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7520 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7521 [(set_attr "type" "multi")
7522 (set_attr "length" "5,5,6")])
7525 [(set (match_operand:SI 0 "register_operand" "=r")
7526 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7528 (match_operand:SI 2 "small_int_or_double" "n")))]
7530 && ((GET_CODE (operands[2]) == CONST_INT
7531 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7532 || (GET_CODE (operands[2]) == CONST_DOUBLE
7533 && !CONST_DOUBLE_HIGH (operands[2])
7534 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7537 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7539 return \"srax\\t%1, %2, %0\";
7541 [(set_attr "type" "shift")])
7544 [(set (match_operand:SI 0 "register_operand" "=r")
7545 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7547 (match_operand:SI 2 "small_int_or_double" "n")))]
7549 && ((GET_CODE (operands[2]) == CONST_INT
7550 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7551 || (GET_CODE (operands[2]) == CONST_DOUBLE
7552 && !CONST_DOUBLE_HIGH (operands[2])
7553 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7556 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7558 return \"srlx\\t%1, %2, %0\";
7560 [(set_attr "type" "shift")])
7563 [(set (match_operand:SI 0 "register_operand" "=r")
7564 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7565 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7566 (match_operand:SI 3 "small_int_or_double" "n")))]
7568 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7569 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7570 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7571 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7574 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7576 return \"srax\\t%1, %2, %0\";
7578 [(set_attr "type" "shift")])
7581 [(set (match_operand:SI 0 "register_operand" "=r")
7582 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7583 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7584 (match_operand:SI 3 "small_int_or_double" "n")))]
7586 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7587 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7588 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7589 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7592 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7594 return \"srlx\\t%1, %2, %0\";
7596 [(set_attr "type" "shift")])
7598 ;; Unconditional and other jump instructions
7599 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7600 ;; following insn is never executed. This saves us a nop. Dbx does not
7601 ;; handle such branches though, so we only use them when optimizing.
7603 [(set (pc) (label_ref (match_operand 0 "" "")))]
7607 /* TurboSparc is reported to have problems with
7610 i.e. an empty loop with the annul bit set. The workaround is to use
7614 if (! TARGET_V9 && flag_delayed_branch
7615 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7616 == INSN_ADDRESSES (INSN_UID (insn))))
7617 return \"b\\t%l0%#\";
7619 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7621 [(set_attr "type" "uncond_branch")])
7623 (define_expand "tablejump"
7624 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7625 (use (label_ref (match_operand 1 "" "")))])]
7629 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7632 /* In pic mode, our address differences are against the base of the
7633 table. Add that base value back in; CSE ought to be able to combine
7634 the two address loads. */
7638 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7640 if (CASE_VECTOR_MODE != Pmode)
7641 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7642 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7643 operands[0] = memory_address (Pmode, tmp);
7647 (define_insn "*tablejump_sp32"
7648 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7649 (use (label_ref (match_operand 1 "" "")))]
7652 [(set_attr "type" "uncond_branch")])
7654 (define_insn "*tablejump_sp64"
7655 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7656 (use (label_ref (match_operand 1 "" "")))]
7659 [(set_attr "type" "uncond_branch")])
7661 ;; This pattern recognizes the "instruction" that appears in
7662 ;; a function call that wants a structure value,
7663 ;; to inform the called function if compiled with Sun CC.
7664 ;(define_insn "*unimp_insn"
7665 ; [(match_operand:SI 0 "immediate_operand" "")]
7666 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7668 ; [(set_attr "type" "marker")])
7670 ;;- jump to subroutine
7671 (define_expand "call"
7672 ;; Note that this expression is not used for generating RTL.
7673 ;; All the RTL is generated explicitly below.
7674 [(call (match_operand 0 "call_operand" "")
7675 (match_operand 3 "" "i"))]
7676 ;; operands[2] is next_arg_register
7677 ;; operands[3] is struct_value_size_rtx.
7681 rtx fn_rtx, nregs_rtx;
7683 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7686 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7688 /* This is really a PIC sequence. We want to represent
7689 it as a funny jump so its delay slots can be filled.
7691 ??? But if this really *is* a CALL, will not it clobber the
7692 call-clobbered registers? We lose this if it is a JUMP_INSN.
7693 Why cannot we have delay slots filled if it were a CALL? */
7695 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7700 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7702 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7708 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7709 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7713 fn_rtx = operands[0];
7715 /* Count the number of parameter registers being used by this call.
7716 if that argument is NULL, it means we are using them all, which
7717 means 6 on the sparc. */
7720 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7722 nregs_rtx = GEN_INT (6);
7724 nregs_rtx = const0_rtx;
7727 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7731 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7733 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7738 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7739 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7743 /* If this call wants a structure value,
7744 emit an unimp insn to let the called function know about this. */
7745 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7747 rtx insn = emit_insn (operands[3]);
7748 SCHED_GROUP_P (insn) = 1;
7755 ;; We can't use the same pattern for these two insns, because then registers
7756 ;; in the address may not be properly reloaded.
7758 (define_insn "*call_address_sp32"
7759 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7760 (match_operand 1 "" ""))
7761 (clobber (reg:SI 15))]
7762 ;;- Do not use operand 1 for most machines.
7765 [(set_attr "type" "call")])
7767 (define_insn "*call_symbolic_sp32"
7768 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7769 (match_operand 1 "" ""))
7770 (clobber (reg:SI 15))]
7771 ;;- Do not use operand 1 for most machines.
7774 [(set_attr "type" "call")])
7776 (define_insn "*call_address_sp64"
7777 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7778 (match_operand 1 "" ""))
7779 (clobber (reg:DI 15))]
7780 ;;- Do not use operand 1 for most machines.
7783 [(set_attr "type" "call")])
7785 (define_insn "*call_symbolic_sp64"
7786 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7787 (match_operand 1 "" ""))
7788 (clobber (reg:DI 15))]
7789 ;;- Do not use operand 1 for most machines.
7792 [(set_attr "type" "call")])
7794 ;; This is a call that wants a structure value.
7795 ;; There is no such critter for v9 (??? we may need one anyway).
7796 (define_insn "*call_address_struct_value_sp32"
7797 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7798 (match_operand 1 "" ""))
7799 (match_operand 2 "immediate_operand" "")
7800 (clobber (reg:SI 15))]
7801 ;;- Do not use operand 1 for most machines.
7802 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7803 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7804 [(set_attr "type" "call_no_delay_slot")
7805 (set_attr "length" "3")])
7807 ;; This is a call that wants a structure value.
7808 ;; There is no such critter for v9 (??? we may need one anyway).
7809 (define_insn "*call_symbolic_struct_value_sp32"
7810 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7811 (match_operand 1 "" ""))
7812 (match_operand 2 "immediate_operand" "")
7813 (clobber (reg:SI 15))]
7814 ;;- Do not use operand 1 for most machines.
7815 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7816 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7817 [(set_attr "type" "call_no_delay_slot")
7818 (set_attr "length" "3")])
7820 ;; This is a call that may want a structure value. This is used for
7822 (define_insn "*call_address_untyped_struct_value_sp32"
7823 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7824 (match_operand 1 "" ""))
7825 (match_operand 2 "immediate_operand" "")
7826 (clobber (reg:SI 15))]
7827 ;;- Do not use operand 1 for most machines.
7828 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7829 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7830 [(set_attr "type" "call_no_delay_slot")
7831 (set_attr "length" "3")])
7833 ;; This is a call that wants a structure value.
7834 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7835 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7836 (match_operand 1 "" ""))
7837 (match_operand 2 "immediate_operand" "")
7838 (clobber (reg:SI 15))]
7839 ;;- Do not use operand 1 for most machines.
7840 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7841 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7842 [(set_attr "type" "call_no_delay_slot")
7843 (set_attr "length" "3")])
7845 (define_expand "call_value"
7846 ;; Note that this expression is not used for generating RTL.
7847 ;; All the RTL is generated explicitly below.
7848 [(set (match_operand 0 "register_operand" "=rf")
7849 (call (match_operand 1 "" "")
7850 (match_operand 4 "" "")))]
7851 ;; operand 2 is stack_size_rtx
7852 ;; operand 3 is next_arg_register
7856 rtx fn_rtx, nregs_rtx;
7859 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7862 fn_rtx = operands[1];
7866 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7868 nregs_rtx = GEN_INT (6);
7870 nregs_rtx = const0_rtx;
7874 gen_rtx_SET (VOIDmode, operands[0],
7875 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7876 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7878 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7883 (define_insn "*call_value_address_sp32"
7884 [(set (match_operand 0 "" "=rf")
7885 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7886 (match_operand 2 "" "")))
7887 (clobber (reg:SI 15))]
7888 ;;- Do not use operand 2 for most machines.
7891 [(set_attr "type" "call")])
7893 (define_insn "*call_value_symbolic_sp32"
7894 [(set (match_operand 0 "" "=rf")
7895 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7896 (match_operand 2 "" "")))
7897 (clobber (reg:SI 15))]
7898 ;;- Do not use operand 2 for most machines.
7901 [(set_attr "type" "call")])
7903 (define_insn "*call_value_address_sp64"
7904 [(set (match_operand 0 "" "")
7905 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7906 (match_operand 2 "" "")))
7907 (clobber (reg:DI 15))]
7908 ;;- Do not use operand 2 for most machines.
7911 [(set_attr "type" "call")])
7913 (define_insn "*call_value_symbolic_sp64"
7914 [(set (match_operand 0 "" "")
7915 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7916 (match_operand 2 "" "")))
7917 (clobber (reg:DI 15))]
7918 ;;- Do not use operand 2 for most machines.
7921 [(set_attr "type" "call")])
7923 (define_expand "untyped_call"
7924 [(parallel [(call (match_operand 0 "" "")
7926 (match_operand 1 "" "")
7927 (match_operand 2 "" "")])]
7933 /* Pass constm1 to indicate that it may expect a structure value, but
7934 we don't know what size it is. */
7935 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7937 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7939 rtx set = XVECEXP (operands[2], 0, i);
7940 emit_move_insn (SET_DEST (set), SET_SRC (set));
7943 /* The optimizer does not know that the call sets the function value
7944 registers we stored in the result block. We avoid problems by
7945 claiming that all hard registers are used and clobbered at this
7947 emit_insn (gen_blockage ());
7953 (define_expand "sibcall"
7954 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7959 (define_insn "*sibcall_symbolic_sp32"
7960 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7961 (match_operand 1 "" ""))
7964 "* return output_sibcall(insn, operands[0]);"
7965 [(set_attr "type" "sibcall")])
7967 (define_insn "*sibcall_symbolic_sp64"
7968 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7969 (match_operand 1 "" ""))
7972 "* return output_sibcall(insn, operands[0]);"
7973 [(set_attr "type" "sibcall")])
7975 (define_expand "sibcall_value"
7976 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7977 (call (match_operand 1 "" "") (const_int 0)))
7982 (define_insn "*sibcall_value_symbolic_sp32"
7983 [(set (match_operand 0 "" "=rf")
7984 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7985 (match_operand 2 "" "")))
7988 "* return output_sibcall(insn, operands[1]);"
7989 [(set_attr "type" "sibcall")])
7991 (define_insn "*sibcall_value_symbolic_sp64"
7992 [(set (match_operand 0 "" "")
7993 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7994 (match_operand 2 "" "")))
7997 "* return output_sibcall(insn, operands[1]);"
7998 [(set_attr "type" "sibcall")])
8000 (define_expand "sibcall_epilogue"
8005 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8006 ;; all of memory. This blocks insns from being moved across this point.
8008 (define_insn "blockage"
8009 [(unspec_volatile [(const_int 0)] 0)]
8012 [(set_attr "length" "0")])
8014 ;; Prepare to return any type including a structure value.
8016 (define_expand "untyped_return"
8017 [(match_operand:BLK 0 "memory_operand" "")
8018 (match_operand 1 "" "")]
8022 rtx valreg1 = gen_rtx_REG (DImode, 24);
8023 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8024 rtx result = operands[0];
8026 if (! TARGET_ARCH64)
8028 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8030 rtx value = gen_reg_rtx (SImode);
8032 /* Fetch the instruction where we will return to and see if it's an unimp
8033 instruction (the most significant 10 bits will be zero). If so,
8034 update the return address to skip the unimp instruction. */
8035 emit_move_insn (value,
8036 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8037 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8038 emit_insn (gen_update_return (rtnreg, value));
8041 /* Reload the function value registers. */
8042 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8043 emit_move_insn (valreg2,
8044 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8046 /* Put USE insns before the return. */
8047 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8048 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8050 /* Construct the return. */
8051 expand_null_return ();
8056 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8057 ;; and parts of the compiler don't want to believe that the add is needed.
8059 (define_insn "update_return"
8060 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8061 (match_operand:SI 1 "register_operand" "r")] 1)]
8063 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8064 [(set_attr "type" "multi")
8065 (set_attr "length" "3")])
8072 (define_expand "indirect_jump"
8073 [(set (pc) (match_operand 0 "address_operand" "p"))]
8077 (define_insn "*branch_sp32"
8078 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8081 [(set_attr "type" "uncond_branch")])
8083 (define_insn "*branch_sp64"
8084 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8087 [(set_attr "type" "uncond_branch")])
8089 ;; ??? Doesn't work with -mflat.
8090 (define_expand "nonlocal_goto"
8091 [(match_operand:SI 0 "general_operand" "")
8092 (match_operand:SI 1 "general_operand" "")
8093 (match_operand:SI 2 "general_operand" "")
8094 (match_operand:SI 3 "" "")]
8099 rtx chain = operands[0];
8101 rtx lab = operands[1];
8102 rtx stack = operands[2];
8103 rtx fp = operands[3];
8106 /* Trap instruction to flush all the register windows. */
8107 emit_insn (gen_flush_register_windows ());
8109 /* Load the fp value for the containing fn into %fp. This is needed
8110 because STACK refers to %fp. Note that virtual register instantiation
8111 fails if the virtual %fp isn't set from a register. */
8112 if (GET_CODE (fp) != REG)
8113 fp = force_reg (Pmode, fp);
8114 emit_move_insn (virtual_stack_vars_rtx, fp);
8116 /* Find the containing function's current nonlocal goto handler,
8117 which will do any cleanups and then jump to the label. */
8118 labreg = gen_rtx_REG (Pmode, 8);
8119 emit_move_insn (labreg, lab);
8121 /* Restore %fp from stack pointer value for containing function.
8122 The restore insn that follows will move this to %sp,
8123 and reload the appropriate value into %fp. */
8124 emit_move_insn (hard_frame_pointer_rtx, stack);
8126 /* USE of frame_pointer_rtx added for consistency; not clear if
8128 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8129 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8132 /* Return, restoring reg window and jumping to goto handler. */
8133 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8134 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8136 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8142 /* Put in the static chain register the nonlocal label address. */
8143 emit_move_insn (static_chain_rtx, chain);
8146 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8147 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8152 ;; Special trap insn to flush register windows.
8153 (define_insn "flush_register_windows"
8154 [(unspec_volatile [(const_int 0)] 1)]
8156 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8157 [(set_attr "type" "misc")])
8159 (define_insn "goto_handler_and_restore"
8160 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8161 "GET_MODE (operands[0]) == Pmode"
8162 "jmp\\t%0+0\\n\\trestore"
8163 [(set_attr "type" "multi")
8164 (set_attr "length" "2")])
8166 ;;(define_insn "goto_handler_and_restore_v9"
8167 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8168 ;; (match_operand:SI 1 "register_operand" "=r,r")
8169 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8170 ;; "TARGET_V9 && ! TARGET_ARCH64"
8172 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8173 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8174 ;; [(set_attr "type" "multi")
8175 ;; (set_attr "length" "2,3")])
8177 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8178 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8179 ;; (match_operand:DI 1 "register_operand" "=r,r")
8180 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8181 ;; "TARGET_V9 && TARGET_ARCH64"
8183 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8184 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8185 ;; [(set_attr "type" "multi")
8186 ;; (set_attr "length" "2,3")])
8188 ;; For __builtin_setjmp we need to flush register windows iff the function
8189 ;; calls alloca as well, because otherwise the register window might be
8190 ;; saved after %sp adjustement and thus setjmp would crash
8191 (define_expand "builtin_setjmp_setup"
8192 [(match_operand 0 "register_operand" "r")]
8196 emit_insn (gen_do_builtin_setjmp_setup ());
8200 (define_insn "do_builtin_setjmp_setup"
8201 [(unspec_volatile [(const_int 0)] 5)]
8205 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8207 fputs (\"\tflushw\n\", asm_out_file);
8209 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8210 TARGET_ARCH64 ? 'x' : 'w',
8211 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8212 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8213 TARGET_ARCH64 ? 'x' : 'w',
8214 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8215 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8216 TARGET_ARCH64 ? 'x' : 'w',
8217 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8220 [(set_attr "type" "misc")
8221 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8226 [(unspec_volatile [(const_int 0)] 5)]
8227 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8231 if (current_function_calls_alloca)
8232 emit_insn (gen_flush_register_windows ());
8236 ;; Pattern for use after a setjmp to store FP and the return register
8237 ;; into the stack area.
8239 (define_expand "setjmp"
8245 emit_insn (gen_setjmp_64 ());
8247 emit_insn (gen_setjmp_32 ());
8251 (define_expand "setjmp_32"
8252 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8253 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8256 { operands[0] = frame_pointer_rtx; }")
8258 (define_expand "setjmp_64"
8259 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8260 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8263 { operands[0] = frame_pointer_rtx; }")
8265 ;; Special pattern for the FLUSH instruction.
8267 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8268 ; of the define_insn otherwise missing a mode. We make "flush", aka
8269 ; gen_flush, the default one since sparc_initialize_trampoline uses
8270 ; it on SImode mem values.
8272 (define_insn "flush"
8273 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8275 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8276 [(set_attr "type" "misc")])
8278 (define_insn "flushdi"
8279 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8281 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8282 [(set_attr "type" "misc")])
8287 ;; The scan instruction searches from the most significant bit while ffs
8288 ;; searches from the least significant bit. The bit index and treatment of
8289 ;; zero also differ. It takes at least 7 instructions to get the proper
8290 ;; result. Here is an obvious 8 instruction sequence.
8293 (define_insn "ffssi2"
8294 [(set (match_operand:SI 0 "register_operand" "=&r")
8295 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8296 (clobber (match_scratch:SI 2 "=&r"))]
8297 "TARGET_SPARCLITE || TARGET_SPARCLET"
8300 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\";
8302 [(set_attr "type" "multi")
8303 (set_attr "length" "8")])
8305 ;; ??? This should be a define expand, so that the extra instruction have
8306 ;; a chance of being optimized away.
8308 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8309 ;; does, but no one uses that and we don't have a switch for it.
8311 ;(define_insn "ffsdi2"
8312 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8313 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8314 ; (clobber (match_scratch:DI 2 "=&r"))]
8316 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8317 ; [(set_attr "type" "multi")
8318 ; (set_attr "length" "4")])
8322 ;; Peepholes go at the end.
8324 ;; Optimize consecutive loads or stores into ldd and std when possible.
8325 ;; The conditions in which we do this are very restricted and are
8326 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8329 [(set (match_operand:SI 0 "memory_operand" "")
8331 (set (match_operand:SI 1 "memory_operand" "")
8334 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8337 "operands[0] = change_address (operands[0], DImode, NULL);")
8340 [(set (match_operand:SI 0 "memory_operand" "")
8342 (set (match_operand:SI 1 "memory_operand" "")
8345 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8348 "operands[1] = change_address (operands[1], DImode, NULL);")
8351 [(set (match_operand:SI 0 "register_operand" "")
8352 (match_operand:SI 1 "memory_operand" ""))
8353 (set (match_operand:SI 2 "register_operand" "")
8354 (match_operand:SI 3 "memory_operand" ""))]
8355 "registers_ok_for_ldd_peep (operands[0], operands[2])
8356 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8359 "operands[1] = change_address (operands[1], DImode, NULL);
8360 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8363 [(set (match_operand:SI 0 "memory_operand" "")
8364 (match_operand:SI 1 "register_operand" ""))
8365 (set (match_operand:SI 2 "memory_operand" "")
8366 (match_operand:SI 3 "register_operand" ""))]
8367 "registers_ok_for_ldd_peep (operands[1], operands[3])
8368 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8371 "operands[0] = change_address (operands[0], DImode, NULL);
8372 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8375 [(set (match_operand:SF 0 "register_operand" "")
8376 (match_operand:SF 1 "memory_operand" ""))
8377 (set (match_operand:SF 2 "register_operand" "")
8378 (match_operand:SF 3 "memory_operand" ""))]
8379 "registers_ok_for_ldd_peep (operands[0], operands[2])
8380 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8383 "operands[1] = change_address (operands[1], DFmode, NULL);
8384 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8387 [(set (match_operand:SF 0 "memory_operand" "")
8388 (match_operand:SF 1 "register_operand" ""))
8389 (set (match_operand:SF 2 "memory_operand" "")
8390 (match_operand:SF 3 "register_operand" ""))]
8391 "registers_ok_for_ldd_peep (operands[1], operands[3])
8392 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8395 "operands[0] = change_address (operands[0], DFmode, NULL);
8396 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8399 [(set (match_operand:SI 0 "register_operand" "")
8400 (match_operand:SI 1 "memory_operand" ""))
8401 (set (match_operand:SI 2 "register_operand" "")
8402 (match_operand:SI 3 "memory_operand" ""))]
8403 "registers_ok_for_ldd_peep (operands[2], operands[0])
8404 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8407 "operands[3] = change_address (operands[3], DImode, NULL);
8408 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8411 [(set (match_operand:SI 0 "memory_operand" "")
8412 (match_operand:SI 1 "register_operand" ""))
8413 (set (match_operand:SI 2 "memory_operand" "")
8414 (match_operand:SI 3 "register_operand" ""))]
8415 "registers_ok_for_ldd_peep (operands[3], operands[1])
8416 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8419 "operands[2] = change_address (operands[2], DImode, NULL);
8420 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8424 [(set (match_operand:SF 0 "register_operand" "")
8425 (match_operand:SF 1 "memory_operand" ""))
8426 (set (match_operand:SF 2 "register_operand" "")
8427 (match_operand:SF 3 "memory_operand" ""))]
8428 "registers_ok_for_ldd_peep (operands[2], operands[0])
8429 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8432 "operands[3] = change_address (operands[3], DFmode, NULL);
8433 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8436 [(set (match_operand:SF 0 "memory_operand" "")
8437 (match_operand:SF 1 "register_operand" ""))
8438 (set (match_operand:SF 2 "memory_operand" "")
8439 (match_operand:SF 3 "register_operand" ""))]
8440 "registers_ok_for_ldd_peep (operands[3], operands[1])
8441 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8444 "operands[2] = change_address (operands[2], DFmode, NULL);
8445 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8447 ;; Optimize the case of following a reg-reg move with a test
8448 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8449 ;; This can result from a float to fix conversion.
8452 [(set (match_operand:SI 0 "register_operand" "")
8453 (match_operand:SI 1 "register_operand" ""))
8455 (compare:CC (match_operand:SI 2 "register_operand" "")
8457 "(rtx_equal_p (operands[2], operands[0])
8458 || rtx_equal_p (operands[2], operands[1]))
8459 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8460 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8461 [(parallel [(set (match_dup 0) (match_dup 1))
8463 (compare:CC (match_dup 1) (const_int 0)))])]
8467 [(set (match_operand:DI 0 "register_operand" "")
8468 (match_operand:DI 1 "register_operand" ""))
8470 (compare:CCX (match_operand:DI 2 "register_operand" "")
8473 && (rtx_equal_p (operands[2], operands[0])
8474 || rtx_equal_p (operands[2], operands[1]))
8475 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8476 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8477 [(parallel [(set (match_dup 0) (match_dup 1))
8479 (compare:CCX (match_dup 1) (const_int 0)))])]
8482 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8483 ;; who then immediately calls final_scan_insn.
8485 (define_insn "*return_qi"
8486 [(set (match_operand:QI 0 "restore_operand" "")
8487 (match_operand:QI 1 "arith_operand" "rI"))
8489 "sparc_emitting_epilogue"
8492 if (! TARGET_ARCH64 && current_function_returns_struct)
8493 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8494 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8495 || IN_OR_GLOBAL_P (operands[1])))
8496 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8498 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8500 [(set_attr "type" "multi")
8501 (set_attr "length" "2")])
8503 (define_insn "*return_hi"
8504 [(set (match_operand:HI 0 "restore_operand" "")
8505 (match_operand:HI 1 "arith_operand" "rI"))
8507 "sparc_emitting_epilogue"
8510 if (! TARGET_ARCH64 && current_function_returns_struct)
8511 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8512 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8513 || IN_OR_GLOBAL_P (operands[1])))
8514 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8516 return \"ret\;restore %%g0, %1, %Y0\";
8518 [(set_attr "type" "multi")
8519 (set_attr "length" "2")])
8521 (define_insn "*return_si"
8522 [(set (match_operand:SI 0 "restore_operand" "")
8523 (match_operand:SI 1 "arith_operand" "rI"))
8525 "sparc_emitting_epilogue"
8528 if (! TARGET_ARCH64 && current_function_returns_struct)
8529 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8530 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8531 || IN_OR_GLOBAL_P (operands[1])))
8532 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8534 return \"ret\;restore %%g0, %1, %Y0\";
8536 [(set_attr "type" "multi")
8537 (set_attr "length" "2")])
8539 (define_insn "*return_sf_no_fpu"
8540 [(set (match_operand:SF 0 "restore_operand" "=r")
8541 (match_operand:SF 1 "register_operand" "r"))
8543 "sparc_emitting_epilogue"
8546 if (! TARGET_ARCH64 && current_function_returns_struct)
8547 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8548 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8549 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8551 return \"ret\;restore %%g0, %1, %Y0\";
8553 [(set_attr "type" "multi")
8554 (set_attr "length" "2")])
8556 (define_insn "*return_df_no_fpu"
8557 [(set (match_operand:DF 0 "restore_operand" "=r")
8558 (match_operand:DF 1 "register_operand" "r"))
8560 "sparc_emitting_epilogue && TARGET_ARCH64"
8563 if (IN_OR_GLOBAL_P (operands[1]))
8564 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8566 return \"ret\;restore %%g0, %1, %Y0\";
8568 [(set_attr "type" "multi")
8569 (set_attr "length" "2")])
8571 (define_insn "*return_addsi"
8572 [(set (match_operand:SI 0 "restore_operand" "")
8573 (plus:SI (match_operand:SI 1 "register_operand" "r")
8574 (match_operand:SI 2 "arith_operand" "rI")))
8576 "sparc_emitting_epilogue"
8579 if (! TARGET_ARCH64 && current_function_returns_struct)
8580 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8581 /* If operands are global or in registers, can use return */
8582 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8583 && (GET_CODE (operands[2]) == CONST_INT
8584 || IN_OR_GLOBAL_P (operands[2])))
8585 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8587 return \"ret\;restore %r1, %2, %Y0\";
8589 [(set_attr "type" "multi")
8590 (set_attr "length" "2")])
8592 (define_insn "*return_losum_si"
8593 [(set (match_operand:SI 0 "restore_operand" "")
8594 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8595 (match_operand:SI 2 "immediate_operand" "in")))
8597 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8600 if (! TARGET_ARCH64 && current_function_returns_struct)
8601 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8602 /* If operands are global or in registers, can use return */
8603 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8604 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8606 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8608 [(set_attr "type" "multi")
8609 (set_attr "length" "2")])
8611 (define_insn "*return_di"
8612 [(set (match_operand:DI 0 "restore_operand" "")
8613 (match_operand:DI 1 "arith_double_operand" "rHI"))
8615 "sparc_emitting_epilogue && TARGET_ARCH64"
8616 "ret\;restore %%g0, %1, %Y0"
8617 [(set_attr "type" "multi")
8618 (set_attr "length" "2")])
8620 (define_insn "*return_adddi"
8621 [(set (match_operand:DI 0 "restore_operand" "")
8622 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8623 (match_operand:DI 2 "arith_double_operand" "rHI")))
8625 "sparc_emitting_epilogue && TARGET_ARCH64"
8626 "ret\;restore %r1, %2, %Y0"
8627 [(set_attr "type" "multi")
8628 (set_attr "length" "2")])
8630 (define_insn "*return_losum_di"
8631 [(set (match_operand:DI 0 "restore_operand" "")
8632 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8633 (match_operand:DI 2 "immediate_operand" "in")))
8635 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8636 "ret\;restore %r1, %%lo(%a2), %Y0"
8637 [(set_attr "type" "multi")
8638 (set_attr "length" "2")])
8640 (define_insn "*return_sf"
8642 (match_operand:SF 0 "register_operand" "f"))
8644 "sparc_emitting_epilogue"
8645 "ret\;fmovs\\t%0, %%f0"
8646 [(set_attr "type" "multi")
8647 (set_attr "length" "2")])
8649 ;; Now peepholes to do a call followed by a jump.
8652 [(parallel [(set (match_operand 0 "" "")
8653 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8654 (match_operand 2 "" "")))
8655 (clobber (reg:SI 15))])
8656 (set (pc) (label_ref (match_operand 3 "" "")))]
8657 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8658 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8659 && sparc_cpu != PROCESSOR_ULTRASPARC
8660 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8661 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8664 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8665 (match_operand 1 "" ""))
8666 (clobber (reg:SI 15))])
8667 (set (pc) (label_ref (match_operand 2 "" "")))]
8668 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8669 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8670 && sparc_cpu != PROCESSOR_ULTRASPARC
8671 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8672 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8674 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8675 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8676 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8678 (define_expand "prefetch"
8679 [(match_operand 0 "address_operand" "")
8680 (match_operand 1 "const_int_operand" "")
8681 (match_operand 2 "const_int_operand" "")]
8686 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8688 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8692 (define_insn "prefetch_64"
8693 [(prefetch (match_operand:DI 0 "address_operand" "p")
8694 (match_operand:DI 1 "const_int_operand" "n")
8695 (match_operand:DI 2 "const_int_operand" "n"))]
8698 static const char * const prefetch_instr[2][2] = {
8700 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8701 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8704 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8705 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8708 int read_or_write = INTVAL (operands[1]);
8709 int locality = INTVAL (operands[2]);
8711 if (read_or_write != 0 && read_or_write != 1)
8713 if (locality < 0 || locality > 3)
8715 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8717 [(set_attr "type" "load")])
8719 (define_insn "prefetch_32"
8720 [(prefetch (match_operand:SI 0 "address_operand" "p")
8721 (match_operand:SI 1 "const_int_operand" "n")
8722 (match_operand:SI 2 "const_int_operand" "n"))]
8725 static const char * const prefetch_instr[2][2] = {
8727 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8728 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8731 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8732 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8735 int read_or_write = INTVAL (operands[1]);
8736 int locality = INTVAL (operands[2]);
8738 if (read_or_write != 0 && read_or_write != 1)
8740 if (locality < 0 || locality > 3)
8742 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8744 [(set_attr "type" "load")])
8746 (define_expand "prologue"
8748 "flag_pic && current_function_uses_pic_offset_table"
8751 load_pic_register ();
8755 ;; We need to reload %l7 for -mflat -fpic,
8756 ;; otherwise %l7 should be preserved simply
8757 ;; by loading the function's register window
8758 (define_expand "exception_receiver"
8760 "TARGET_FLAT && flag_pic"
8763 load_pic_register ();
8768 (define_expand "builtin_setjmp_receiver"
8769 [(label_ref (match_operand 0 "" ""))]
8770 "TARGET_FLAT && flag_pic"
8773 load_pic_register ();
8778 [(trap_if (const_int 1) (const_int 5))]
8781 [(set_attr "type" "misc")])
8783 (define_expand "conditional_trap"
8784 [(trap_if (match_operator 0 "noov_compare_op"
8785 [(match_dup 2) (match_dup 3)])
8786 (match_operand:SI 1 "arith_operand" ""))]
8788 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8789 sparc_compare_op0, sparc_compare_op1);
8790 operands[3] = const0_rtx;")
8793 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8794 (match_operand:SI 1 "arith_operand" "rM"))]
8797 [(set_attr "type" "misc")])
8800 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8801 (match_operand:SI 1 "arith_operand" "rM"))]
8804 [(set_attr "type" "misc")])