1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
49 (UNSPEC_TLSLD_BASE 35)
80 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
81 (define_mode_iterator I [QI HI SI DI])
82 (define_mode_iterator F [SF DF TF])
84 ;; We don't define V1SI because SI should work just fine.
85 (define_mode_iterator V32 [SF V2HI V4QI])
86 (define_mode_iterator V32I [SI V2HI V4QI])
88 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
89 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
91 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
92 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
93 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
94 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
95 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
98 ;; Attribute for cpu type.
99 ;; These must match the values for enum processor_type in sparc.h.
106 hypersparc,sparclite86x,
113 (const (symbol_ref "sparc_cpu_attr")))
115 ;; Attribute for the instruction set.
116 ;; At present we only need to distinguish v9/!v9, but for clarity we
117 ;; test TARGET_V8 too.
118 (define_attr "isa" "v7,v8,v9,sparclet"
120 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
121 (symbol_ref "TARGET_V8") (const_string "v8")
122 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
123 (const_string "v7"))))
129 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
137 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
140 multi,savew,flushw,iflush,trap"
141 (const_string "ialu"))
143 ;; True if branch/call has empty delay slot and will emit a nop in it
144 (define_attr "empty_delay_slot" "false,true"
145 (symbol_ref "(empty_delay_slot (insn)
146 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
148 (define_attr "branch_type" "none,icc,fcc,reg"
149 (const_string "none"))
151 (define_attr "pic" "false,true"
152 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
154 (define_attr "calls_alloca" "false,true"
155 (symbol_ref "(cfun->calls_alloca != 0
156 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
158 (define_attr "calls_eh_return" "false,true"
159 (symbol_ref "(crtl->calls_eh_return != 0
160 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
162 (define_attr "leaf_function" "false,true"
163 (symbol_ref "(current_function_uses_only_leaf_regs != 0
164 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
166 (define_attr "delayed_branch" "false,true"
167 (symbol_ref "(flag_delayed_branch != 0
168 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
170 ;; Length (in # of insns).
171 ;; Beware that setting a length greater or equal to 3 for conditional branches
172 ;; has a side-effect (see output_cbranch and output_v9branch).
173 (define_attr "length" ""
174 (cond [(eq_attr "type" "uncond_branch,call")
175 (if_then_else (eq_attr "empty_delay_slot" "true")
178 (eq_attr "type" "sibcall")
179 (if_then_else (eq_attr "leaf_function" "true")
180 (if_then_else (eq_attr "empty_delay_slot" "true")
183 (if_then_else (eq_attr "empty_delay_slot" "true")
186 (eq_attr "branch_type" "icc")
187 (if_then_else (match_operand 0 "noov_compare64_operator" "")
188 (if_then_else (lt (pc) (match_dup 1))
189 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
190 (if_then_else (eq_attr "empty_delay_slot" "true")
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
197 (if_then_else (eq_attr "empty_delay_slot" "true")
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (eq_attr "empty_delay_slot" "true")
206 (eq_attr "branch_type" "fcc")
207 (if_then_else (match_operand 0 "fcc0_register_operand" "")
208 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
212 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
215 (if_then_else (lt (pc) (match_dup 2))
216 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
217 (if_then_else (eq_attr "empty_delay_slot" "true")
220 (if_then_else (eq_attr "empty_delay_slot" "true")
223 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
224 (if_then_else (eq_attr "empty_delay_slot" "true")
227 (if_then_else (eq_attr "empty_delay_slot" "true")
230 (eq_attr "branch_type" "reg")
231 (if_then_else (lt (pc) (match_dup 2))
232 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
233 (if_then_else (eq_attr "empty_delay_slot" "true")
236 (if_then_else (eq_attr "empty_delay_slot" "true")
239 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
240 (if_then_else (eq_attr "empty_delay_slot" "true")
243 (if_then_else (eq_attr "empty_delay_slot" "true")
249 (define_attr "fptype" "single,double"
250 (const_string "single"))
252 ;; UltraSPARC-III integer load type.
253 (define_attr "us3load_type" "2cycle,3cycle"
254 (const_string "2cycle"))
256 (define_asm_attributes
257 [(set_attr "length" "2")
258 (set_attr "type" "multi")])
260 ;; Attributes for instruction and branch scheduling
261 (define_attr "tls_call_delay" "false,true"
262 (symbol_ref "(tls_call_delay (insn)
263 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
265 (define_attr "in_call_delay" "false,true"
266 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
267 (const_string "false")
268 (eq_attr "type" "load,fpload,store,fpstore")
269 (if_then_else (eq_attr "length" "1")
270 (const_string "true")
271 (const_string "false"))]
272 (if_then_else (and (eq_attr "length" "1")
273 (eq_attr "tls_call_delay" "true"))
274 (const_string "true")
275 (const_string "false"))))
277 (define_attr "eligible_for_sibcall_delay" "false,true"
278 (symbol_ref "(eligible_for_sibcall_delay (insn)
279 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
280 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
282 (define_attr "eligible_for_return_delay" "false,true"
283 (symbol_ref "(eligible_for_return_delay (insn)
284 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
285 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
287 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
288 ;; branches. This would allow us to remove the nop always inserted before
289 ;; a floating point branch.
291 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
292 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
293 ;; This is because doing so will add several pipeline stalls to the path
294 ;; that the load/store did not come from. Unfortunately, there is no way
295 ;; to prevent fill_eager_delay_slots from using load/store without completely
296 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
297 ;; because it prevents us from moving back the final store of inner loops.
299 (define_attr "in_branch_delay" "false,true"
300 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
301 (eq_attr "length" "1"))
302 (const_string "true")
303 (const_string "false")))
305 (define_attr "in_uncond_branch_delay" "false,true"
306 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
307 (eq_attr "length" "1"))
308 (const_string "true")
309 (const_string "false")))
311 (define_attr "in_annul_branch_delay" "false,true"
312 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
313 (eq_attr "length" "1"))
314 (const_string "true")
315 (const_string "false")))
317 (define_delay (eq_attr "type" "call")
318 [(eq_attr "in_call_delay" "true") (nil) (nil)])
320 (define_delay (eq_attr "type" "sibcall")
321 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
323 (define_delay (eq_attr "type" "branch")
324 [(eq_attr "in_branch_delay" "true")
325 (nil) (eq_attr "in_annul_branch_delay" "true")])
327 (define_delay (eq_attr "type" "uncond_branch")
328 [(eq_attr "in_uncond_branch_delay" "true")
331 (define_delay (eq_attr "type" "return")
332 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
335 ;; Include SPARC DFA schedulers
337 (include "cypress.md")
338 (include "supersparc.md")
339 (include "hypersparc.md")
340 (include "sparclet.md")
341 (include "ultra1_2.md")
342 (include "ultra3.md")
343 (include "niagara.md")
344 (include "niagara2.md")
347 ;; Operand and operator predicates and constraints
349 (include "predicates.md")
350 (include "constraints.md")
353 ;; Compare instructions.
355 ;; These are just the DEFINE_INSNs to match the patterns and the
356 ;; DEFINE_SPLITs for some of the scc insns that actually require
357 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
359 ;; The compare DEFINE_INSNs.
361 (define_insn "*cmpsi_insn"
363 (compare:CC (match_operand:SI 0 "register_operand" "r")
364 (match_operand:SI 1 "arith_operand" "rI")))]
367 [(set_attr "type" "compare")])
369 (define_insn "*cmpdi_sp64"
371 (compare:CCX (match_operand:DI 0 "register_operand" "r")
372 (match_operand:DI 1 "arith_operand" "rI")))]
375 [(set_attr "type" "compare")])
377 (define_insn "*cmpsf_fpe"
378 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
379 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
380 (match_operand:SF 2 "register_operand" "f")))]
384 return "fcmpes\t%0, %1, %2";
385 return "fcmpes\t%1, %2";
387 [(set_attr "type" "fpcmp")])
389 (define_insn "*cmpdf_fpe"
390 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
391 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
392 (match_operand:DF 2 "register_operand" "e")))]
396 return "fcmped\t%0, %1, %2";
397 return "fcmped\t%1, %2";
399 [(set_attr "type" "fpcmp")
400 (set_attr "fptype" "double")])
402 (define_insn "*cmptf_fpe"
403 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
404 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
405 (match_operand:TF 2 "register_operand" "e")))]
406 "TARGET_FPU && TARGET_HARD_QUAD"
409 return "fcmpeq\t%0, %1, %2";
410 return "fcmpeq\t%1, %2";
412 [(set_attr "type" "fpcmp")])
414 (define_insn "*cmpsf_fp"
415 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
416 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
417 (match_operand:SF 2 "register_operand" "f")))]
421 return "fcmps\t%0, %1, %2";
422 return "fcmps\t%1, %2";
424 [(set_attr "type" "fpcmp")])
426 (define_insn "*cmpdf_fp"
427 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
428 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
429 (match_operand:DF 2 "register_operand" "e")))]
433 return "fcmpd\t%0, %1, %2";
434 return "fcmpd\t%1, %2";
436 [(set_attr "type" "fpcmp")
437 (set_attr "fptype" "double")])
439 (define_insn "*cmptf_fp"
440 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
441 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
442 (match_operand:TF 2 "register_operand" "e")))]
443 "TARGET_FPU && TARGET_HARD_QUAD"
446 return "fcmpq\t%0, %1, %2";
447 return "fcmpq\t%1, %2";
449 [(set_attr "type" "fpcmp")])
451 ;; Next come the scc insns.
453 (define_expand "cstoresi4"
454 [(use (match_operator 1 "comparison_operator"
455 [(match_operand:SI 2 "compare_operand" "")
456 (match_operand:SI 3 "arith_operand" "")]))
457 (clobber (match_operand:SI 0 "register_operand"))]
460 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
461 operands[2] = force_reg (SImode, operands[2]);
462 if (emit_scc_insn (operands)) DONE; else FAIL;
465 (define_expand "cstoredi4"
466 [(use (match_operator 1 "comparison_operator"
467 [(match_operand:DI 2 "compare_operand" "")
468 (match_operand:DI 3 "arith_operand" "")]))
469 (clobber (match_operand:SI 0 "register_operand"))]
472 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
473 operands[2] = force_reg (DImode, operands[2]);
474 if (emit_scc_insn (operands)) DONE; else FAIL;
477 (define_expand "cstore<F:mode>4"
478 [(use (match_operator 1 "comparison_operator"
479 [(match_operand:F 2 "register_operand" "")
480 (match_operand:F 3 "register_operand" "")]))
481 (clobber (match_operand:SI 0 "register_operand"))]
483 { if (emit_scc_insn (operands)) DONE; else FAIL; })
487 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
488 ;; generate addcc/subcc instructions.
490 (define_expand "seqsi_special"
492 (xor:SI (match_operand:SI 1 "register_operand" "")
493 (match_operand:SI 2 "register_operand" "")))
494 (parallel [(set (match_operand:SI 0 "register_operand" "")
495 (eq:SI (match_dup 3) (const_int 0)))
496 (clobber (reg:CC 100))])]
498 { operands[3] = gen_reg_rtx (SImode); })
500 (define_expand "seqdi_special"
502 (xor:DI (match_operand:DI 1 "register_operand" "")
503 (match_operand:DI 2 "register_operand" "")))
504 (set (match_operand:SI 0 "register_operand" "")
505 (eq:SI (match_dup 3) (const_int 0)))]
507 { operands[3] = gen_reg_rtx (DImode); })
509 (define_expand "snesi_special"
511 (xor:SI (match_operand:SI 1 "register_operand" "")
512 (match_operand:SI 2 "register_operand" "")))
513 (parallel [(set (match_operand:SI 0 "register_operand" "")
514 (ne:SI (match_dup 3) (const_int 0)))
515 (clobber (reg:CC 100))])]
517 { operands[3] = gen_reg_rtx (SImode); })
519 (define_expand "snedi_special"
521 (xor:DI (match_operand:DI 1 "register_operand" "")
522 (match_operand:DI 2 "register_operand" "")))
523 (set (match_operand:SI 0 "register_operand" "")
524 (ne:SI (match_dup 3) (const_int 0)))]
526 { operands[3] = gen_reg_rtx (DImode); })
529 ;; Now the DEFINE_INSNs for the scc cases.
531 ;; The SEQ and SNE patterns are special because they can be done
532 ;; without any branching and do not involve a COMPARE. We want
533 ;; them to always use the splits below so the results can be
536 (define_insn_and_split "*snesi_zero"
537 [(set (match_operand:SI 0 "register_operand" "=r")
538 (ne:SI (match_operand:SI 1 "register_operand" "r")
540 (clobber (reg:CC 100))]
544 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
546 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
548 [(set_attr "length" "2")])
550 (define_insn_and_split "*neg_snesi_zero"
551 [(set (match_operand:SI 0 "register_operand" "=r")
552 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
554 (clobber (reg:CC 100))]
558 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
560 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
562 [(set_attr "length" "2")])
564 (define_insn_and_split "*snesi_zero_extend"
565 [(set (match_operand:DI 0 "register_operand" "=r")
566 (ne:DI (match_operand:SI 1 "register_operand" "r")
568 (clobber (reg:CC 100))]
572 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
575 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
577 (ltu:SI (reg:CC_NOOV 100)
580 [(set_attr "length" "2")])
582 (define_insn_and_split "*snedi_zero"
583 [(set (match_operand:DI 0 "register_operand" "=&r")
584 (ne:DI (match_operand:DI 1 "register_operand" "r")
588 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
589 [(set (match_dup 0) (const_int 0))
590 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
595 [(set_attr "length" "2")])
597 (define_insn_and_split "*neg_snedi_zero"
598 [(set (match_operand:DI 0 "register_operand" "=&r")
599 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
603 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
604 [(set (match_dup 0) (const_int 0))
605 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
610 [(set_attr "length" "2")])
612 (define_insn_and_split "*snedi_zero_trunc"
613 [(set (match_operand:SI 0 "register_operand" "=&r")
614 (ne:SI (match_operand:DI 1 "register_operand" "r")
618 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
619 [(set (match_dup 0) (const_int 0))
620 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
625 [(set_attr "length" "2")])
627 (define_insn_and_split "*seqsi_zero"
628 [(set (match_operand:SI 0 "register_operand" "=r")
629 (eq:SI (match_operand:SI 1 "register_operand" "r")
631 (clobber (reg:CC 100))]
635 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
637 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
639 [(set_attr "length" "2")])
641 (define_insn_and_split "*neg_seqsi_zero"
642 [(set (match_operand:SI 0 "register_operand" "=r")
643 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
645 (clobber (reg:CC 100))]
649 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
651 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
653 [(set_attr "length" "2")])
655 (define_insn_and_split "*seqsi_zero_extend"
656 [(set (match_operand:DI 0 "register_operand" "=r")
657 (eq:DI (match_operand:SI 1 "register_operand" "r")
659 (clobber (reg:CC 100))]
663 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
666 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
668 (ltu:SI (reg:CC_NOOV 100)
671 [(set_attr "length" "2")])
673 (define_insn_and_split "*seqdi_zero"
674 [(set (match_operand:DI 0 "register_operand" "=&r")
675 (eq:DI (match_operand:DI 1 "register_operand" "r")
679 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
680 [(set (match_dup 0) (const_int 0))
681 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
686 [(set_attr "length" "2")])
688 (define_insn_and_split "*neg_seqdi_zero"
689 [(set (match_operand:DI 0 "register_operand" "=&r")
690 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
694 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
695 [(set (match_dup 0) (const_int 0))
696 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
701 [(set_attr "length" "2")])
703 (define_insn_and_split "*seqdi_zero_trunc"
704 [(set (match_operand:SI 0 "register_operand" "=&r")
705 (eq:SI (match_operand:DI 1 "register_operand" "r")
709 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
710 [(set (match_dup 0) (const_int 0))
711 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
716 [(set_attr "length" "2")])
718 ;; We can also do (x + (i == 0)) and related, so put them in.
719 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
722 (define_insn_and_split "*x_plus_i_ne_0"
723 [(set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
726 (match_operand:SI 2 "register_operand" "r")))
727 (clobber (reg:CC 100))]
731 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
733 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
736 [(set_attr "length" "2")])
738 (define_insn_and_split "*x_minus_i_ne_0"
739 [(set (match_operand:SI 0 "register_operand" "=r")
740 (minus:SI (match_operand:SI 2 "register_operand" "r")
741 (ne:SI (match_operand:SI 1 "register_operand" "r")
743 (clobber (reg:CC 100))]
747 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
749 (set (match_dup 0) (minus:SI (match_dup 2)
750 (ltu:SI (reg:CC 100) (const_int 0))))]
752 [(set_attr "length" "2")])
754 (define_insn_and_split "*x_plus_i_eq_0"
755 [(set (match_operand:SI 0 "register_operand" "=r")
756 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
758 (match_operand:SI 2 "register_operand" "r")))
759 (clobber (reg:CC 100))]
763 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
765 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
768 [(set_attr "length" "2")])
770 (define_insn_and_split "*x_minus_i_eq_0"
771 [(set (match_operand:SI 0 "register_operand" "=r")
772 (minus:SI (match_operand:SI 2 "register_operand" "r")
773 (eq:SI (match_operand:SI 1 "register_operand" "r")
775 (clobber (reg:CC 100))]
779 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
781 (set (match_dup 0) (minus:SI (match_dup 2)
782 (geu:SI (reg:CC 100) (const_int 0))))]
784 [(set_attr "length" "2")])
786 ;; We can also do GEU and LTU directly, but these operate after a compare.
787 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
790 (define_insn "*sltu_insn"
791 [(set (match_operand:SI 0 "register_operand" "=r")
792 (ltu:SI (reg:CC 100) (const_int 0)))]
795 [(set_attr "type" "ialuX")])
797 (define_insn "*neg_sltu_insn"
798 [(set (match_operand:SI 0 "register_operand" "=r")
799 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
802 [(set_attr "type" "ialuX")])
804 ;; ??? Combine should canonicalize these next two to the same pattern.
805 (define_insn "*neg_sltu_minus_x"
806 [(set (match_operand:SI 0 "register_operand" "=r")
807 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
808 (match_operand:SI 1 "arith_operand" "rI")))]
811 [(set_attr "type" "ialuX")])
813 (define_insn "*neg_sltu_plus_x"
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
816 (match_operand:SI 1 "arith_operand" "rI"))))]
819 [(set_attr "type" "ialuX")])
821 (define_insn "*sgeu_insn"
822 [(set (match_operand:SI 0 "register_operand" "=r")
823 (geu:SI (reg:CC 100) (const_int 0)))]
826 [(set_attr "type" "ialuX")])
828 (define_insn "*neg_sgeu_insn"
829 [(set (match_operand:SI 0 "register_operand" "=r")
830 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
833 [(set_attr "type" "ialuX")])
835 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
836 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
839 (define_insn "*sltu_plus_x"
840 [(set (match_operand:SI 0 "register_operand" "=r")
841 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
842 (match_operand:SI 1 "arith_operand" "rI")))]
845 [(set_attr "type" "ialuX")])
847 (define_insn "*sltu_plus_x_plus_y"
848 [(set (match_operand:SI 0 "register_operand" "=r")
849 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
850 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
851 (match_operand:SI 2 "arith_operand" "rI"))))]
854 [(set_attr "type" "ialuX")])
856 (define_insn "*x_minus_sltu"
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (minus:SI (match_operand:SI 1 "register_operand" "r")
859 (ltu:SI (reg:CC 100) (const_int 0))))]
862 [(set_attr "type" "ialuX")])
864 ;; ??? Combine should canonicalize these next two to the same pattern.
865 (define_insn "*x_minus_y_minus_sltu"
866 [(set (match_operand:SI 0 "register_operand" "=r")
867 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
868 (match_operand:SI 2 "arith_operand" "rI"))
869 (ltu:SI (reg:CC 100) (const_int 0))))]
872 [(set_attr "type" "ialuX")])
874 (define_insn "*x_minus_sltu_plus_y"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
877 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
878 (match_operand:SI 2 "arith_operand" "rI"))))]
881 [(set_attr "type" "ialuX")])
883 (define_insn "*sgeu_plus_x"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
886 (match_operand:SI 1 "register_operand" "r")))]
889 [(set_attr "type" "ialuX")])
891 (define_insn "*x_minus_sgeu"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (minus:SI (match_operand:SI 1 "register_operand" "r")
894 (geu:SI (reg:CC 100) (const_int 0))))]
897 [(set_attr "type" "ialuX")])
900 [(set (match_operand:SI 0 "register_operand" "")
901 (match_operator:SI 2 "noov_compare_operator"
902 [(match_operand 1 "icc_or_fcc_register_operand" "")
905 && REGNO (operands[1]) == SPARC_ICC_REG
906 && (GET_MODE (operands[1]) == CCXmode
907 /* 32-bit LTU/GEU are better implemented using addx/subx. */
908 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
909 [(set (match_dup 0) (const_int 0))
911 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
917 ;; These control RTL generation for conditional jump insns
919 (define_expand "cbranchcc4"
921 (if_then_else (match_operator 0 "comparison_operator"
922 [(match_operand 1 "compare_operand" "")
923 (match_operand 2 "const_zero_operand" "")])
924 (label_ref (match_operand 3 "" ""))
929 (define_expand "cbranchsi4"
930 [(use (match_operator 0 "comparison_operator"
931 [(match_operand:SI 1 "compare_operand" "")
932 (match_operand:SI 2 "arith_operand" "")]))
933 (use (match_operand 3 ""))]
936 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
937 operands[1] = force_reg (SImode, operands[1]);
938 emit_conditional_branch_insn (operands);
942 (define_expand "cbranchdi4"
943 [(use (match_operator 0 "comparison_operator"
944 [(match_operand:DI 1 "compare_operand" "")
945 (match_operand:DI 2 "arith_operand" "")]))
946 (use (match_operand 3 ""))]
949 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
950 operands[1] = force_reg (DImode, operands[1]);
951 emit_conditional_branch_insn (operands);
955 (define_expand "cbranch<F:mode>4"
956 [(use (match_operator 0 "comparison_operator"
957 [(match_operand:F 1 "register_operand" "")
958 (match_operand:F 2 "register_operand" "")]))
959 (use (match_operand 3 ""))]
961 { emit_conditional_branch_insn (operands); DONE; })
964 ;; Now match both normal and inverted jump.
966 ;; XXX fpcmp nop braindamage
967 (define_insn "*normal_branch"
969 (if_then_else (match_operator 0 "noov_compare_operator"
970 [(reg 100) (const_int 0)])
971 (label_ref (match_operand 1 "" ""))
975 return output_cbranch (operands[0], operands[1], 1, 0,
976 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
979 [(set_attr "type" "branch")
980 (set_attr "branch_type" "icc")])
982 ;; XXX fpcmp nop braindamage
983 (define_insn "*inverted_branch"
985 (if_then_else (match_operator 0 "noov_compare_operator"
986 [(reg 100) (const_int 0)])
988 (label_ref (match_operand 1 "" ""))))]
991 return output_cbranch (operands[0], operands[1], 1, 1,
992 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
995 [(set_attr "type" "branch")
996 (set_attr "branch_type" "icc")])
998 ;; XXX fpcmp nop braindamage
999 (define_insn "*normal_fp_branch"
1001 (if_then_else (match_operator 1 "comparison_operator"
1002 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1004 (label_ref (match_operand 2 "" ""))
1008 return output_cbranch (operands[1], operands[2], 2, 0,
1009 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1012 [(set_attr "type" "branch")
1013 (set_attr "branch_type" "fcc")])
1015 ;; XXX fpcmp nop braindamage
1016 (define_insn "*inverted_fp_branch"
1018 (if_then_else (match_operator 1 "comparison_operator"
1019 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1022 (label_ref (match_operand 2 "" ""))))]
1025 return output_cbranch (operands[1], operands[2], 2, 1,
1026 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1029 [(set_attr "type" "branch")
1030 (set_attr "branch_type" "fcc")])
1032 ;; XXX fpcmp nop braindamage
1033 (define_insn "*normal_fpe_branch"
1035 (if_then_else (match_operator 1 "comparison_operator"
1036 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1038 (label_ref (match_operand 2 "" ""))
1042 return output_cbranch (operands[1], operands[2], 2, 0,
1043 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1046 [(set_attr "type" "branch")
1047 (set_attr "branch_type" "fcc")])
1049 ;; XXX fpcmp nop braindamage
1050 (define_insn "*inverted_fpe_branch"
1052 (if_then_else (match_operator 1 "comparison_operator"
1053 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1056 (label_ref (match_operand 2 "" ""))))]
1059 return output_cbranch (operands[1], operands[2], 2, 1,
1060 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1063 [(set_attr "type" "branch")
1064 (set_attr "branch_type" "fcc")])
1066 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1067 ;; in the architecture.
1069 ;; There are no 32 bit brreg insns.
1072 (define_insn "*normal_int_branch_sp64"
1074 (if_then_else (match_operator 0 "v9_register_compare_operator"
1075 [(match_operand:DI 1 "register_operand" "r")
1077 (label_ref (match_operand 2 "" ""))
1081 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1082 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1085 [(set_attr "type" "branch")
1086 (set_attr "branch_type" "reg")])
1089 (define_insn "*inverted_int_branch_sp64"
1091 (if_then_else (match_operator 0 "v9_register_compare_operator"
1092 [(match_operand:DI 1 "register_operand" "r")
1095 (label_ref (match_operand 2 "" ""))))]
1098 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1099 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1102 [(set_attr "type" "branch")
1103 (set_attr "branch_type" "reg")])
1106 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1107 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1108 ;; that adds the PC value at the call point to operand 0.
1110 (define_insn "load_pcrel_sym<P:mode>"
1111 [(set (match_operand:P 0 "register_operand" "=r")
1112 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1113 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1114 (clobber (reg:P 15))]
1117 if (flag_delayed_branch)
1118 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1120 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1122 [(set (attr "type") (const_string "multi"))
1123 (set (attr "length")
1124 (if_then_else (eq_attr "delayed_branch" "true")
1129 ;; Integer move instructions
1131 (define_expand "movqi"
1132 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1133 (match_operand:QI 1 "general_operand" ""))]
1136 if (sparc_expand_move (QImode, operands))
1140 (define_insn "*movqi_insn"
1141 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1142 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1143 "(register_operand (operands[0], QImode)
1144 || register_or_zero_operand (operands[1], QImode))"
1149 [(set_attr "type" "*,load,store")
1150 (set_attr "us3load_type" "*,3cycle,*")])
1152 (define_expand "movhi"
1153 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1154 (match_operand:HI 1 "general_operand" ""))]
1157 if (sparc_expand_move (HImode, operands))
1161 (define_insn "*movhi_insn"
1162 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1163 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1164 "(register_operand (operands[0], HImode)
1165 || register_or_zero_operand (operands[1], HImode))"
1168 sethi\t%%hi(%a1), %0
1171 [(set_attr "type" "*,*,load,store")
1172 (set_attr "us3load_type" "*,*,3cycle,*")])
1174 ;; We always work with constants here.
1175 (define_insn "*movhi_lo_sum"
1176 [(set (match_operand:HI 0 "register_operand" "=r")
1177 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1178 (match_operand:HI 2 "small_int_operand" "I")))]
1182 (define_expand "movsi"
1183 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1184 (match_operand:SI 1 "general_operand" ""))]
1187 if (sparc_expand_move (SImode, operands))
1191 (define_insn "*movsi_insn"
1192 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1193 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1194 "(register_operand (operands[0], SImode)
1195 || register_or_zero_operand (operands[1], SImode))"
1198 sethi\t%%hi(%a1), %0
1205 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1207 (define_insn "*movsi_lo_sum"
1208 [(set (match_operand:SI 0 "register_operand" "=r")
1209 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1210 (match_operand:SI 2 "immediate_operand" "in")))]
1212 "or\t%1, %%lo(%a2), %0")
1214 (define_insn "*movsi_high"
1215 [(set (match_operand:SI 0 "register_operand" "=r")
1216 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1218 "sethi\t%%hi(%a1), %0")
1220 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1221 ;; so that CSE won't optimize the address computation away.
1222 (define_insn "movsi_lo_sum_pic"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1225 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1227 "or\t%1, %%lo(%a2), %0")
1229 (define_insn "movsi_high_pic"
1230 [(set (match_operand:SI 0 "register_operand" "=r")
1231 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1232 "flag_pic && check_pic (1)"
1233 "sethi\t%%hi(%a1), %0")
1235 (define_expand "movsi_pic_label_ref"
1236 [(set (match_dup 3) (high:SI
1237 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1238 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1239 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1240 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1241 (set (match_operand:SI 0 "register_operand" "=r")
1242 (minus:SI (match_dup 5) (match_dup 4)))]
1245 crtl->uses_pic_offset_table = 1;
1246 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1247 if (!can_create_pseudo_p ())
1249 operands[3] = operands[0];
1250 operands[4] = operands[0];
1254 operands[3] = gen_reg_rtx (SImode);
1255 operands[4] = gen_reg_rtx (SImode);
1257 operands[5] = pic_offset_table_rtx;
1260 (define_insn "*movsi_high_pic_label_ref"
1261 [(set (match_operand:SI 0 "register_operand" "=r")
1263 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1264 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1266 "sethi\t%%hi(%a2-(%a1-.)), %0")
1268 (define_insn "*movsi_lo_sum_pic_label_ref"
1269 [(set (match_operand:SI 0 "register_operand" "=r")
1270 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1271 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1272 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1274 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1276 ;; Set up the PIC register for VxWorks.
1278 (define_expand "vxworks_load_got"
1280 (high:SI (match_dup 1)))
1282 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1284 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1285 "TARGET_VXWORKS_RTP"
1287 operands[0] = pic_offset_table_rtx;
1288 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1289 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1292 (define_expand "movdi"
1293 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1294 (match_operand:DI 1 "general_operand" ""))]
1297 if (sparc_expand_move (DImode, operands))
1301 ;; Be careful, fmovd does not exist when !v9.
1302 ;; We match MEM moves directly when we have correct even
1303 ;; numbered registers, but fall into splits otherwise.
1304 ;; The constraint ordering here is really important to
1305 ;; avoid insane problems in reload, especially for patterns
1308 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1309 ;; (const_int -5016)))
1313 (define_insn "*movdi_insn_sp32"
1314 [(set (match_operand:DI 0 "nonimmediate_operand"
1315 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1316 (match_operand:DI 1 "input_operand"
1317 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1319 && (register_operand (operands[0], DImode)
1320 || register_or_zero_operand (operands[1], DImode))"
1334 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1335 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1337 (define_insn "*movdi_insn_sp32_v9"
1338 [(set (match_operand:DI 0 "nonimmediate_operand"
1339 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1340 (match_operand:DI 1 "input_operand"
1341 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1344 && (register_operand (operands[0], DImode)
1345 || register_or_zero_operand (operands[1], DImode))"
1362 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1363 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1364 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1366 (define_insn "*movdi_insn_sp64"
1367 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1368 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1370 && (register_operand (operands[0], DImode)
1371 || register_or_zero_operand (operands[1], DImode))"
1374 sethi\t%%hi(%a1), %0
1381 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1382 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1384 (define_expand "movdi_pic_label_ref"
1385 [(set (match_dup 3) (high:DI
1386 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1387 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1388 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1389 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1390 (set (match_operand:DI 0 "register_operand" "=r")
1391 (minus:DI (match_dup 5) (match_dup 4)))]
1392 "TARGET_ARCH64 && flag_pic"
1394 crtl->uses_pic_offset_table = 1;
1395 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1396 if (!can_create_pseudo_p ())
1398 operands[3] = operands[0];
1399 operands[4] = operands[0];
1403 operands[3] = gen_reg_rtx (DImode);
1404 operands[4] = gen_reg_rtx (DImode);
1406 operands[5] = pic_offset_table_rtx;
1409 (define_insn "*movdi_high_pic_label_ref"
1410 [(set (match_operand:DI 0 "register_operand" "=r")
1412 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1413 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1414 "TARGET_ARCH64 && flag_pic"
1415 "sethi\t%%hi(%a2-(%a1-.)), %0")
1417 (define_insn "*movdi_lo_sum_pic_label_ref"
1418 [(set (match_operand:DI 0 "register_operand" "=r")
1419 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1420 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1421 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1422 "TARGET_ARCH64 && flag_pic"
1423 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1425 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1426 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1428 (define_insn "movdi_lo_sum_pic"
1429 [(set (match_operand:DI 0 "register_operand" "=r")
1430 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1431 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1432 "TARGET_ARCH64 && flag_pic"
1433 "or\t%1, %%lo(%a2), %0")
1435 (define_insn "movdi_high_pic"
1436 [(set (match_operand:DI 0 "register_operand" "=r")
1437 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1438 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1439 "sethi\t%%hi(%a1), %0")
1441 (define_insn "*sethi_di_medlow_embmedany_pic"
1442 [(set (match_operand:DI 0 "register_operand" "=r")
1443 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1444 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1445 "sethi\t%%hi(%a1), %0")
1447 (define_insn "*sethi_di_medlow"
1448 [(set (match_operand:DI 0 "register_operand" "=r")
1449 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1450 "TARGET_CM_MEDLOW && check_pic (1)"
1451 "sethi\t%%hi(%a1), %0")
1453 (define_insn "*losum_di_medlow"
1454 [(set (match_operand:DI 0 "register_operand" "=r")
1455 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1456 (match_operand:DI 2 "symbolic_operand" "")))]
1458 "or\t%1, %%lo(%a2), %0")
1460 (define_insn "seth44"
1461 [(set (match_operand:DI 0 "register_operand" "=r")
1462 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1464 "sethi\t%%h44(%a1), %0")
1466 (define_insn "setm44"
1467 [(set (match_operand:DI 0 "register_operand" "=r")
1468 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1469 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1471 "or\t%1, %%m44(%a2), %0")
1473 (define_insn "setl44"
1474 [(set (match_operand:DI 0 "register_operand" "=r")
1475 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1476 (match_operand:DI 2 "symbolic_operand" "")))]
1478 "or\t%1, %%l44(%a2), %0")
1480 (define_insn "sethh"
1481 [(set (match_operand:DI 0 "register_operand" "=r")
1482 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1484 "sethi\t%%hh(%a1), %0")
1486 (define_insn "setlm"
1487 [(set (match_operand:DI 0 "register_operand" "=r")
1488 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1490 "sethi\t%%lm(%a1), %0")
1492 (define_insn "sethm"
1493 [(set (match_operand:DI 0 "register_operand" "=r")
1494 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1495 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1497 "or\t%1, %%hm(%a2), %0")
1499 (define_insn "setlo"
1500 [(set (match_operand:DI 0 "register_operand" "=r")
1501 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1502 (match_operand:DI 2 "symbolic_operand" "")))]
1504 "or\t%1, %%lo(%a2), %0")
1506 (define_insn "embmedany_sethi"
1507 [(set (match_operand:DI 0 "register_operand" "=r")
1508 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1509 "TARGET_CM_EMBMEDANY && check_pic (1)"
1510 "sethi\t%%hi(%a1), %0")
1512 (define_insn "embmedany_losum"
1513 [(set (match_operand:DI 0 "register_operand" "=r")
1514 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1515 (match_operand:DI 2 "data_segment_operand" "")))]
1516 "TARGET_CM_EMBMEDANY"
1517 "add\t%1, %%lo(%a2), %0")
1519 (define_insn "embmedany_brsum"
1520 [(set (match_operand:DI 0 "register_operand" "=r")
1521 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1522 "TARGET_CM_EMBMEDANY"
1525 (define_insn "embmedany_textuhi"
1526 [(set (match_operand:DI 0 "register_operand" "=r")
1527 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1528 "TARGET_CM_EMBMEDANY && check_pic (1)"
1529 "sethi\t%%uhi(%a1), %0")
1531 (define_insn "embmedany_texthi"
1532 [(set (match_operand:DI 0 "register_operand" "=r")
1533 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1534 "TARGET_CM_EMBMEDANY && check_pic (1)"
1535 "sethi\t%%hi(%a1), %0")
1537 (define_insn "embmedany_textulo"
1538 [(set (match_operand:DI 0 "register_operand" "=r")
1539 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1540 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1541 "TARGET_CM_EMBMEDANY"
1542 "or\t%1, %%ulo(%a2), %0")
1544 (define_insn "embmedany_textlo"
1545 [(set (match_operand:DI 0 "register_operand" "=r")
1546 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1547 (match_operand:DI 2 "text_segment_operand" "")))]
1548 "TARGET_CM_EMBMEDANY"
1549 "or\t%1, %%lo(%a2), %0")
1551 ;; Now some patterns to help reload out a bit.
1552 (define_expand "reload_indi"
1553 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1554 (match_operand:DI 1 "immediate_operand" "")
1555 (match_operand:TI 2 "register_operand" "=&r")])]
1557 || TARGET_CM_EMBMEDANY)
1560 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1564 (define_expand "reload_outdi"
1565 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1566 (match_operand:DI 1 "immediate_operand" "")
1567 (match_operand:TI 2 "register_operand" "=&r")])]
1569 || TARGET_CM_EMBMEDANY)
1572 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1576 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1578 [(set (match_operand:DI 0 "register_operand" "")
1579 (match_operand:DI 1 "const_int_operand" ""))]
1580 "! TARGET_ARCH64 && reload_completed"
1581 [(clobber (const_int 0))]
1583 #if HOST_BITS_PER_WIDE_INT == 32
1584 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1585 (INTVAL (operands[1]) < 0) ?
1588 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1591 unsigned int low, high;
1593 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1594 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1595 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1597 /* Slick... but this trick loses if this subreg constant part
1598 can be done in one insn. */
1600 && ! SPARC_SETHI32_P (high)
1601 && ! SPARC_SIMM13_P (high))
1602 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1603 gen_highpart (SImode, operands[0])));
1605 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1611 [(set (match_operand:DI 0 "register_operand" "")
1612 (match_operand:DI 1 "const_double_operand" ""))]
1616 && ((GET_CODE (operands[0]) == REG
1617 && REGNO (operands[0]) < 32)
1618 || (GET_CODE (operands[0]) == SUBREG
1619 && GET_CODE (SUBREG_REG (operands[0])) == REG
1620 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1621 [(clobber (const_int 0))]
1623 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1624 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1626 /* Slick... but this trick loses if this subreg constant part
1627 can be done in one insn. */
1628 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1629 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1630 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1632 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1633 gen_highpart (SImode, operands[0])));
1637 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1638 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1644 [(set (match_operand:DI 0 "register_operand" "")
1645 (match_operand:DI 1 "register_operand" ""))]
1649 && ((GET_CODE (operands[0]) == REG
1650 && REGNO (operands[0]) < 32)
1651 || (GET_CODE (operands[0]) == SUBREG
1652 && GET_CODE (SUBREG_REG (operands[0])) == REG
1653 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1654 [(clobber (const_int 0))]
1656 rtx set_dest = operands[0];
1657 rtx set_src = operands[1];
1661 dest1 = gen_highpart (SImode, set_dest);
1662 dest2 = gen_lowpart (SImode, set_dest);
1663 src1 = gen_highpart (SImode, set_src);
1664 src2 = gen_lowpart (SImode, set_src);
1666 /* Now emit using the real source and destination we found, swapping
1667 the order if we detect overlap. */
1668 if (reg_overlap_mentioned_p (dest1, src2))
1670 emit_insn (gen_movsi (dest2, src2));
1671 emit_insn (gen_movsi (dest1, src1));
1675 emit_insn (gen_movsi (dest1, src1));
1676 emit_insn (gen_movsi (dest2, src2));
1681 ;; Now handle the cases of memory moves from/to non-even
1682 ;; DI mode register pairs.
1684 [(set (match_operand:DI 0 "register_operand" "")
1685 (match_operand:DI 1 "memory_operand" ""))]
1688 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1689 [(clobber (const_int 0))]
1691 rtx word0 = adjust_address (operands[1], SImode, 0);
1692 rtx word1 = adjust_address (operands[1], SImode, 4);
1693 rtx high_part = gen_highpart (SImode, operands[0]);
1694 rtx low_part = gen_lowpart (SImode, operands[0]);
1696 if (reg_overlap_mentioned_p (high_part, word1))
1698 emit_insn (gen_movsi (low_part, word1));
1699 emit_insn (gen_movsi (high_part, word0));
1703 emit_insn (gen_movsi (high_part, word0));
1704 emit_insn (gen_movsi (low_part, word1));
1710 [(set (match_operand:DI 0 "memory_operand" "")
1711 (match_operand:DI 1 "register_operand" ""))]
1714 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1715 [(clobber (const_int 0))]
1717 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1718 gen_highpart (SImode, operands[1])));
1719 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1720 gen_lowpart (SImode, operands[1])));
1725 [(set (match_operand:DI 0 "memory_operand" "")
1726 (match_operand:DI 1 "const_zero_operand" ""))]
1730 && ! mem_min_alignment (operands[0], 8)))
1731 && offsettable_memref_p (operands[0])"
1732 [(clobber (const_int 0))]
1734 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1735 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1740 ;; Floating point and vector move instructions
1742 ;; Yes, you guessed it right, the former movsf expander.
1743 (define_expand "mov<V32:mode>"
1744 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1745 (match_operand:V32 1 "general_operand" ""))]
1746 "<V32:MODE>mode == SFmode || TARGET_VIS"
1748 if (sparc_expand_move (<V32:MODE>mode, operands))
1752 (define_insn "*movsf_insn"
1753 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1754 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1756 && (register_operand (operands[0], <V32:MODE>mode)
1757 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1759 if (GET_CODE (operands[1]) == CONST_DOUBLE
1760 && (which_alternative == 2
1761 || which_alternative == 3
1762 || which_alternative == 4))
1767 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1768 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1769 operands[1] = GEN_INT (i);
1772 switch (which_alternative)
1775 return "fzeros\t%0";
1777 return "fmovs\t%1, %0";
1779 return "mov\t%1, %0";
1781 return "sethi\t%%hi(%a1), %0";
1786 return "ld\t%1, %0";
1789 return "st\t%r1, %0";
1794 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1796 ;; Exactly the same as above, except that all `f' cases are deleted.
1797 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1800 (define_insn "*movsf_insn_no_fpu"
1801 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1802 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1804 && (register_operand (operands[0], SFmode)
1805 || register_or_zero_operand (operands[1], SFmode))"
1807 if (GET_CODE (operands[1]) == CONST_DOUBLE
1808 && (which_alternative == 0
1809 || which_alternative == 1
1810 || which_alternative == 2))
1815 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1816 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1817 operands[1] = GEN_INT (i);
1820 switch (which_alternative)
1823 return "mov\t%1, %0";
1825 return "sethi\t%%hi(%a1), %0";
1829 return "ld\t%1, %0";
1831 return "st\t%r1, %0";
1836 [(set_attr "type" "*,*,*,load,store")])
1838 ;; The following 3 patterns build SFmode constants in integer registers.
1840 (define_insn "*movsf_lo_sum"
1841 [(set (match_operand:SF 0 "register_operand" "=r")
1842 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1843 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1849 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1850 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1851 operands[2] = GEN_INT (i);
1852 return "or\t%1, %%lo(%a2), %0";
1855 (define_insn "*movsf_high"
1856 [(set (match_operand:SF 0 "register_operand" "=r")
1857 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1863 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1864 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1865 operands[1] = GEN_INT (i);
1866 return "sethi\t%%hi(%1), %0";
1870 [(set (match_operand:SF 0 "register_operand" "")
1871 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1872 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1873 [(set (match_dup 0) (high:SF (match_dup 1)))
1874 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1876 ;; Yes, you again guessed it right, the former movdf expander.
1877 (define_expand "mov<V64:mode>"
1878 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1879 (match_operand:V64 1 "general_operand" ""))]
1880 "<V64:MODE>mode == DFmode || TARGET_VIS"
1882 if (sparc_expand_move (<V64:MODE>mode, operands))
1886 ;; Be careful, fmovd does not exist when !v9.
1887 (define_insn "*movdf_insn_sp32"
1888 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1889 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1892 && (register_operand (operands[0], DFmode)
1893 || register_or_zero_operand (operands[1], DFmode))"
1905 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1906 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1908 (define_insn "*movdf_insn_sp32_no_fpu"
1909 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1910 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1913 && (register_operand (operands[0], DFmode)
1914 || register_or_zero_operand (operands[1], DFmode))"
1921 [(set_attr "type" "load,store,*,*,*")
1922 (set_attr "length" "*,*,2,2,2")])
1924 ;; We have available v9 double floats but not 64-bit integer registers.
1925 (define_insn "*movdf_insn_sp32_v9"
1926 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1927 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1931 && (register_operand (operands[0], <V64:MODE>mode)
1932 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1944 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
1945 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
1946 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
1948 (define_insn "*movdf_insn_sp32_v9_no_fpu"
1949 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
1950 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
1954 && (register_operand (operands[0], DFmode)
1955 || register_or_zero_operand (operands[1], DFmode))"
1962 [(set_attr "type" "load,store,store,*,*")
1963 (set_attr "length" "*,*,*,2,2")])
1965 ;; We have available both v9 double floats and 64-bit integer registers.
1966 (define_insn "*movdf_insn_sp64"
1967 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
1968 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
1971 && (register_operand (operands[0], <V64:MODE>mode)
1972 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1982 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
1983 (set_attr "length" "*,*,*,*,*,*,*,2")
1984 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
1986 (define_insn "*movdf_insn_sp64_no_fpu"
1987 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
1988 (match_operand:DF 1 "input_operand" "r,m,rG"))]
1991 && (register_operand (operands[0], DFmode)
1992 || register_or_zero_operand (operands[1], DFmode))"
1997 [(set_attr "type" "*,load,store")])
1999 ;; This pattern builds V64mode constants in integer registers.
2001 [(set (match_operand:V64 0 "register_operand" "")
2002 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2004 && (GET_CODE (operands[0]) == REG
2005 && REGNO (operands[0]) < 32)
2006 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2007 && reload_completed"
2008 [(clobber (const_int 0))]
2010 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2014 #if HOST_BITS_PER_WIDE_INT == 32
2017 enum machine_mode mode = GET_MODE (operands[1]);
2018 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2019 emit_insn (gen_movdi (operands[0], tem));
2024 enum machine_mode mode = GET_MODE (operands[1]);
2025 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2026 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2028 gcc_assert (GET_CODE (hi) == CONST_INT);
2029 gcc_assert (GET_CODE (lo) == CONST_INT);
2031 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2033 /* Slick... but this trick loses if this subreg constant part
2034 can be done in one insn. */
2036 && ! SPARC_SETHI32_P (INTVAL (hi))
2037 && ! SPARC_SIMM13_P (INTVAL (hi)))
2039 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2040 gen_highpart (SImode, operands[0])));
2044 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2050 ;; Ok, now the splits to handle all the multi insn and
2051 ;; mis-aligned memory address cases.
2052 ;; In these splits please take note that we must be
2053 ;; careful when V9 but not ARCH64 because the integer
2054 ;; register DFmode cases must be handled.
2056 [(set (match_operand:V64 0 "register_operand" "")
2057 (match_operand:V64 1 "register_operand" ""))]
2060 && ((GET_CODE (operands[0]) == REG
2061 && REGNO (operands[0]) < 32)
2062 || (GET_CODE (operands[0]) == SUBREG
2063 && GET_CODE (SUBREG_REG (operands[0])) == REG
2064 && REGNO (SUBREG_REG (operands[0])) < 32))))
2065 && reload_completed"
2066 [(clobber (const_int 0))]
2068 rtx set_dest = operands[0];
2069 rtx set_src = operands[1];
2072 enum machine_mode half_mode;
2074 /* We can be expanded for DFmode or integral vector modes. */
2075 if (<V64:MODE>mode == DFmode)
2080 dest1 = gen_highpart (half_mode, set_dest);
2081 dest2 = gen_lowpart (half_mode, set_dest);
2082 src1 = gen_highpart (half_mode, set_src);
2083 src2 = gen_lowpart (half_mode, set_src);
2085 /* Now emit using the real source and destination we found, swapping
2086 the order if we detect overlap. */
2087 if (reg_overlap_mentioned_p (dest1, src2))
2089 emit_move_insn_1 (dest2, src2);
2090 emit_move_insn_1 (dest1, src1);
2094 emit_move_insn_1 (dest1, src1);
2095 emit_move_insn_1 (dest2, src2);
2101 [(set (match_operand:V64 0 "register_operand" "")
2102 (match_operand:V64 1 "memory_operand" ""))]
2105 && (((REGNO (operands[0]) % 2) != 0)
2106 || ! mem_min_alignment (operands[1], 8))
2107 && offsettable_memref_p (operands[1])"
2108 [(clobber (const_int 0))]
2110 enum machine_mode half_mode;
2113 /* We can be expanded for DFmode or integral vector modes. */
2114 if (<V64:MODE>mode == DFmode)
2119 word0 = adjust_address (operands[1], half_mode, 0);
2120 word1 = adjust_address (operands[1], half_mode, 4);
2122 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2124 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2125 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2129 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2130 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2136 [(set (match_operand:V64 0 "memory_operand" "")
2137 (match_operand:V64 1 "register_operand" ""))]
2140 && (((REGNO (operands[1]) % 2) != 0)
2141 || ! mem_min_alignment (operands[0], 8))
2142 && offsettable_memref_p (operands[0])"
2143 [(clobber (const_int 0))]
2145 enum machine_mode half_mode;
2148 /* We can be expanded for DFmode or integral vector modes. */
2149 if (<V64:MODE>mode == DFmode)
2154 word0 = adjust_address (operands[0], half_mode, 0);
2155 word1 = adjust_address (operands[0], half_mode, 4);
2157 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2158 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2163 [(set (match_operand:V64 0 "memory_operand" "")
2164 (match_operand:V64 1 "const_zero_operand" ""))]
2168 && ! mem_min_alignment (operands[0], 8)))
2169 && offsettable_memref_p (operands[0])"
2170 [(clobber (const_int 0))]
2172 enum machine_mode half_mode;
2175 /* We can be expanded for DFmode or integral vector modes. */
2176 if (<V64:MODE>mode == DFmode)
2181 dest1 = adjust_address (operands[0], half_mode, 0);
2182 dest2 = adjust_address (operands[0], half_mode, 4);
2184 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2185 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2190 [(set (match_operand:V64 0 "register_operand" "")
2191 (match_operand:V64 1 "const_zero_operand" ""))]
2194 && ((GET_CODE (operands[0]) == REG
2195 && REGNO (operands[0]) < 32)
2196 || (GET_CODE (operands[0]) == SUBREG
2197 && GET_CODE (SUBREG_REG (operands[0])) == REG
2198 && REGNO (SUBREG_REG (operands[0])) < 32))"
2199 [(clobber (const_int 0))]
2201 enum machine_mode half_mode;
2202 rtx set_dest = operands[0];
2205 /* We can be expanded for DFmode or integral vector modes. */
2206 if (<V64:MODE>mode == DFmode)
2211 dest1 = gen_highpart (half_mode, set_dest);
2212 dest2 = gen_lowpart (half_mode, set_dest);
2213 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2214 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2218 (define_expand "movtf"
2219 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2220 (match_operand:TF 1 "general_operand" ""))]
2223 if (sparc_expand_move (TFmode, operands))
2227 (define_insn "*movtf_insn_sp32"
2228 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2229 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2232 && (register_operand (operands[0], TFmode)
2233 || register_or_zero_operand (operands[1], TFmode))"
2235 [(set_attr "length" "4")])
2237 ;; Exactly the same as above, except that all `e' cases are deleted.
2238 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2241 (define_insn "*movtf_insn_sp32_no_fpu"
2242 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2243 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2246 && (register_operand (operands[0], TFmode)
2247 || register_or_zero_operand (operands[1], TFmode))"
2249 [(set_attr "length" "4")])
2251 (define_insn "*movtf_insn_sp64"
2252 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2253 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2256 && ! TARGET_HARD_QUAD
2257 && (register_operand (operands[0], TFmode)
2258 || register_or_zero_operand (operands[1], TFmode))"
2260 [(set_attr "length" "2")])
2262 (define_insn "*movtf_insn_sp64_hq"
2263 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2264 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2268 && (register_operand (operands[0], TFmode)
2269 || register_or_zero_operand (operands[1], TFmode))"
2277 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2278 (set_attr "length" "2,*,*,*,2,2")])
2280 (define_insn "*movtf_insn_sp64_no_fpu"
2281 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2282 (match_operand:TF 1 "input_operand" "orG,rG"))]
2285 && (register_operand (operands[0], TFmode)
2286 || register_or_zero_operand (operands[1], TFmode))"
2288 [(set_attr "length" "2")])
2290 ;; Now all the splits to handle multi-insn TF mode moves.
2292 [(set (match_operand:TF 0 "register_operand" "")
2293 (match_operand:TF 1 "register_operand" ""))]
2297 && ! TARGET_HARD_QUAD)
2298 || ! fp_register_operand (operands[0], TFmode))"
2299 [(clobber (const_int 0))]
2301 rtx set_dest = operands[0];
2302 rtx set_src = operands[1];
2306 dest1 = gen_df_reg (set_dest, 0);
2307 dest2 = gen_df_reg (set_dest, 1);
2308 src1 = gen_df_reg (set_src, 0);
2309 src2 = gen_df_reg (set_src, 1);
2311 /* Now emit using the real source and destination we found, swapping
2312 the order if we detect overlap. */
2313 if (reg_overlap_mentioned_p (dest1, src2))
2315 emit_insn (gen_movdf (dest2, src2));
2316 emit_insn (gen_movdf (dest1, src1));
2320 emit_insn (gen_movdf (dest1, src1));
2321 emit_insn (gen_movdf (dest2, src2));
2327 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2328 (match_operand:TF 1 "const_zero_operand" ""))]
2330 [(clobber (const_int 0))]
2332 rtx set_dest = operands[0];
2335 switch (GET_CODE (set_dest))
2338 dest1 = gen_df_reg (set_dest, 0);
2339 dest2 = gen_df_reg (set_dest, 1);
2342 dest1 = adjust_address (set_dest, DFmode, 0);
2343 dest2 = adjust_address (set_dest, DFmode, 8);
2349 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2350 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2355 [(set (match_operand:TF 0 "register_operand" "")
2356 (match_operand:TF 1 "memory_operand" ""))]
2358 && offsettable_memref_p (operands[1])
2360 || ! TARGET_HARD_QUAD
2361 || ! fp_register_operand (operands[0], TFmode)))"
2362 [(clobber (const_int 0))]
2364 rtx word0 = adjust_address (operands[1], DFmode, 0);
2365 rtx word1 = adjust_address (operands[1], DFmode, 8);
2366 rtx set_dest, dest1, dest2;
2368 set_dest = operands[0];
2370 dest1 = gen_df_reg (set_dest, 0);
2371 dest2 = gen_df_reg (set_dest, 1);
2373 /* Now output, ordering such that we don't clobber any registers
2374 mentioned in the address. */
2375 if (reg_overlap_mentioned_p (dest1, word1))
2378 emit_insn (gen_movdf (dest2, word1));
2379 emit_insn (gen_movdf (dest1, word0));
2383 emit_insn (gen_movdf (dest1, word0));
2384 emit_insn (gen_movdf (dest2, word1));
2390 [(set (match_operand:TF 0 "memory_operand" "")
2391 (match_operand:TF 1 "register_operand" ""))]
2393 && offsettable_memref_p (operands[0])
2395 || ! TARGET_HARD_QUAD
2396 || ! fp_register_operand (operands[1], TFmode)))"
2397 [(clobber (const_int 0))]
2399 rtx set_src = operands[1];
2401 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2402 gen_df_reg (set_src, 0)));
2403 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2404 gen_df_reg (set_src, 1)));
2409 ;; SPARC-V9 conditional move instructions
2411 ;; We can handle larger constants here for some flavors, but for now we keep
2412 ;; it simple and only allow those constants supported by all flavors.
2413 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2414 ;; 3 contains the constant if one is present, but we handle either for
2415 ;; generality (sparc.c puts a constant in operand 2).
2417 (define_expand "mov<I:mode>cc"
2418 [(set (match_operand:I 0 "register_operand" "")
2419 (if_then_else:I (match_operand 1 "comparison_operator" "")
2420 (match_operand:I 2 "arith10_operand" "")
2421 (match_operand:I 3 "arith10_operand" "")))]
2422 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2424 enum rtx_code code = GET_CODE (operands[1]);
2427 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2431 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2433 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2434 GET_CODE (operands[1]));
2436 if (XEXP (operands[1], 1) == const0_rtx
2437 && GET_CODE (XEXP (operands[1], 0)) == REG
2438 && GET_MODE (XEXP (operands[1], 0)) == DImode
2439 && v9_regcmp_p (code))
2440 cc_reg = XEXP (operands[1], 0);
2442 cc_reg = gen_compare_reg (operands[1]);
2444 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2447 (define_expand "mov<F:mode>cc"
2448 [(set (match_operand:F 0 "register_operand" "")
2449 (if_then_else:F (match_operand 1 "comparison_operator" "")
2450 (match_operand:F 2 "register_operand" "")
2451 (match_operand:F 3 "register_operand" "")))]
2452 "TARGET_V9 && TARGET_FPU"
2454 enum rtx_code code = GET_CODE (operands[1]);
2457 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2461 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2463 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2464 GET_CODE (operands[1]));
2466 if (XEXP (operands[1], 1) == const0_rtx
2467 && GET_CODE (XEXP (operands[1], 0)) == REG
2468 && GET_MODE (XEXP (operands[1], 0)) == DImode
2469 && v9_regcmp_p (code))
2470 cc_reg = XEXP (operands[1], 0);
2472 cc_reg = gen_compare_reg (operands[1]);
2474 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2477 ;; Conditional move define_insns
2479 (define_insn "*mov<I:mode>_cc_v9"
2480 [(set (match_operand:I 0 "register_operand" "=r,r")
2481 (if_then_else:I (match_operator 1 "comparison_operator"
2482 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2484 (match_operand:I 3 "arith11_operand" "rL,0")
2485 (match_operand:I 4 "arith11_operand" "0,rL")))]
2486 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2489 mov%c1\t%x2, %4, %0"
2490 [(set_attr "type" "cmove")])
2492 (define_insn "*mov<I:mode>_cc_reg_sp64"
2493 [(set (match_operand:I 0 "register_operand" "=r,r")
2494 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2495 [(match_operand:DI 2 "register_operand" "r,r")
2497 (match_operand:I 3 "arith10_operand" "rM,0")
2498 (match_operand:I 4 "arith10_operand" "0,rM")))]
2501 movr%D1\t%2, %r3, %0
2502 movr%d1\t%2, %r4, %0"
2503 [(set_attr "type" "cmove")])
2505 (define_insn "*movsf_cc_v9"
2506 [(set (match_operand:SF 0 "register_operand" "=f,f")
2507 (if_then_else:SF (match_operator 1 "comparison_operator"
2508 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2510 (match_operand:SF 3 "register_operand" "f,0")
2511 (match_operand:SF 4 "register_operand" "0,f")))]
2512 "TARGET_V9 && TARGET_FPU"
2514 fmovs%C1\t%x2, %3, %0
2515 fmovs%c1\t%x2, %4, %0"
2516 [(set_attr "type" "fpcmove")])
2518 (define_insn "*movsf_cc_reg_sp64"
2519 [(set (match_operand:SF 0 "register_operand" "=f,f")
2520 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2521 [(match_operand:DI 2 "register_operand" "r,r")
2523 (match_operand:SF 3 "register_operand" "f,0")
2524 (match_operand:SF 4 "register_operand" "0,f")))]
2525 "TARGET_ARCH64 && TARGET_FPU"
2527 fmovrs%D1\t%2, %3, %0
2528 fmovrs%d1\t%2, %4, %0"
2529 [(set_attr "type" "fpcrmove")])
2531 ;; Named because invoked by movtf_cc_v9
2532 (define_insn "movdf_cc_v9"
2533 [(set (match_operand:DF 0 "register_operand" "=e,e")
2534 (if_then_else:DF (match_operator 1 "comparison_operator"
2535 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2537 (match_operand:DF 3 "register_operand" "e,0")
2538 (match_operand:DF 4 "register_operand" "0,e")))]
2539 "TARGET_V9 && TARGET_FPU"
2541 fmovd%C1\t%x2, %3, %0
2542 fmovd%c1\t%x2, %4, %0"
2543 [(set_attr "type" "fpcmove")
2544 (set_attr "fptype" "double")])
2546 ;; Named because invoked by movtf_cc_reg_sp64
2547 (define_insn "movdf_cc_reg_sp64"
2548 [(set (match_operand:DF 0 "register_operand" "=e,e")
2549 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2550 [(match_operand:DI 2 "register_operand" "r,r")
2552 (match_operand:DF 3 "register_operand" "e,0")
2553 (match_operand:DF 4 "register_operand" "0,e")))]
2554 "TARGET_ARCH64 && TARGET_FPU"
2556 fmovrd%D1\t%2, %3, %0
2557 fmovrd%d1\t%2, %4, %0"
2558 [(set_attr "type" "fpcrmove")
2559 (set_attr "fptype" "double")])
2561 (define_insn "*movtf_cc_hq_v9"
2562 [(set (match_operand:TF 0 "register_operand" "=e,e")
2563 (if_then_else:TF (match_operator 1 "comparison_operator"
2564 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2566 (match_operand:TF 3 "register_operand" "e,0")
2567 (match_operand:TF 4 "register_operand" "0,e")))]
2568 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2570 fmovq%C1\t%x2, %3, %0
2571 fmovq%c1\t%x2, %4, %0"
2572 [(set_attr "type" "fpcmove")])
2574 (define_insn "*movtf_cc_reg_hq_sp64"
2575 [(set (match_operand:TF 0 "register_operand" "=e,e")
2576 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2577 [(match_operand:DI 2 "register_operand" "r,r")
2579 (match_operand:TF 3 "register_operand" "e,0")
2580 (match_operand:TF 4 "register_operand" "0,e")))]
2581 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2583 fmovrq%D1\t%2, %3, %0
2584 fmovrq%d1\t%2, %4, %0"
2585 [(set_attr "type" "fpcrmove")])
2587 (define_insn_and_split "*movtf_cc_v9"
2588 [(set (match_operand:TF 0 "register_operand" "=e,e")
2589 (if_then_else:TF (match_operator 1 "comparison_operator"
2590 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2592 (match_operand:TF 3 "register_operand" "e,0")
2593 (match_operand:TF 4 "register_operand" "0,e")))]
2594 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2596 "&& reload_completed"
2597 [(clobber (const_int 0))]
2599 rtx set_dest = operands[0];
2600 rtx set_srca = operands[3];
2601 rtx set_srcb = operands[4];
2602 int third = rtx_equal_p (set_dest, set_srca);
2604 rtx srca1, srca2, srcb1, srcb2;
2606 dest1 = gen_df_reg (set_dest, 0);
2607 dest2 = gen_df_reg (set_dest, 1);
2608 srca1 = gen_df_reg (set_srca, 0);
2609 srca2 = gen_df_reg (set_srca, 1);
2610 srcb1 = gen_df_reg (set_srcb, 0);
2611 srcb2 = gen_df_reg (set_srcb, 1);
2613 /* Now emit using the real source and destination we found, swapping
2614 the order if we detect overlap. */
2615 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2616 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2618 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2619 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2623 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2624 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2628 [(set_attr "length" "2")])
2630 (define_insn_and_split "*movtf_cc_reg_sp64"
2631 [(set (match_operand:TF 0 "register_operand" "=e,e")
2632 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2633 [(match_operand:DI 2 "register_operand" "r,r")
2635 (match_operand:TF 3 "register_operand" "e,0")
2636 (match_operand:TF 4 "register_operand" "0,e")))]
2637 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2639 "&& reload_completed"
2640 [(clobber (const_int 0))]
2642 rtx set_dest = operands[0];
2643 rtx set_srca = operands[3];
2644 rtx set_srcb = operands[4];
2645 int third = rtx_equal_p (set_dest, set_srca);
2647 rtx srca1, srca2, srcb1, srcb2;
2649 dest1 = gen_df_reg (set_dest, 0);
2650 dest2 = gen_df_reg (set_dest, 1);
2651 srca1 = gen_df_reg (set_srca, 0);
2652 srca2 = gen_df_reg (set_srca, 1);
2653 srcb1 = gen_df_reg (set_srcb, 0);
2654 srcb2 = gen_df_reg (set_srcb, 1);
2656 /* Now emit using the real source and destination we found, swapping
2657 the order if we detect overlap. */
2658 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2659 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2661 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2662 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2666 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2667 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2671 [(set_attr "length" "2")])
2674 ;; Zero-extension instructions
2676 ;; These patterns originally accepted general_operands, however, slightly
2677 ;; better code is generated by only accepting register_operands, and then
2678 ;; letting combine generate the ldu[hb] insns.
2680 (define_expand "zero_extendhisi2"
2681 [(set (match_operand:SI 0 "register_operand" "")
2682 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2685 rtx temp = gen_reg_rtx (SImode);
2686 rtx shift_16 = GEN_INT (16);
2687 int op1_subbyte = 0;
2689 if (GET_CODE (operand1) == SUBREG)
2691 op1_subbyte = SUBREG_BYTE (operand1);
2692 op1_subbyte /= GET_MODE_SIZE (SImode);
2693 op1_subbyte *= GET_MODE_SIZE (SImode);
2694 operand1 = XEXP (operand1, 0);
2697 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2699 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2703 (define_insn "*zero_extendhisi2_insn"
2704 [(set (match_operand:SI 0 "register_operand" "=r")
2705 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2708 [(set_attr "type" "load")
2709 (set_attr "us3load_type" "3cycle")])
2711 (define_expand "zero_extendqihi2"
2712 [(set (match_operand:HI 0 "register_operand" "")
2713 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2717 (define_insn "*zero_extendqihi2_insn"
2718 [(set (match_operand:HI 0 "register_operand" "=r,r")
2719 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2720 "GET_CODE (operands[1]) != CONST_INT"
2724 [(set_attr "type" "*,load")
2725 (set_attr "us3load_type" "*,3cycle")])
2727 (define_expand "zero_extendqisi2"
2728 [(set (match_operand:SI 0 "register_operand" "")
2729 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2733 (define_insn "*zero_extendqisi2_insn"
2734 [(set (match_operand:SI 0 "register_operand" "=r,r")
2735 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2736 "GET_CODE (operands[1]) != CONST_INT"
2740 [(set_attr "type" "*,load")
2741 (set_attr "us3load_type" "*,3cycle")])
2743 (define_expand "zero_extendqidi2"
2744 [(set (match_operand:DI 0 "register_operand" "")
2745 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2749 (define_insn "*zero_extendqidi2_insn"
2750 [(set (match_operand:DI 0 "register_operand" "=r,r")
2751 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2752 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2756 [(set_attr "type" "*,load")
2757 (set_attr "us3load_type" "*,3cycle")])
2759 (define_expand "zero_extendhidi2"
2760 [(set (match_operand:DI 0 "register_operand" "")
2761 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2764 rtx temp = gen_reg_rtx (DImode);
2765 rtx shift_48 = GEN_INT (48);
2766 int op1_subbyte = 0;
2768 if (GET_CODE (operand1) == SUBREG)
2770 op1_subbyte = SUBREG_BYTE (operand1);
2771 op1_subbyte /= GET_MODE_SIZE (DImode);
2772 op1_subbyte *= GET_MODE_SIZE (DImode);
2773 operand1 = XEXP (operand1, 0);
2776 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2778 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2782 (define_insn "*zero_extendhidi2_insn"
2783 [(set (match_operand:DI 0 "register_operand" "=r")
2784 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2787 [(set_attr "type" "load")
2788 (set_attr "us3load_type" "3cycle")])
2790 ;; ??? Write truncdisi pattern using sra?
2792 (define_expand "zero_extendsidi2"
2793 [(set (match_operand:DI 0 "register_operand" "")
2794 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2798 (define_insn "*zero_extendsidi2_insn_sp64"
2799 [(set (match_operand:DI 0 "register_operand" "=r,r")
2800 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2801 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2805 [(set_attr "type" "shift,load")])
2807 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2808 [(set (match_operand:DI 0 "register_operand" "=r")
2809 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2812 "&& reload_completed"
2813 [(set (match_dup 2) (match_dup 3))
2814 (set (match_dup 4) (match_dup 5))]
2818 dest1 = gen_highpart (SImode, operands[0]);
2819 dest2 = gen_lowpart (SImode, operands[0]);
2821 /* Swap the order in case of overlap. */
2822 if (REGNO (dest1) == REGNO (operands[1]))
2824 operands[2] = dest2;
2825 operands[3] = operands[1];
2826 operands[4] = dest1;
2827 operands[5] = const0_rtx;
2831 operands[2] = dest1;
2832 operands[3] = const0_rtx;
2833 operands[4] = dest2;
2834 operands[5] = operands[1];
2837 [(set_attr "length" "2")])
2839 ;; Simplify comparisons of extended values.
2841 (define_insn "*cmp_zero_extendqisi2"
2843 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2846 "andcc\t%0, 0xff, %%g0"
2847 [(set_attr "type" "compare")])
2849 (define_insn "*cmp_zero_qi"
2851 (compare:CC (match_operand:QI 0 "register_operand" "r")
2854 "andcc\t%0, 0xff, %%g0"
2855 [(set_attr "type" "compare")])
2857 (define_insn "*cmp_zero_extendqisi2_set"
2859 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2861 (set (match_operand:SI 0 "register_operand" "=r")
2862 (zero_extend:SI (match_dup 1)))]
2864 "andcc\t%1, 0xff, %0"
2865 [(set_attr "type" "compare")])
2867 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2869 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2872 (set (match_operand:SI 0 "register_operand" "=r")
2873 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2875 "andcc\t%1, 0xff, %0"
2876 [(set_attr "type" "compare")])
2878 (define_insn "*cmp_zero_extendqidi2"
2880 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2883 "andcc\t%0, 0xff, %%g0"
2884 [(set_attr "type" "compare")])
2886 (define_insn "*cmp_zero_qi_sp64"
2888 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2891 "andcc\t%0, 0xff, %%g0"
2892 [(set_attr "type" "compare")])
2894 (define_insn "*cmp_zero_extendqidi2_set"
2896 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2898 (set (match_operand:DI 0 "register_operand" "=r")
2899 (zero_extend:DI (match_dup 1)))]
2901 "andcc\t%1, 0xff, %0"
2902 [(set_attr "type" "compare")])
2904 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2906 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2909 (set (match_operand:DI 0 "register_operand" "=r")
2910 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2912 "andcc\t%1, 0xff, %0"
2913 [(set_attr "type" "compare")])
2915 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2917 (define_insn "*cmp_siqi_trunc"
2919 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2922 "andcc\t%0, 0xff, %%g0"
2923 [(set_attr "type" "compare")])
2925 (define_insn "*cmp_siqi_trunc_set"
2927 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2929 (set (match_operand:QI 0 "register_operand" "=r")
2930 (subreg:QI (match_dup 1) 3))]
2932 "andcc\t%1, 0xff, %0"
2933 [(set_attr "type" "compare")])
2935 (define_insn "*cmp_diqi_trunc"
2937 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
2940 "andcc\t%0, 0xff, %%g0"
2941 [(set_attr "type" "compare")])
2943 (define_insn "*cmp_diqi_trunc_set"
2945 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
2947 (set (match_operand:QI 0 "register_operand" "=r")
2948 (subreg:QI (match_dup 1) 7))]
2950 "andcc\t%1, 0xff, %0"
2951 [(set_attr "type" "compare")])
2954 ;; Sign-extension instructions
2956 ;; These patterns originally accepted general_operands, however, slightly
2957 ;; better code is generated by only accepting register_operands, and then
2958 ;; letting combine generate the lds[hb] insns.
2960 (define_expand "extendhisi2"
2961 [(set (match_operand:SI 0 "register_operand" "")
2962 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2965 rtx temp = gen_reg_rtx (SImode);
2966 rtx shift_16 = GEN_INT (16);
2967 int op1_subbyte = 0;
2969 if (GET_CODE (operand1) == SUBREG)
2971 op1_subbyte = SUBREG_BYTE (operand1);
2972 op1_subbyte /= GET_MODE_SIZE (SImode);
2973 op1_subbyte *= GET_MODE_SIZE (SImode);
2974 operand1 = XEXP (operand1, 0);
2977 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2979 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2983 (define_insn "*sign_extendhisi2_insn"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2988 [(set_attr "type" "sload")
2989 (set_attr "us3load_type" "3cycle")])
2991 (define_expand "extendqihi2"
2992 [(set (match_operand:HI 0 "register_operand" "")
2993 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2996 rtx temp = gen_reg_rtx (SImode);
2997 rtx shift_24 = GEN_INT (24);
2998 int op1_subbyte = 0;
2999 int op0_subbyte = 0;
3001 if (GET_CODE (operand1) == SUBREG)
3003 op1_subbyte = SUBREG_BYTE (operand1);
3004 op1_subbyte /= GET_MODE_SIZE (SImode);
3005 op1_subbyte *= GET_MODE_SIZE (SImode);
3006 operand1 = XEXP (operand1, 0);
3008 if (GET_CODE (operand0) == SUBREG)
3010 op0_subbyte = SUBREG_BYTE (operand0);
3011 op0_subbyte /= GET_MODE_SIZE (SImode);
3012 op0_subbyte *= GET_MODE_SIZE (SImode);
3013 operand0 = XEXP (operand0, 0);
3015 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3017 if (GET_MODE (operand0) != SImode)
3018 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3019 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3023 (define_insn "*sign_extendqihi2_insn"
3024 [(set (match_operand:HI 0 "register_operand" "=r")
3025 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3028 [(set_attr "type" "sload")
3029 (set_attr "us3load_type" "3cycle")])
3031 (define_expand "extendqisi2"
3032 [(set (match_operand:SI 0 "register_operand" "")
3033 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3036 rtx temp = gen_reg_rtx (SImode);
3037 rtx shift_24 = GEN_INT (24);
3038 int op1_subbyte = 0;
3040 if (GET_CODE (operand1) == SUBREG)
3042 op1_subbyte = SUBREG_BYTE (operand1);
3043 op1_subbyte /= GET_MODE_SIZE (SImode);
3044 op1_subbyte *= GET_MODE_SIZE (SImode);
3045 operand1 = XEXP (operand1, 0);
3048 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3050 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3054 (define_insn "*sign_extendqisi2_insn"
3055 [(set (match_operand:SI 0 "register_operand" "=r")
3056 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3059 [(set_attr "type" "sload")
3060 (set_attr "us3load_type" "3cycle")])
3062 (define_expand "extendqidi2"
3063 [(set (match_operand:DI 0 "register_operand" "")
3064 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3067 rtx temp = gen_reg_rtx (DImode);
3068 rtx shift_56 = GEN_INT (56);
3069 int op1_subbyte = 0;
3071 if (GET_CODE (operand1) == SUBREG)
3073 op1_subbyte = SUBREG_BYTE (operand1);
3074 op1_subbyte /= GET_MODE_SIZE (DImode);
3075 op1_subbyte *= GET_MODE_SIZE (DImode);
3076 operand1 = XEXP (operand1, 0);
3079 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3081 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3085 (define_insn "*sign_extendqidi2_insn"
3086 [(set (match_operand:DI 0 "register_operand" "=r")
3087 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3090 [(set_attr "type" "sload")
3091 (set_attr "us3load_type" "3cycle")])
3093 (define_expand "extendhidi2"
3094 [(set (match_operand:DI 0 "register_operand" "")
3095 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3098 rtx temp = gen_reg_rtx (DImode);
3099 rtx shift_48 = GEN_INT (48);
3100 int op1_subbyte = 0;
3102 if (GET_CODE (operand1) == SUBREG)
3104 op1_subbyte = SUBREG_BYTE (operand1);
3105 op1_subbyte /= GET_MODE_SIZE (DImode);
3106 op1_subbyte *= GET_MODE_SIZE (DImode);
3107 operand1 = XEXP (operand1, 0);
3110 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3112 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3116 (define_insn "*sign_extendhidi2_insn"
3117 [(set (match_operand:DI 0 "register_operand" "=r")
3118 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3121 [(set_attr "type" "sload")
3122 (set_attr "us3load_type" "3cycle")])
3124 (define_expand "extendsidi2"
3125 [(set (match_operand:DI 0 "register_operand" "")
3126 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3130 (define_insn "*sign_extendsidi2_insn"
3131 [(set (match_operand:DI 0 "register_operand" "=r,r")
3132 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3137 [(set_attr "type" "shift,sload")
3138 (set_attr "us3load_type" "*,3cycle")])
3141 ;; Special pattern for optimizing bit-field compares. This is needed
3142 ;; because combine uses this as a canonical form.
3144 (define_insn "*cmp_zero_extract"
3147 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3148 (match_operand:SI 1 "small_int_operand" "I")
3149 (match_operand:SI 2 "small_int_operand" "I"))
3151 "INTVAL (operands[2]) > 19"
3153 int len = INTVAL (operands[1]);
3154 int pos = 32 - INTVAL (operands[2]) - len;
3155 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3156 operands[1] = GEN_INT (mask);
3157 return "andcc\t%0, %1, %%g0";
3159 [(set_attr "type" "compare")])
3161 (define_insn "*cmp_zero_extract_sp64"
3164 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3165 (match_operand:SI 1 "small_int_operand" "I")
3166 (match_operand:SI 2 "small_int_operand" "I"))
3168 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3170 int len = INTVAL (operands[1]);
3171 int pos = 64 - INTVAL (operands[2]) - len;
3172 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3173 operands[1] = GEN_INT (mask);
3174 return "andcc\t%0, %1, %%g0";
3176 [(set_attr "type" "compare")])
3179 ;; Conversions between float, double and long double.
3181 (define_insn "extendsfdf2"
3182 [(set (match_operand:DF 0 "register_operand" "=e")
3184 (match_operand:SF 1 "register_operand" "f")))]
3187 [(set_attr "type" "fp")
3188 (set_attr "fptype" "double")])
3190 (define_expand "extendsftf2"
3191 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3193 (match_operand:SF 1 "register_operand" "")))]
3194 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3195 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3197 (define_insn "*extendsftf2_hq"
3198 [(set (match_operand:TF 0 "register_operand" "=e")
3200 (match_operand:SF 1 "register_operand" "f")))]
3201 "TARGET_FPU && TARGET_HARD_QUAD"
3203 [(set_attr "type" "fp")])
3205 (define_expand "extenddftf2"
3206 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3208 (match_operand:DF 1 "register_operand" "")))]
3209 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3210 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3212 (define_insn "*extenddftf2_hq"
3213 [(set (match_operand:TF 0 "register_operand" "=e")
3215 (match_operand:DF 1 "register_operand" "e")))]
3216 "TARGET_FPU && TARGET_HARD_QUAD"
3218 [(set_attr "type" "fp")])
3220 (define_insn "truncdfsf2"
3221 [(set (match_operand:SF 0 "register_operand" "=f")
3223 (match_operand:DF 1 "register_operand" "e")))]
3226 [(set_attr "type" "fp")
3227 (set_attr "fptype" "double")])
3229 (define_expand "trunctfsf2"
3230 [(set (match_operand:SF 0 "register_operand" "")
3232 (match_operand:TF 1 "general_operand" "")))]
3233 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3234 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3236 (define_insn "*trunctfsf2_hq"
3237 [(set (match_operand:SF 0 "register_operand" "=f")
3239 (match_operand:TF 1 "register_operand" "e")))]
3240 "TARGET_FPU && TARGET_HARD_QUAD"
3242 [(set_attr "type" "fp")])
3244 (define_expand "trunctfdf2"
3245 [(set (match_operand:DF 0 "register_operand" "")
3247 (match_operand:TF 1 "general_operand" "")))]
3248 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3249 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3251 (define_insn "*trunctfdf2_hq"
3252 [(set (match_operand:DF 0 "register_operand" "=e")
3254 (match_operand:TF 1 "register_operand" "e")))]
3255 "TARGET_FPU && TARGET_HARD_QUAD"
3257 [(set_attr "type" "fp")])
3260 ;; Conversion between fixed point and floating point.
3262 (define_insn "floatsisf2"
3263 [(set (match_operand:SF 0 "register_operand" "=f")
3264 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3267 [(set_attr "type" "fp")
3268 (set_attr "fptype" "double")])
3270 (define_insn "floatsidf2"
3271 [(set (match_operand:DF 0 "register_operand" "=e")
3272 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3275 [(set_attr "type" "fp")
3276 (set_attr "fptype" "double")])
3278 (define_expand "floatsitf2"
3279 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3280 (float:TF (match_operand:SI 1 "register_operand" "")))]
3281 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3282 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3284 (define_insn "*floatsitf2_hq"
3285 [(set (match_operand:TF 0 "register_operand" "=e")
3286 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3287 "TARGET_FPU && TARGET_HARD_QUAD"
3289 [(set_attr "type" "fp")])
3291 (define_expand "floatunssitf2"
3292 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3293 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3294 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3295 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3297 ;; Now the same for 64 bit sources.
3299 (define_insn "floatdisf2"
3300 [(set (match_operand:SF 0 "register_operand" "=f")
3301 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3302 "TARGET_V9 && TARGET_FPU"
3304 [(set_attr "type" "fp")
3305 (set_attr "fptype" "double")])
3307 (define_expand "floatunsdisf2"
3308 [(use (match_operand:SF 0 "register_operand" ""))
3309 (use (match_operand:DI 1 "general_operand" ""))]
3310 "TARGET_ARCH64 && TARGET_FPU"
3311 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3313 (define_insn "floatdidf2"
3314 [(set (match_operand:DF 0 "register_operand" "=e")
3315 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3316 "TARGET_V9 && TARGET_FPU"
3318 [(set_attr "type" "fp")
3319 (set_attr "fptype" "double")])
3321 (define_expand "floatunsdidf2"
3322 [(use (match_operand:DF 0 "register_operand" ""))
3323 (use (match_operand:DI 1 "general_operand" ""))]
3324 "TARGET_ARCH64 && TARGET_FPU"
3325 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3327 (define_expand "floatditf2"
3328 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3329 (float:TF (match_operand:DI 1 "register_operand" "")))]
3330 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3331 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3333 (define_insn "*floatditf2_hq"
3334 [(set (match_operand:TF 0 "register_operand" "=e")
3335 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3336 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3338 [(set_attr "type" "fp")])
3340 (define_expand "floatunsditf2"
3341 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3342 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3343 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3344 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3346 ;; Convert a float to an actual integer.
3347 ;; Truncation is performed as part of the conversion.
3349 (define_insn "fix_truncsfsi2"
3350 [(set (match_operand:SI 0 "register_operand" "=f")
3351 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3354 [(set_attr "type" "fp")
3355 (set_attr "fptype" "double")])
3357 (define_insn "fix_truncdfsi2"
3358 [(set (match_operand:SI 0 "register_operand" "=f")
3359 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3362 [(set_attr "type" "fp")
3363 (set_attr "fptype" "double")])
3365 (define_expand "fix_trunctfsi2"
3366 [(set (match_operand:SI 0 "register_operand" "")
3367 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3368 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3369 "emit_tfmode_cvt (FIX, operands); DONE;")
3371 (define_insn "*fix_trunctfsi2_hq"
3372 [(set (match_operand:SI 0 "register_operand" "=f")
3373 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3374 "TARGET_FPU && TARGET_HARD_QUAD"
3376 [(set_attr "type" "fp")])
3378 (define_expand "fixuns_trunctfsi2"
3379 [(set (match_operand:SI 0 "register_operand" "")
3380 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3381 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3382 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3384 ;; Now the same, for V9 targets
3386 (define_insn "fix_truncsfdi2"
3387 [(set (match_operand:DI 0 "register_operand" "=e")
3388 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3389 "TARGET_V9 && TARGET_FPU"
3391 [(set_attr "type" "fp")
3392 (set_attr "fptype" "double")])
3394 (define_expand "fixuns_truncsfdi2"
3395 [(use (match_operand:DI 0 "register_operand" ""))
3396 (use (match_operand:SF 1 "general_operand" ""))]
3397 "TARGET_ARCH64 && TARGET_FPU"
3398 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3400 (define_insn "fix_truncdfdi2"
3401 [(set (match_operand:DI 0 "register_operand" "=e")
3402 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3403 "TARGET_V9 && TARGET_FPU"
3405 [(set_attr "type" "fp")
3406 (set_attr "fptype" "double")])
3408 (define_expand "fixuns_truncdfdi2"
3409 [(use (match_operand:DI 0 "register_operand" ""))
3410 (use (match_operand:DF 1 "general_operand" ""))]
3411 "TARGET_ARCH64 && TARGET_FPU"
3412 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3414 (define_expand "fix_trunctfdi2"
3415 [(set (match_operand:DI 0 "register_operand" "")
3416 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3417 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3418 "emit_tfmode_cvt (FIX, operands); DONE;")
3420 (define_insn "*fix_trunctfdi2_hq"
3421 [(set (match_operand:DI 0 "register_operand" "=e")
3422 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3423 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3425 [(set_attr "type" "fp")])
3427 (define_expand "fixuns_trunctfdi2"
3428 [(set (match_operand:DI 0 "register_operand" "")
3429 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3430 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3431 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3434 ;; Integer addition/subtraction instructions.
3436 (define_expand "adddi3"
3437 [(set (match_operand:DI 0 "register_operand" "")
3438 (plus:DI (match_operand:DI 1 "register_operand" "")
3439 (match_operand:DI 2 "arith_double_add_operand" "")))]
3442 if (! TARGET_ARCH64)
3444 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3445 gen_rtx_SET (VOIDmode, operands[0],
3446 gen_rtx_PLUS (DImode, operands[1],
3448 gen_rtx_CLOBBER (VOIDmode,
3449 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3454 (define_insn_and_split "adddi3_insn_sp32"
3455 [(set (match_operand:DI 0 "register_operand" "=r")
3456 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3457 (match_operand:DI 2 "arith_double_operand" "rHI")))
3458 (clobber (reg:CC 100))]
3461 "&& reload_completed"
3462 [(parallel [(set (reg:CC_NOOV 100)
3463 (compare:CC_NOOV (plus:SI (match_dup 4)
3467 (plus:SI (match_dup 4) (match_dup 5)))])
3469 (plus:SI (plus:SI (match_dup 7)
3471 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3473 operands[3] = gen_lowpart (SImode, operands[0]);
3474 operands[4] = gen_lowpart (SImode, operands[1]);
3475 operands[5] = gen_lowpart (SImode, operands[2]);
3476 operands[6] = gen_highpart (SImode, operands[0]);
3477 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3478 #if HOST_BITS_PER_WIDE_INT == 32
3479 if (GET_CODE (operands[2]) == CONST_INT)
3481 if (INTVAL (operands[2]) < 0)
3482 operands[8] = constm1_rtx;
3484 operands[8] = const0_rtx;
3488 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3490 [(set_attr "length" "2")])
3492 ;; LTU here means "carry set"
3494 [(set (match_operand:SI 0 "register_operand" "=r")
3495 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3496 (match_operand:SI 2 "arith_operand" "rI"))
3497 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3500 [(set_attr "type" "ialuX")])
3502 (define_insn_and_split "*addx_extend_sp32"
3503 [(set (match_operand:DI 0 "register_operand" "=r")
3504 (zero_extend:DI (plus:SI (plus:SI
3505 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3506 (match_operand:SI 2 "arith_operand" "rI"))
3507 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3510 "&& reload_completed"
3511 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3512 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3513 (set (match_dup 4) (const_int 0))]
3514 "operands[3] = gen_lowpart (SImode, operands[0]);
3515 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3516 [(set_attr "length" "2")])
3518 (define_insn "*addx_extend_sp64"
3519 [(set (match_operand:DI 0 "register_operand" "=r")
3520 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3521 (match_operand:SI 2 "arith_operand" "rI"))
3522 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3525 [(set_attr "type" "ialuX")])
3527 (define_insn_and_split ""
3528 [(set (match_operand:DI 0 "register_operand" "=r")
3529 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3530 (match_operand:DI 2 "register_operand" "r")))
3531 (clobber (reg:CC 100))]
3534 "&& reload_completed"
3535 [(parallel [(set (reg:CC_NOOV 100)
3536 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3538 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3540 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3541 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3542 "operands[3] = gen_lowpart (SImode, operands[2]);
3543 operands[4] = gen_highpart (SImode, operands[2]);
3544 operands[5] = gen_lowpart (SImode, operands[0]);
3545 operands[6] = gen_highpart (SImode, operands[0]);"
3546 [(set_attr "length" "2")])
3548 (define_insn "*adddi3_sp64"
3549 [(set (match_operand:DI 0 "register_operand" "=r,r")
3550 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3551 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3557 (define_insn "addsi3"
3558 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3559 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3560 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3565 fpadd32s\t%1, %2, %0"
3566 [(set_attr "type" "*,*,fga")
3567 (set_attr "fptype" "*,*,single")])
3569 (define_insn "*cmp_cc_plus"
3570 [(set (reg:CC_NOOV 100)
3571 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3572 (match_operand:SI 1 "arith_operand" "rI"))
3575 "addcc\t%0, %1, %%g0"
3576 [(set_attr "type" "compare")])
3578 (define_insn "*cmp_ccx_plus"
3579 [(set (reg:CCX_NOOV 100)
3580 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3581 (match_operand:DI 1 "arith_operand" "rI"))
3584 "addcc\t%0, %1, %%g0"
3585 [(set_attr "type" "compare")])
3587 (define_insn "*cmp_cc_plus_set"
3588 [(set (reg:CC_NOOV 100)
3589 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3590 (match_operand:SI 2 "arith_operand" "rI"))
3592 (set (match_operand:SI 0 "register_operand" "=r")
3593 (plus:SI (match_dup 1) (match_dup 2)))]
3596 [(set_attr "type" "compare")])
3598 (define_insn "*cmp_ccx_plus_set"
3599 [(set (reg:CCX_NOOV 100)
3600 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3601 (match_operand:DI 2 "arith_operand" "rI"))
3603 (set (match_operand:DI 0 "register_operand" "=r")
3604 (plus:DI (match_dup 1) (match_dup 2)))]
3607 [(set_attr "type" "compare")])
3609 (define_expand "subdi3"
3610 [(set (match_operand:DI 0 "register_operand" "")
3611 (minus:DI (match_operand:DI 1 "register_operand" "")
3612 (match_operand:DI 2 "arith_double_add_operand" "")))]
3615 if (! TARGET_ARCH64)
3617 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3618 gen_rtx_SET (VOIDmode, operands[0],
3619 gen_rtx_MINUS (DImode, operands[1],
3621 gen_rtx_CLOBBER (VOIDmode,
3622 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3627 (define_insn_and_split "subdi3_insn_sp32"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3629 (minus:DI (match_operand:DI 1 "register_operand" "r")
3630 (match_operand:DI 2 "arith_double_operand" "rHI")))
3631 (clobber (reg:CC 100))]
3634 "&& reload_completed"
3635 [(parallel [(set (reg:CC_NOOV 100)
3636 (compare:CC_NOOV (minus:SI (match_dup 4)
3640 (minus:SI (match_dup 4) (match_dup 5)))])
3642 (minus:SI (minus:SI (match_dup 7)
3644 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3646 operands[3] = gen_lowpart (SImode, operands[0]);
3647 operands[4] = gen_lowpart (SImode, operands[1]);
3648 operands[5] = gen_lowpart (SImode, operands[2]);
3649 operands[6] = gen_highpart (SImode, operands[0]);
3650 operands[7] = gen_highpart (SImode, operands[1]);
3651 #if HOST_BITS_PER_WIDE_INT == 32
3652 if (GET_CODE (operands[2]) == CONST_INT)
3654 if (INTVAL (operands[2]) < 0)
3655 operands[8] = constm1_rtx;
3657 operands[8] = const0_rtx;
3661 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3663 [(set_attr "length" "2")])
3665 ;; LTU here means "carry set"
3667 [(set (match_operand:SI 0 "register_operand" "=r")
3668 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3669 (match_operand:SI 2 "arith_operand" "rI"))
3670 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3673 [(set_attr "type" "ialuX")])
3675 (define_insn "*subx_extend_sp64"
3676 [(set (match_operand:DI 0 "register_operand" "=r")
3677 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3678 (match_operand:SI 2 "arith_operand" "rI"))
3679 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3682 [(set_attr "type" "ialuX")])
3684 (define_insn_and_split "*subx_extend"
3685 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3687 (match_operand:SI 2 "arith_operand" "rI"))
3688 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3691 "&& reload_completed"
3692 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3693 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3694 (set (match_dup 4) (const_int 0))]
3695 "operands[3] = gen_lowpart (SImode, operands[0]);
3696 operands[4] = gen_highpart (SImode, operands[0]);"
3697 [(set_attr "length" "2")])
3699 (define_insn_and_split ""
3700 [(set (match_operand:DI 0 "register_operand" "=r")
3701 (minus:DI (match_operand:DI 1 "register_operand" "r")
3702 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3703 (clobber (reg:CC 100))]
3706 "&& reload_completed"
3707 [(parallel [(set (reg:CC_NOOV 100)
3708 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3710 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3712 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3713 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3714 "operands[3] = gen_lowpart (SImode, operands[1]);
3715 operands[4] = gen_highpart (SImode, operands[1]);
3716 operands[5] = gen_lowpart (SImode, operands[0]);
3717 operands[6] = gen_highpart (SImode, operands[0]);"
3718 [(set_attr "length" "2")])
3720 (define_insn "*subdi3_sp64"
3721 [(set (match_operand:DI 0 "register_operand" "=r,r")
3722 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3723 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3729 (define_insn "subsi3"
3730 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3731 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3732 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3737 fpsub32s\t%1, %2, %0"
3738 [(set_attr "type" "*,*,fga")
3739 (set_attr "fptype" "*,*,single")])
3741 (define_insn "*cmp_minus_cc"
3742 [(set (reg:CC_NOOV 100)
3743 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3744 (match_operand:SI 1 "arith_operand" "rI"))
3747 "subcc\t%r0, %1, %%g0"
3748 [(set_attr "type" "compare")])
3750 (define_insn "*cmp_minus_ccx"
3751 [(set (reg:CCX_NOOV 100)
3752 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3753 (match_operand:DI 1 "arith_operand" "rI"))
3756 "subcc\t%0, %1, %%g0"
3757 [(set_attr "type" "compare")])
3759 (define_insn "cmp_minus_cc_set"
3760 [(set (reg:CC_NOOV 100)
3761 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3762 (match_operand:SI 2 "arith_operand" "rI"))
3764 (set (match_operand:SI 0 "register_operand" "=r")
3765 (minus:SI (match_dup 1) (match_dup 2)))]
3767 "subcc\t%r1, %2, %0"
3768 [(set_attr "type" "compare")])
3770 (define_insn "*cmp_minus_ccx_set"
3771 [(set (reg:CCX_NOOV 100)
3772 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3773 (match_operand:DI 2 "arith_operand" "rI"))
3775 (set (match_operand:DI 0 "register_operand" "=r")
3776 (minus:DI (match_dup 1) (match_dup 2)))]
3779 [(set_attr "type" "compare")])
3782 ;; Integer multiply/divide instructions.
3784 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3785 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3787 (define_insn "mulsi3"
3788 [(set (match_operand:SI 0 "register_operand" "=r")
3789 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3790 (match_operand:SI 2 "arith_operand" "rI")))]
3793 [(set_attr "type" "imul")])
3795 (define_expand "muldi3"
3796 [(set (match_operand:DI 0 "register_operand" "")
3797 (mult:DI (match_operand:DI 1 "arith_operand" "")
3798 (match_operand:DI 2 "arith_operand" "")))]
3799 "TARGET_ARCH64 || TARGET_V8PLUS"
3803 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3808 (define_insn "*muldi3_sp64"
3809 [(set (match_operand:DI 0 "register_operand" "=r")
3810 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3811 (match_operand:DI 2 "arith_operand" "rI")))]
3814 [(set_attr "type" "imul")])
3816 ;; V8plus wide multiply.
3818 (define_insn "muldi3_v8plus"
3819 [(set (match_operand:DI 0 "register_operand" "=r,h")
3820 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3821 (match_operand:DI 2 "arith_operand" "rI,rI")))
3822 (clobber (match_scratch:SI 3 "=&h,X"))
3823 (clobber (match_scratch:SI 4 "=&h,X"))]
3826 if (sparc_check_64 (operands[1], insn) <= 0)
3827 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3828 if (which_alternative == 1)
3829 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3830 if (GET_CODE (operands[2]) == CONST_INT)
3832 if (which_alternative == 1)
3833 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3835 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";
3837 else if (rtx_equal_p (operands[1], operands[2]))
3839 if (which_alternative == 1)
3840 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3842 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";
3844 if (sparc_check_64 (operands[2], insn) <= 0)
3845 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3846 if (which_alternative == 1)
3847 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";
3849 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";
3851 [(set_attr "type" "multi")
3852 (set_attr "length" "9,8")])
3854 (define_insn "*cmp_mul_set"
3856 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3857 (match_operand:SI 2 "arith_operand" "rI"))
3859 (set (match_operand:SI 0 "register_operand" "=r")
3860 (mult:SI (match_dup 1) (match_dup 2)))]
3861 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3862 "smulcc\t%1, %2, %0"
3863 [(set_attr "type" "imul")])
3865 (define_expand "mulsidi3"
3866 [(set (match_operand:DI 0 "register_operand" "")
3867 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3868 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3871 if (CONSTANT_P (operands[2]))
3874 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3876 else if (TARGET_ARCH32)
3877 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3880 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3886 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3891 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3892 ;; registers can hold 64-bit values in the V8plus environment.
3894 (define_insn "mulsidi3_v8plus"
3895 [(set (match_operand:DI 0 "register_operand" "=h,r")
3896 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3897 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3898 (clobber (match_scratch:SI 3 "=X,&h"))]
3901 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3902 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3903 [(set_attr "type" "multi")
3904 (set_attr "length" "2,3")])
3907 (define_insn "const_mulsidi3_v8plus"
3908 [(set (match_operand:DI 0 "register_operand" "=h,r")
3909 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3910 (match_operand:DI 2 "small_int_operand" "I,I")))
3911 (clobber (match_scratch:SI 3 "=X,&h"))]
3914 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3915 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3916 [(set_attr "type" "multi")
3917 (set_attr "length" "2,3")])
3920 (define_insn "*mulsidi3_sp32"
3921 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3923 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3926 return TARGET_SPARCLET
3927 ? "smuld\t%1, %2, %L0"
3928 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3931 (if_then_else (eq_attr "isa" "sparclet")
3932 (const_string "imul") (const_string "multi")))
3933 (set (attr "length")
3934 (if_then_else (eq_attr "isa" "sparclet")
3935 (const_int 1) (const_int 2)))])
3937 (define_insn "*mulsidi3_sp64"
3938 [(set (match_operand:DI 0 "register_operand" "=r")
3939 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3940 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3941 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3943 [(set_attr "type" "imul")])
3945 ;; Extra pattern, because sign_extend of a constant isn't valid.
3948 (define_insn "const_mulsidi3_sp32"
3949 [(set (match_operand:DI 0 "register_operand" "=r")
3950 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3951 (match_operand:DI 2 "small_int_operand" "I")))]
3954 return TARGET_SPARCLET
3955 ? "smuld\t%1, %2, %L0"
3956 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3959 (if_then_else (eq_attr "isa" "sparclet")
3960 (const_string "imul") (const_string "multi")))
3961 (set (attr "length")
3962 (if_then_else (eq_attr "isa" "sparclet")
3963 (const_int 1) (const_int 2)))])
3965 (define_insn "const_mulsidi3_sp64"
3966 [(set (match_operand:DI 0 "register_operand" "=r")
3967 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3968 (match_operand:DI 2 "small_int_operand" "I")))]
3969 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3971 [(set_attr "type" "imul")])
3973 (define_expand "smulsi3_highpart"
3974 [(set (match_operand:SI 0 "register_operand" "")
3976 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3977 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3979 "TARGET_HARD_MUL && TARGET_ARCH32"
3981 if (CONSTANT_P (operands[2]))
3985 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
3991 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3996 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
3997 operands[2], GEN_INT (32)));
4003 (define_insn "smulsi3_highpart_v8plus"
4004 [(set (match_operand:SI 0 "register_operand" "=h,r")
4006 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4007 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4008 (match_operand:SI 3 "small_int_operand" "I,I"))))
4009 (clobber (match_scratch:SI 4 "=X,&h"))]
4012 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4013 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4014 [(set_attr "type" "multi")
4015 (set_attr "length" "2")])
4017 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4020 [(set (match_operand:SI 0 "register_operand" "=h,r")
4023 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4024 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4025 (match_operand:SI 3 "small_int_operand" "I,I"))
4027 (clobber (match_scratch:SI 4 "=X,&h"))]
4030 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4031 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4032 [(set_attr "type" "multi")
4033 (set_attr "length" "2")])
4036 (define_insn "const_smulsi3_highpart_v8plus"
4037 [(set (match_operand:SI 0 "register_operand" "=h,r")
4039 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4040 (match_operand:DI 2 "small_int_operand" "I,I"))
4041 (match_operand:SI 3 "small_int_operand" "I,I"))))
4042 (clobber (match_scratch:SI 4 "=X,&h"))]
4045 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4046 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4047 [(set_attr "type" "multi")
4048 (set_attr "length" "2")])
4051 (define_insn "*smulsi3_highpart_sp32"
4052 [(set (match_operand:SI 0 "register_operand" "=r")
4054 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4055 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4058 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4059 [(set_attr "type" "multi")
4060 (set_attr "length" "2")])
4063 (define_insn "const_smulsi3_highpart"
4064 [(set (match_operand:SI 0 "register_operand" "=r")
4066 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4067 (match_operand:DI 2 "small_int_operand" "i"))
4070 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4071 [(set_attr "type" "multi")
4072 (set_attr "length" "2")])
4074 (define_expand "umulsidi3"
4075 [(set (match_operand:DI 0 "register_operand" "")
4076 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4077 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4080 if (CONSTANT_P (operands[2]))
4083 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4085 else if (TARGET_ARCH32)
4086 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4089 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4095 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4101 (define_insn "umulsidi3_v8plus"
4102 [(set (match_operand:DI 0 "register_operand" "=h,r")
4103 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4104 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4105 (clobber (match_scratch:SI 3 "=X,&h"))]
4108 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4109 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4110 [(set_attr "type" "multi")
4111 (set_attr "length" "2,3")])
4114 (define_insn "*umulsidi3_sp32"
4115 [(set (match_operand:DI 0 "register_operand" "=r")
4116 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4117 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4120 return TARGET_SPARCLET
4121 ? "umuld\t%1, %2, %L0"
4122 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4125 (if_then_else (eq_attr "isa" "sparclet")
4126 (const_string "imul") (const_string "multi")))
4127 (set (attr "length")
4128 (if_then_else (eq_attr "isa" "sparclet")
4129 (const_int 1) (const_int 2)))])
4131 (define_insn "*umulsidi3_sp64"
4132 [(set (match_operand:DI 0 "register_operand" "=r")
4133 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4134 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4135 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4137 [(set_attr "type" "imul")])
4139 ;; Extra pattern, because sign_extend of a constant isn't valid.
4142 (define_insn "const_umulsidi3_sp32"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4145 (match_operand:DI 2 "uns_small_int_operand" "")))]
4148 return TARGET_SPARCLET
4149 ? "umuld\t%1, %s2, %L0"
4150 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4153 (if_then_else (eq_attr "isa" "sparclet")
4154 (const_string "imul") (const_string "multi")))
4155 (set (attr "length")
4156 (if_then_else (eq_attr "isa" "sparclet")
4157 (const_int 1) (const_int 2)))])
4159 (define_insn "const_umulsidi3_sp64"
4160 [(set (match_operand:DI 0 "register_operand" "=r")
4161 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4162 (match_operand:DI 2 "uns_small_int_operand" "")))]
4163 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4165 [(set_attr "type" "imul")])
4168 (define_insn "const_umulsidi3_v8plus"
4169 [(set (match_operand:DI 0 "register_operand" "=h,r")
4170 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4171 (match_operand:DI 2 "uns_small_int_operand" "")))
4172 (clobber (match_scratch:SI 3 "=X,h"))]
4175 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4176 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4177 [(set_attr "type" "multi")
4178 (set_attr "length" "2,3")])
4180 (define_expand "umulsi3_highpart"
4181 [(set (match_operand:SI 0 "register_operand" "")
4183 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4184 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4186 "TARGET_HARD_MUL && TARGET_ARCH32"
4188 if (CONSTANT_P (operands[2]))
4192 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4198 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4203 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4204 operands[2], GEN_INT (32)));
4210 (define_insn "umulsi3_highpart_v8plus"
4211 [(set (match_operand:SI 0 "register_operand" "=h,r")
4213 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4214 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4215 (match_operand:SI 3 "small_int_operand" "I,I"))))
4216 (clobber (match_scratch:SI 4 "=X,h"))]
4219 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4220 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4221 [(set_attr "type" "multi")
4222 (set_attr "length" "2")])
4225 (define_insn "const_umulsi3_highpart_v8plus"
4226 [(set (match_operand:SI 0 "register_operand" "=h,r")
4228 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4229 (match_operand:DI 2 "uns_small_int_operand" ""))
4230 (match_operand:SI 3 "small_int_operand" "I,I"))))
4231 (clobber (match_scratch:SI 4 "=X,h"))]
4234 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4235 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4236 [(set_attr "type" "multi")
4237 (set_attr "length" "2")])
4240 (define_insn "*umulsi3_highpart_sp32"
4241 [(set (match_operand:SI 0 "register_operand" "=r")
4243 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4244 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4247 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4248 [(set_attr "type" "multi")
4249 (set_attr "length" "2")])
4252 (define_insn "const_umulsi3_highpart"
4253 [(set (match_operand:SI 0 "register_operand" "=r")
4255 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4256 (match_operand:DI 2 "uns_small_int_operand" ""))
4259 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4260 [(set_attr "type" "multi")
4261 (set_attr "length" "2")])
4263 (define_expand "divsi3"
4264 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4265 (div:SI (match_operand:SI 1 "register_operand" "")
4266 (match_operand:SI 2 "input_operand" "")))
4267 (clobber (match_scratch:SI 3 ""))])]
4268 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4272 operands[3] = gen_reg_rtx(SImode);
4273 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4274 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4280 ;; The V8 architecture specifies that there must be at least 3 instructions
4281 ;; between a write to the Y register and a use of it for correct results.
4282 ;; We try to fill one of them with a simple constant or a memory load.
4284 (define_insn "divsi3_sp32"
4285 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4286 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4287 (match_operand:SI 2 "input_operand" "rI,K,m")))
4288 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4289 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4291 output_asm_insn ("sra\t%1, 31, %3", operands);
4292 output_asm_insn ("wr\t%3, 0, %%y", operands);
4294 switch (which_alternative)
4298 return "sdiv\t%1, %2, %0";
4300 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4303 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4305 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4308 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4310 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4315 [(set_attr "type" "multi")
4316 (set (attr "length")
4317 (if_then_else (eq_attr "isa" "v9")
4318 (const_int 4) (const_int 6)))])
4320 (define_insn "divsi3_sp64"
4321 [(set (match_operand:SI 0 "register_operand" "=r")
4322 (div:SI (match_operand:SI 1 "register_operand" "r")
4323 (match_operand:SI 2 "input_operand" "rI")))
4324 (use (match_operand:SI 3 "register_operand" "r"))]
4325 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4326 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4327 [(set_attr "type" "multi")
4328 (set_attr "length" "2")])
4330 (define_insn "divdi3"
4331 [(set (match_operand:DI 0 "register_operand" "=r")
4332 (div:DI (match_operand:DI 1 "register_operand" "r")
4333 (match_operand:DI 2 "arith_operand" "rI")))]
4336 [(set_attr "type" "idiv")])
4338 (define_insn "*cmp_sdiv_cc_set"
4340 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4341 (match_operand:SI 2 "arith_operand" "rI"))
4343 (set (match_operand:SI 0 "register_operand" "=r")
4344 (div:SI (match_dup 1) (match_dup 2)))
4345 (clobber (match_scratch:SI 3 "=&r"))]
4346 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4348 output_asm_insn ("sra\t%1, 31, %3", operands);
4349 output_asm_insn ("wr\t%3, 0, %%y", operands);
4352 return "sdivcc\t%1, %2, %0";
4354 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4356 [(set_attr "type" "multi")
4357 (set (attr "length")
4358 (if_then_else (eq_attr "isa" "v9")
4359 (const_int 3) (const_int 6)))])
4362 (define_expand "udivsi3"
4363 [(set (match_operand:SI 0 "register_operand" "")
4364 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4365 (match_operand:SI 2 "input_operand" "")))]
4366 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4369 ;; The V8 architecture specifies that there must be at least 3 instructions
4370 ;; between a write to the Y register and a use of it for correct results.
4371 ;; We try to fill one of them with a simple constant or a memory load.
4373 (define_insn "udivsi3_sp32"
4374 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4375 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4376 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4377 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4379 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4381 switch (which_alternative)
4385 return "udiv\t%1, %2, %0";
4387 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4390 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4392 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4395 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4397 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4400 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4402 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4407 [(set_attr "type" "multi")
4408 (set (attr "length")
4409 (if_then_else (eq_attr "isa" "v9")
4410 (const_int 3) (const_int 5)))])
4412 (define_insn "udivsi3_sp64"
4413 [(set (match_operand:SI 0 "register_operand" "=r")
4414 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4415 (match_operand:SI 2 "input_operand" "rI")))]
4416 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4417 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4418 [(set_attr "type" "multi")
4419 (set_attr "length" "2")])
4421 (define_insn "udivdi3"
4422 [(set (match_operand:DI 0 "register_operand" "=r")
4423 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4424 (match_operand:DI 2 "arith_operand" "rI")))]
4427 [(set_attr "type" "idiv")])
4429 (define_insn "*cmp_udiv_cc_set"
4431 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4432 (match_operand:SI 2 "arith_operand" "rI"))
4434 (set (match_operand:SI 0 "register_operand" "=r")
4435 (udiv:SI (match_dup 1) (match_dup 2)))]
4436 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4438 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4441 return "udivcc\t%1, %2, %0";
4443 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4445 [(set_attr "type" "multi")
4446 (set (attr "length")
4447 (if_then_else (eq_attr "isa" "v9")
4448 (const_int 2) (const_int 5)))])
4450 ; sparclet multiply/accumulate insns
4452 (define_insn "*smacsi"
4453 [(set (match_operand:SI 0 "register_operand" "=r")
4454 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4455 (match_operand:SI 2 "arith_operand" "rI"))
4456 (match_operand:SI 3 "register_operand" "0")))]
4459 [(set_attr "type" "imul")])
4461 (define_insn "*smacdi"
4462 [(set (match_operand:DI 0 "register_operand" "=r")
4463 (plus:DI (mult:DI (sign_extend:DI
4464 (match_operand:SI 1 "register_operand" "%r"))
4466 (match_operand:SI 2 "register_operand" "r")))
4467 (match_operand:DI 3 "register_operand" "0")))]
4469 "smacd\t%1, %2, %L0"
4470 [(set_attr "type" "imul")])
4472 (define_insn "*umacdi"
4473 [(set (match_operand:DI 0 "register_operand" "=r")
4474 (plus:DI (mult:DI (zero_extend:DI
4475 (match_operand:SI 1 "register_operand" "%r"))
4477 (match_operand:SI 2 "register_operand" "r")))
4478 (match_operand:DI 3 "register_operand" "0")))]
4480 "umacd\t%1, %2, %L0"
4481 [(set_attr "type" "imul")])
4484 ;; Boolean instructions.
4486 ;; We define DImode `and' so with DImode `not' we can get
4487 ;; DImode `andn'. Other combinations are possible.
4489 (define_expand "and<V64I:mode>3"
4490 [(set (match_operand:V64I 0 "register_operand" "")
4491 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4492 (match_operand:V64I 2 "arith_double_operand" "")))]
4496 (define_insn "*and<V64I:mode>3_sp32"
4497 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4498 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4499 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4504 [(set_attr "type" "*,fga")
4505 (set_attr "length" "2,*")
4506 (set_attr "fptype" "*,double")])
4508 (define_insn "*and<V64I:mode>3_sp64"
4509 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4510 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4511 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4516 [(set_attr "type" "*,fga")
4517 (set_attr "fptype" "*,double")])
4519 (define_insn "and<V32I:mode>3"
4520 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4521 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4522 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4527 [(set_attr "type" "*,fga")
4528 (set_attr "fptype" "*,single")])
4531 [(set (match_operand:SI 0 "register_operand" "")
4532 (and:SI (match_operand:SI 1 "register_operand" "")
4533 (match_operand:SI 2 "const_compl_high_operand" "")))
4534 (clobber (match_operand:SI 3 "register_operand" ""))]
4536 [(set (match_dup 3) (match_dup 4))
4537 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4539 operands[4] = GEN_INT (~INTVAL (operands[2]));
4542 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4543 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4544 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4545 (match_operand:V64I 2 "register_operand" "r,b")))]
4549 fandnot1\t%1, %2, %0"
4550 "&& reload_completed
4551 && ((GET_CODE (operands[0]) == REG
4552 && REGNO (operands[0]) < 32)
4553 || (GET_CODE (operands[0]) == SUBREG
4554 && GET_CODE (SUBREG_REG (operands[0])) == REG
4555 && REGNO (SUBREG_REG (operands[0])) < 32))"
4556 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4557 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4558 "operands[3] = gen_highpart (SImode, operands[0]);
4559 operands[4] = gen_highpart (SImode, operands[1]);
4560 operands[5] = gen_highpart (SImode, operands[2]);
4561 operands[6] = gen_lowpart (SImode, operands[0]);
4562 operands[7] = gen_lowpart (SImode, operands[1]);
4563 operands[8] = gen_lowpart (SImode, operands[2]);"
4564 [(set_attr "type" "*,fga")
4565 (set_attr "length" "2,*")
4566 (set_attr "fptype" "*,double")])
4568 (define_insn "*and_not_<V64I:mode>_sp64"
4569 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4570 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4571 (match_operand:V64I 2 "register_operand" "r,b")))]
4575 fandnot1\t%1, %2, %0"
4576 [(set_attr "type" "*,fga")
4577 (set_attr "fptype" "*,double")])
4579 (define_insn "*and_not_<V32I:mode>"
4580 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4581 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4582 (match_operand:V32I 2 "register_operand" "r,d")))]
4586 fandnot1s\t%1, %2, %0"
4587 [(set_attr "type" "*,fga")
4588 (set_attr "fptype" "*,single")])
4590 (define_expand "ior<V64I:mode>3"
4591 [(set (match_operand:V64I 0 "register_operand" "")
4592 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4593 (match_operand:V64I 2 "arith_double_operand" "")))]
4597 (define_insn "*ior<V64I:mode>3_sp32"
4598 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4599 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4600 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4605 [(set_attr "type" "*,fga")
4606 (set_attr "length" "2,*")
4607 (set_attr "fptype" "*,double")])
4609 (define_insn "*ior<V64I:mode>3_sp64"
4610 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4611 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4612 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4617 [(set_attr "type" "*,fga")
4618 (set_attr "fptype" "*,double")])
4620 (define_insn "ior<V32I:mode>3"
4621 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4622 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4623 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4628 [(set_attr "type" "*,fga")
4629 (set_attr "fptype" "*,single")])
4632 [(set (match_operand:SI 0 "register_operand" "")
4633 (ior:SI (match_operand:SI 1 "register_operand" "")
4634 (match_operand:SI 2 "const_compl_high_operand" "")))
4635 (clobber (match_operand:SI 3 "register_operand" ""))]
4637 [(set (match_dup 3) (match_dup 4))
4638 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4640 operands[4] = GEN_INT (~INTVAL (operands[2]));
4643 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4644 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4645 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4646 (match_operand:V64I 2 "register_operand" "r,b")))]
4650 fornot1\t%1, %2, %0"
4651 "&& reload_completed
4652 && ((GET_CODE (operands[0]) == REG
4653 && REGNO (operands[0]) < 32)
4654 || (GET_CODE (operands[0]) == SUBREG
4655 && GET_CODE (SUBREG_REG (operands[0])) == REG
4656 && REGNO (SUBREG_REG (operands[0])) < 32))"
4657 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4658 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4659 "operands[3] = gen_highpart (SImode, operands[0]);
4660 operands[4] = gen_highpart (SImode, operands[1]);
4661 operands[5] = gen_highpart (SImode, operands[2]);
4662 operands[6] = gen_lowpart (SImode, operands[0]);
4663 operands[7] = gen_lowpart (SImode, operands[1]);
4664 operands[8] = gen_lowpart (SImode, operands[2]);"
4665 [(set_attr "type" "*,fga")
4666 (set_attr "length" "2,*")
4667 (set_attr "fptype" "*,double")])
4669 (define_insn "*or_not_<V64I:mode>_sp64"
4670 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4671 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4672 (match_operand:V64I 2 "register_operand" "r,b")))]
4676 fornot1\t%1, %2, %0"
4677 [(set_attr "type" "*,fga")
4678 (set_attr "fptype" "*,double")])
4680 (define_insn "*or_not_<V32I:mode>"
4681 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4682 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4683 (match_operand:V32I 2 "register_operand" "r,d")))]
4687 fornot1s\t%1, %2, %0"
4688 [(set_attr "type" "*,fga")
4689 (set_attr "fptype" "*,single")])
4691 (define_expand "xor<V64I:mode>3"
4692 [(set (match_operand:V64I 0 "register_operand" "")
4693 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4694 (match_operand:V64I 2 "arith_double_operand" "")))]
4698 (define_insn "*xor<V64I:mode>3_sp32"
4699 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4700 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4701 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4706 [(set_attr "type" "*,fga")
4707 (set_attr "length" "2,*")
4708 (set_attr "fptype" "*,double")])
4710 (define_insn "*xor<V64I:mode>3_sp64"
4711 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4712 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4713 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4718 [(set_attr "type" "*,fga")
4719 (set_attr "fptype" "*,double")])
4721 (define_insn "xor<V32I:mode>3"
4722 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4723 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4724 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4729 [(set_attr "type" "*,fga")
4730 (set_attr "fptype" "*,single")])
4733 [(set (match_operand:SI 0 "register_operand" "")
4734 (xor:SI (match_operand:SI 1 "register_operand" "")
4735 (match_operand:SI 2 "const_compl_high_operand" "")))
4736 (clobber (match_operand:SI 3 "register_operand" ""))]
4738 [(set (match_dup 3) (match_dup 4))
4739 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4741 operands[4] = GEN_INT (~INTVAL (operands[2]));
4745 [(set (match_operand:SI 0 "register_operand" "")
4746 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4747 (match_operand:SI 2 "const_compl_high_operand" ""))))
4748 (clobber (match_operand:SI 3 "register_operand" ""))]
4750 [(set (match_dup 3) (match_dup 4))
4751 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4753 operands[4] = GEN_INT (~INTVAL (operands[2]));
4756 ;; Split DImode logical operations requiring two instructions.
4758 [(set (match_operand:V64I 0 "register_operand" "")
4759 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4760 [(match_operand:V64I 2 "register_operand" "")
4761 (match_operand:V64I 3 "arith_double_operand" "")]))]
4764 && ((GET_CODE (operands[0]) == REG
4765 && REGNO (operands[0]) < 32)
4766 || (GET_CODE (operands[0]) == SUBREG
4767 && GET_CODE (SUBREG_REG (operands[0])) == REG
4768 && REGNO (SUBREG_REG (operands[0])) < 32))"
4769 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4770 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4772 operands[4] = gen_highpart (SImode, operands[0]);
4773 operands[5] = gen_lowpart (SImode, operands[0]);
4774 operands[6] = gen_highpart (SImode, operands[2]);
4775 operands[7] = gen_lowpart (SImode, operands[2]);
4776 #if HOST_BITS_PER_WIDE_INT == 32
4777 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4779 if (INTVAL (operands[3]) < 0)
4780 operands[8] = constm1_rtx;
4782 operands[8] = const0_rtx;
4786 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4787 operands[9] = gen_lowpart (SImode, operands[3]);
4790 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4791 ;; Combine now canonicalizes to the rightmost expression.
4792 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4793 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4794 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4795 (match_operand:V64I 2 "register_operand" "r,b"))))]
4800 "&& reload_completed
4801 && ((GET_CODE (operands[0]) == REG
4802 && REGNO (operands[0]) < 32)
4803 || (GET_CODE (operands[0]) == SUBREG
4804 && GET_CODE (SUBREG_REG (operands[0])) == REG
4805 && REGNO (SUBREG_REG (operands[0])) < 32))"
4806 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4807 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4808 "operands[3] = gen_highpart (SImode, operands[0]);
4809 operands[4] = gen_highpart (SImode, operands[1]);
4810 operands[5] = gen_highpart (SImode, operands[2]);
4811 operands[6] = gen_lowpart (SImode, operands[0]);
4812 operands[7] = gen_lowpart (SImode, operands[1]);
4813 operands[8] = gen_lowpart (SImode, operands[2]);"
4814 [(set_attr "type" "*,fga")
4815 (set_attr "length" "2,*")
4816 (set_attr "fptype" "*,double")])
4818 (define_insn "*xor_not_<V64I:mode>_sp64"
4819 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4820 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4821 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4826 [(set_attr "type" "*,fga")
4827 (set_attr "fptype" "*,double")])
4829 (define_insn "*xor_not_<V32I:mode>"
4830 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4831 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4832 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4837 [(set_attr "type" "*,fga")
4838 (set_attr "fptype" "*,single")])
4840 ;; These correspond to the above in the case where we also (or only)
4841 ;; want to set the condition code.
4843 (define_insn "*cmp_cc_arith_op"
4846 (match_operator:SI 2 "cc_arith_operator"
4847 [(match_operand:SI 0 "arith_operand" "%r")
4848 (match_operand:SI 1 "arith_operand" "rI")])
4851 "%A2cc\t%0, %1, %%g0"
4852 [(set_attr "type" "compare")])
4854 (define_insn "*cmp_ccx_arith_op"
4857 (match_operator:DI 2 "cc_arith_operator"
4858 [(match_operand:DI 0 "arith_operand" "%r")
4859 (match_operand:DI 1 "arith_operand" "rI")])
4862 "%A2cc\t%0, %1, %%g0"
4863 [(set_attr "type" "compare")])
4865 (define_insn "*cmp_cc_arith_op_set"
4868 (match_operator:SI 3 "cc_arith_operator"
4869 [(match_operand:SI 1 "arith_operand" "%r")
4870 (match_operand:SI 2 "arith_operand" "rI")])
4872 (set (match_operand:SI 0 "register_operand" "=r")
4873 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4874 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4876 [(set_attr "type" "compare")])
4878 (define_insn "*cmp_ccx_arith_op_set"
4881 (match_operator:DI 3 "cc_arith_operator"
4882 [(match_operand:DI 1 "arith_operand" "%r")
4883 (match_operand:DI 2 "arith_operand" "rI")])
4885 (set (match_operand:DI 0 "register_operand" "=r")
4886 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4887 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4889 [(set_attr "type" "compare")])
4891 (define_insn "*cmp_cc_xor_not"
4894 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4895 (match_operand:SI 1 "arith_operand" "rI")))
4898 "xnorcc\t%r0, %1, %%g0"
4899 [(set_attr "type" "compare")])
4901 (define_insn "*cmp_ccx_xor_not"
4904 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4905 (match_operand:DI 1 "arith_operand" "rI")))
4908 "xnorcc\t%r0, %1, %%g0"
4909 [(set_attr "type" "compare")])
4911 (define_insn "*cmp_cc_xor_not_set"
4914 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4915 (match_operand:SI 2 "arith_operand" "rI")))
4917 (set (match_operand:SI 0 "register_operand" "=r")
4918 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4920 "xnorcc\t%r1, %2, %0"
4921 [(set_attr "type" "compare")])
4923 (define_insn "*cmp_ccx_xor_not_set"
4926 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4927 (match_operand:DI 2 "arith_operand" "rI")))
4929 (set (match_operand:DI 0 "register_operand" "=r")
4930 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4932 "xnorcc\t%r1, %2, %0"
4933 [(set_attr "type" "compare")])
4935 (define_insn "*cmp_cc_arith_op_not"
4938 (match_operator:SI 2 "cc_arith_not_operator"
4939 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4940 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4943 "%B2cc\t%r1, %0, %%g0"
4944 [(set_attr "type" "compare")])
4946 (define_insn "*cmp_ccx_arith_op_not"
4949 (match_operator:DI 2 "cc_arith_not_operator"
4950 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
4951 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
4954 "%B2cc\t%r1, %0, %%g0"
4955 [(set_attr "type" "compare")])
4957 (define_insn "*cmp_cc_arith_op_not_set"
4960 (match_operator:SI 3 "cc_arith_not_operator"
4961 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4962 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
4964 (set (match_operand:SI 0 "register_operand" "=r")
4965 (match_operator:SI 4 "cc_arith_not_operator"
4966 [(not:SI (match_dup 1)) (match_dup 2)]))]
4967 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4968 "%B3cc\t%r2, %1, %0"
4969 [(set_attr "type" "compare")])
4971 (define_insn "*cmp_ccx_arith_op_not_set"
4974 (match_operator:DI 3 "cc_arith_not_operator"
4975 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
4976 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
4978 (set (match_operand:DI 0 "register_operand" "=r")
4979 (match_operator:DI 4 "cc_arith_not_operator"
4980 [(not:DI (match_dup 1)) (match_dup 2)]))]
4981 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4982 "%B3cc\t%r2, %1, %0"
4983 [(set_attr "type" "compare")])
4985 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4986 ;; does not know how to make it work for constants.
4988 (define_expand "negdi2"
4989 [(set (match_operand:DI 0 "register_operand" "=r")
4990 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4993 if (! TARGET_ARCH64)
4995 emit_insn (gen_rtx_PARALLEL
4998 gen_rtx_SET (VOIDmode, operand0,
4999 gen_rtx_NEG (DImode, operand1)),
5000 gen_rtx_CLOBBER (VOIDmode,
5001 gen_rtx_REG (CCmode,
5007 (define_insn_and_split "*negdi2_sp32"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5010 (clobber (reg:CC 100))]
5013 "&& reload_completed"
5014 [(parallel [(set (reg:CC_NOOV 100)
5015 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5017 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5018 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5019 (ltu:SI (reg:CC 100) (const_int 0))))]
5020 "operands[2] = gen_highpart (SImode, operands[0]);
5021 operands[3] = gen_highpart (SImode, operands[1]);
5022 operands[4] = gen_lowpart (SImode, operands[0]);
5023 operands[5] = gen_lowpart (SImode, operands[1]);"
5024 [(set_attr "length" "2")])
5026 (define_insn "*negdi2_sp64"
5027 [(set (match_operand:DI 0 "register_operand" "=r")
5028 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5030 "sub\t%%g0, %1, %0")
5032 (define_insn "negsi2"
5033 [(set (match_operand:SI 0 "register_operand" "=r")
5034 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5036 "sub\t%%g0, %1, %0")
5038 (define_insn "*cmp_cc_neg"
5039 [(set (reg:CC_NOOV 100)
5040 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5043 "subcc\t%%g0, %0, %%g0"
5044 [(set_attr "type" "compare")])
5046 (define_insn "*cmp_ccx_neg"
5047 [(set (reg:CCX_NOOV 100)
5048 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5051 "subcc\t%%g0, %0, %%g0"
5052 [(set_attr "type" "compare")])
5054 (define_insn "*cmp_cc_set_neg"
5055 [(set (reg:CC_NOOV 100)
5056 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5058 (set (match_operand:SI 0 "register_operand" "=r")
5059 (neg:SI (match_dup 1)))]
5061 "subcc\t%%g0, %1, %0"
5062 [(set_attr "type" "compare")])
5064 (define_insn "*cmp_ccx_set_neg"
5065 [(set (reg:CCX_NOOV 100)
5066 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5068 (set (match_operand:DI 0 "register_operand" "=r")
5069 (neg:DI (match_dup 1)))]
5071 "subcc\t%%g0, %1, %0"
5072 [(set_attr "type" "compare")])
5074 ;; We cannot use the "not" pseudo insn because the Sun assembler
5075 ;; does not know how to make it work for constants.
5076 (define_expand "one_cmpl<V64I:mode>2"
5077 [(set (match_operand:V64I 0 "register_operand" "")
5078 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5082 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5083 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5084 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5089 "&& reload_completed
5090 && ((GET_CODE (operands[0]) == REG
5091 && REGNO (operands[0]) < 32)
5092 || (GET_CODE (operands[0]) == SUBREG
5093 && GET_CODE (SUBREG_REG (operands[0])) == REG
5094 && REGNO (SUBREG_REG (operands[0])) < 32))"
5095 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5096 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5097 "operands[2] = gen_highpart (SImode, operands[0]);
5098 operands[3] = gen_highpart (SImode, operands[1]);
5099 operands[4] = gen_lowpart (SImode, operands[0]);
5100 operands[5] = gen_lowpart (SImode, operands[1]);"
5101 [(set_attr "type" "*,fga")
5102 (set_attr "length" "2,*")
5103 (set_attr "fptype" "*,double")])
5105 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5106 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5107 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5112 [(set_attr "type" "*,fga")
5113 (set_attr "fptype" "*,double")])
5115 (define_insn "one_cmpl<V32I:mode>2"
5116 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5117 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5122 [(set_attr "type" "*,fga")
5123 (set_attr "fptype" "*,single")])
5125 (define_insn "*cmp_cc_not"
5127 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5130 "xnorcc\t%%g0, %0, %%g0"
5131 [(set_attr "type" "compare")])
5133 (define_insn "*cmp_ccx_not"
5135 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5138 "xnorcc\t%%g0, %0, %%g0"
5139 [(set_attr "type" "compare")])
5141 (define_insn "*cmp_cc_set_not"
5143 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5145 (set (match_operand:SI 0 "register_operand" "=r")
5146 (not:SI (match_dup 1)))]
5148 "xnorcc\t%%g0, %1, %0"
5149 [(set_attr "type" "compare")])
5151 (define_insn "*cmp_ccx_set_not"
5153 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5155 (set (match_operand:DI 0 "register_operand" "=r")
5156 (not:DI (match_dup 1)))]
5158 "xnorcc\t%%g0, %1, %0"
5159 [(set_attr "type" "compare")])
5161 (define_insn "*cmp_cc_set"
5162 [(set (match_operand:SI 0 "register_operand" "=r")
5163 (match_operand:SI 1 "register_operand" "r"))
5165 (compare:CC (match_dup 1)
5169 [(set_attr "type" "compare")])
5171 (define_insn "*cmp_ccx_set64"
5172 [(set (match_operand:DI 0 "register_operand" "=r")
5173 (match_operand:DI 1 "register_operand" "r"))
5175 (compare:CCX (match_dup 1)
5179 [(set_attr "type" "compare")])
5182 ;; Floating point arithmetic instructions.
5184 (define_expand "addtf3"
5185 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5186 (plus:TF (match_operand:TF 1 "general_operand" "")
5187 (match_operand:TF 2 "general_operand" "")))]
5188 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5189 "emit_tfmode_binop (PLUS, operands); DONE;")
5191 (define_insn "*addtf3_hq"
5192 [(set (match_operand:TF 0 "register_operand" "=e")
5193 (plus:TF (match_operand:TF 1 "register_operand" "e")
5194 (match_operand:TF 2 "register_operand" "e")))]
5195 "TARGET_FPU && TARGET_HARD_QUAD"
5197 [(set_attr "type" "fp")])
5199 (define_insn "adddf3"
5200 [(set (match_operand:DF 0 "register_operand" "=e")
5201 (plus:DF (match_operand:DF 1 "register_operand" "e")
5202 (match_operand:DF 2 "register_operand" "e")))]
5205 [(set_attr "type" "fp")
5206 (set_attr "fptype" "double")])
5208 (define_insn "addsf3"
5209 [(set (match_operand:SF 0 "register_operand" "=f")
5210 (plus:SF (match_operand:SF 1 "register_operand" "f")
5211 (match_operand:SF 2 "register_operand" "f")))]
5214 [(set_attr "type" "fp")])
5216 (define_expand "subtf3"
5217 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5218 (minus:TF (match_operand:TF 1 "general_operand" "")
5219 (match_operand:TF 2 "general_operand" "")))]
5220 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5221 "emit_tfmode_binop (MINUS, operands); DONE;")
5223 (define_insn "*subtf3_hq"
5224 [(set (match_operand:TF 0 "register_operand" "=e")
5225 (minus:TF (match_operand:TF 1 "register_operand" "e")
5226 (match_operand:TF 2 "register_operand" "e")))]
5227 "TARGET_FPU && TARGET_HARD_QUAD"
5229 [(set_attr "type" "fp")])
5231 (define_insn "subdf3"
5232 [(set (match_operand:DF 0 "register_operand" "=e")
5233 (minus:DF (match_operand:DF 1 "register_operand" "e")
5234 (match_operand:DF 2 "register_operand" "e")))]
5237 [(set_attr "type" "fp")
5238 (set_attr "fptype" "double")])
5240 (define_insn "subsf3"
5241 [(set (match_operand:SF 0 "register_operand" "=f")
5242 (minus:SF (match_operand:SF 1 "register_operand" "f")
5243 (match_operand:SF 2 "register_operand" "f")))]
5246 [(set_attr "type" "fp")])
5248 (define_expand "multf3"
5249 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5250 (mult:TF (match_operand:TF 1 "general_operand" "")
5251 (match_operand:TF 2 "general_operand" "")))]
5252 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5253 "emit_tfmode_binop (MULT, operands); DONE;")
5255 (define_insn "*multf3_hq"
5256 [(set (match_operand:TF 0 "register_operand" "=e")
5257 (mult:TF (match_operand:TF 1 "register_operand" "e")
5258 (match_operand:TF 2 "register_operand" "e")))]
5259 "TARGET_FPU && TARGET_HARD_QUAD"
5261 [(set_attr "type" "fpmul")])
5263 (define_insn "muldf3"
5264 [(set (match_operand:DF 0 "register_operand" "=e")
5265 (mult:DF (match_operand:DF 1 "register_operand" "e")
5266 (match_operand:DF 2 "register_operand" "e")))]
5269 [(set_attr "type" "fpmul")
5270 (set_attr "fptype" "double")])
5272 (define_insn "mulsf3"
5273 [(set (match_operand:SF 0 "register_operand" "=f")
5274 (mult:SF (match_operand:SF 1 "register_operand" "f")
5275 (match_operand:SF 2 "register_operand" "f")))]
5278 [(set_attr "type" "fpmul")])
5280 (define_insn "*muldf3_extend"
5281 [(set (match_operand:DF 0 "register_operand" "=e")
5282 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5283 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5284 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5285 "fsmuld\t%1, %2, %0"
5286 [(set_attr "type" "fpmul")
5287 (set_attr "fptype" "double")])
5289 (define_insn "*multf3_extend"
5290 [(set (match_operand:TF 0 "register_operand" "=e")
5291 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5292 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5293 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5294 "fdmulq\t%1, %2, %0"
5295 [(set_attr "type" "fpmul")])
5297 (define_expand "divtf3"
5298 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5299 (div:TF (match_operand:TF 1 "general_operand" "")
5300 (match_operand:TF 2 "general_operand" "")))]
5301 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5302 "emit_tfmode_binop (DIV, operands); DONE;")
5304 ;; don't have timing for quad-prec. divide.
5305 (define_insn "*divtf3_hq"
5306 [(set (match_operand:TF 0 "register_operand" "=e")
5307 (div:TF (match_operand:TF 1 "register_operand" "e")
5308 (match_operand:TF 2 "register_operand" "e")))]
5309 "TARGET_FPU && TARGET_HARD_QUAD"
5311 [(set_attr "type" "fpdivd")])
5313 (define_insn "divdf3"
5314 [(set (match_operand:DF 0 "register_operand" "=e")
5315 (div:DF (match_operand:DF 1 "register_operand" "e")
5316 (match_operand:DF 2 "register_operand" "e")))]
5319 [(set_attr "type" "fpdivd")
5320 (set_attr "fptype" "double")])
5322 (define_insn "divsf3"
5323 [(set (match_operand:SF 0 "register_operand" "=f")
5324 (div:SF (match_operand:SF 1 "register_operand" "f")
5325 (match_operand:SF 2 "register_operand" "f")))]
5328 [(set_attr "type" "fpdivs")])
5330 (define_expand "negtf2"
5331 [(set (match_operand:TF 0 "register_operand" "=e,e")
5332 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5336 (define_insn_and_split "*negtf2_notv9"
5337 [(set (match_operand:TF 0 "register_operand" "=e,e")
5338 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5339 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5345 "&& reload_completed
5346 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5347 [(set (match_dup 2) (neg:SF (match_dup 3)))
5348 (set (match_dup 4) (match_dup 5))
5349 (set (match_dup 6) (match_dup 7))]
5350 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5351 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5352 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5353 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5354 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5355 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5356 [(set_attr "type" "fpmove,*")
5357 (set_attr "length" "*,2")])
5359 (define_insn_and_split "*negtf2_v9"
5360 [(set (match_operand:TF 0 "register_operand" "=e,e")
5361 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5362 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5363 "TARGET_FPU && TARGET_V9"
5367 "&& reload_completed
5368 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5369 [(set (match_dup 2) (neg:DF (match_dup 3)))
5370 (set (match_dup 4) (match_dup 5))]
5371 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5372 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5373 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5374 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5375 [(set_attr "type" "fpmove,*")
5376 (set_attr "length" "*,2")
5377 (set_attr "fptype" "double")])
5379 (define_expand "negdf2"
5380 [(set (match_operand:DF 0 "register_operand" "")
5381 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5385 (define_insn_and_split "*negdf2_notv9"
5386 [(set (match_operand:DF 0 "register_operand" "=e,e")
5387 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5388 "TARGET_FPU && ! TARGET_V9"
5392 "&& reload_completed
5393 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5394 [(set (match_dup 2) (neg:SF (match_dup 3)))
5395 (set (match_dup 4) (match_dup 5))]
5396 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5397 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5398 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5399 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5400 [(set_attr "type" "fpmove,*")
5401 (set_attr "length" "*,2")])
5403 (define_insn "*negdf2_v9"
5404 [(set (match_operand:DF 0 "register_operand" "=e")
5405 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5406 "TARGET_FPU && TARGET_V9"
5408 [(set_attr "type" "fpmove")
5409 (set_attr "fptype" "double")])
5411 (define_insn "negsf2"
5412 [(set (match_operand:SF 0 "register_operand" "=f")
5413 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5416 [(set_attr "type" "fpmove")])
5418 (define_expand "abstf2"
5419 [(set (match_operand:TF 0 "register_operand" "")
5420 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5424 (define_insn_and_split "*abstf2_notv9"
5425 [(set (match_operand:TF 0 "register_operand" "=e,e")
5426 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5427 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5428 "TARGET_FPU && ! TARGET_V9"
5432 "&& reload_completed
5433 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5434 [(set (match_dup 2) (abs:SF (match_dup 3)))
5435 (set (match_dup 4) (match_dup 5))
5436 (set (match_dup 6) (match_dup 7))]
5437 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5438 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5439 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5440 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5441 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5442 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5443 [(set_attr "type" "fpmove,*")
5444 (set_attr "length" "*,2")])
5446 (define_insn "*abstf2_hq_v9"
5447 [(set (match_operand:TF 0 "register_operand" "=e,e")
5448 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5449 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5453 [(set_attr "type" "fpmove")
5454 (set_attr "fptype" "double,*")])
5456 (define_insn_and_split "*abstf2_v9"
5457 [(set (match_operand:TF 0 "register_operand" "=e,e")
5458 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5459 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5463 "&& reload_completed
5464 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5465 [(set (match_dup 2) (abs:DF (match_dup 3)))
5466 (set (match_dup 4) (match_dup 5))]
5467 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5468 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5469 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5470 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5471 [(set_attr "type" "fpmove,*")
5472 (set_attr "length" "*,2")
5473 (set_attr "fptype" "double,*")])
5475 (define_expand "absdf2"
5476 [(set (match_operand:DF 0 "register_operand" "")
5477 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5481 (define_insn_and_split "*absdf2_notv9"
5482 [(set (match_operand:DF 0 "register_operand" "=e,e")
5483 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5484 "TARGET_FPU && ! TARGET_V9"
5488 "&& reload_completed
5489 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5490 [(set (match_dup 2) (abs:SF (match_dup 3)))
5491 (set (match_dup 4) (match_dup 5))]
5492 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5493 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5494 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5495 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5496 [(set_attr "type" "fpmove,*")
5497 (set_attr "length" "*,2")])
5499 (define_insn "*absdf2_v9"
5500 [(set (match_operand:DF 0 "register_operand" "=e")
5501 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5502 "TARGET_FPU && TARGET_V9"
5504 [(set_attr "type" "fpmove")
5505 (set_attr "fptype" "double")])
5507 (define_insn "abssf2"
5508 [(set (match_operand:SF 0 "register_operand" "=f")
5509 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5512 [(set_attr "type" "fpmove")])
5514 (define_expand "sqrttf2"
5515 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5516 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5517 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5518 "emit_tfmode_unop (SQRT, operands); DONE;")
5520 (define_insn "*sqrttf2_hq"
5521 [(set (match_operand:TF 0 "register_operand" "=e")
5522 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5523 "TARGET_FPU && TARGET_HARD_QUAD"
5525 [(set_attr "type" "fpsqrtd")])
5527 (define_insn "sqrtdf2"
5528 [(set (match_operand:DF 0 "register_operand" "=e")
5529 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5532 [(set_attr "type" "fpsqrtd")
5533 (set_attr "fptype" "double")])
5535 (define_insn "sqrtsf2"
5536 [(set (match_operand:SF 0 "register_operand" "=f")
5537 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5540 [(set_attr "type" "fpsqrts")])
5543 ;; Arithmetic shift instructions.
5545 (define_insn "ashlsi3"
5546 [(set (match_operand:SI 0 "register_operand" "=r")
5547 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5548 (match_operand:SI 2 "arith_operand" "rI")))]
5551 if (GET_CODE (operands[2]) == CONST_INT)
5552 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5553 return "sll\t%1, %2, %0";
5556 (if_then_else (match_operand 2 "const_one_operand" "")
5557 (const_string "ialu") (const_string "shift")))])
5559 (define_expand "ashldi3"
5560 [(set (match_operand:DI 0 "register_operand" "=r")
5561 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5562 (match_operand:SI 2 "arith_operand" "rI")))]
5563 "TARGET_ARCH64 || TARGET_V8PLUS"
5565 if (! TARGET_ARCH64)
5567 if (GET_CODE (operands[2]) == CONST_INT)
5569 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5574 (define_insn "*ashldi3_sp64"
5575 [(set (match_operand:DI 0 "register_operand" "=r")
5576 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5577 (match_operand:SI 2 "arith_operand" "rI")))]
5580 if (GET_CODE (operands[2]) == CONST_INT)
5581 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5582 return "sllx\t%1, %2, %0";
5585 (if_then_else (match_operand 2 "const_one_operand" "")
5586 (const_string "ialu") (const_string "shift")))])
5589 (define_insn "ashldi3_v8plus"
5590 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5591 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5592 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5593 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5595 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5596 [(set_attr "type" "multi")
5597 (set_attr "length" "5,5,6")])
5599 ;; Optimize (1LL<<x)-1
5600 ;; XXX this also needs to be fixed to handle equal subregs
5601 ;; XXX first before we could re-enable it.
5603 ; [(set (match_operand:DI 0 "register_operand" "=h")
5604 ; (plus:DI (ashift:DI (const_int 1)
5605 ; (match_operand:SI 1 "arith_operand" "rI"))
5607 ; "0 && TARGET_V8PLUS"
5609 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5610 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5611 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5613 ; [(set_attr "type" "multi")
5614 ; (set_attr "length" "4")])
5616 (define_insn "*cmp_cc_ashift_1"
5617 [(set (reg:CC_NOOV 100)
5618 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5622 "addcc\t%0, %0, %%g0"
5623 [(set_attr "type" "compare")])
5625 (define_insn "*cmp_cc_set_ashift_1"
5626 [(set (reg:CC_NOOV 100)
5627 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5630 (set (match_operand:SI 0 "register_operand" "=r")
5631 (ashift:SI (match_dup 1) (const_int 1)))]
5634 [(set_attr "type" "compare")])
5636 (define_insn "ashrsi3"
5637 [(set (match_operand:SI 0 "register_operand" "=r")
5638 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5639 (match_operand:SI 2 "arith_operand" "rI")))]
5642 if (GET_CODE (operands[2]) == CONST_INT)
5643 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5644 return "sra\t%1, %2, %0";
5646 [(set_attr "type" "shift")])
5648 (define_insn "*ashrsi3_extend"
5649 [(set (match_operand:DI 0 "register_operand" "=r")
5650 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5651 (match_operand:SI 2 "arith_operand" "r"))))]
5654 [(set_attr "type" "shift")])
5656 ;; This handles the case as above, but with constant shift instead of
5657 ;; register. Combiner "simplifies" it for us a little bit though.
5658 (define_insn "*ashrsi3_extend2"
5659 [(set (match_operand:DI 0 "register_operand" "=r")
5660 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5662 (match_operand:SI 2 "small_int_operand" "I")))]
5663 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5665 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5666 return "sra\t%1, %2, %0";
5668 [(set_attr "type" "shift")])
5670 (define_expand "ashrdi3"
5671 [(set (match_operand:DI 0 "register_operand" "=r")
5672 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5673 (match_operand:SI 2 "arith_operand" "rI")))]
5674 "TARGET_ARCH64 || TARGET_V8PLUS"
5676 if (! TARGET_ARCH64)
5678 if (GET_CODE (operands[2]) == CONST_INT)
5679 FAIL; /* prefer generic code in this case */
5680 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5685 (define_insn "*ashrdi3_sp64"
5686 [(set (match_operand:DI 0 "register_operand" "=r")
5687 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5688 (match_operand:SI 2 "arith_operand" "rI")))]
5692 if (GET_CODE (operands[2]) == CONST_INT)
5693 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5694 return "srax\t%1, %2, %0";
5696 [(set_attr "type" "shift")])
5699 (define_insn "ashrdi3_v8plus"
5700 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5701 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5702 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5703 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5705 "* return output_v8plus_shift (operands, insn, \"srax\");"
5706 [(set_attr "type" "multi")
5707 (set_attr "length" "5,5,6")])
5709 (define_insn "lshrsi3"
5710 [(set (match_operand:SI 0 "register_operand" "=r")
5711 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5712 (match_operand:SI 2 "arith_operand" "rI")))]
5715 if (GET_CODE (operands[2]) == CONST_INT)
5716 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5717 return "srl\t%1, %2, %0";
5719 [(set_attr "type" "shift")])
5721 ;; This handles the case where
5722 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5723 ;; but combiner "simplifies" it for us.
5724 (define_insn "*lshrsi3_extend"
5725 [(set (match_operand:DI 0 "register_operand" "=r")
5726 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5727 (match_operand:SI 2 "arith_operand" "r")) 0)
5728 (match_operand 3 "const_int_operand" "")))]
5729 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5731 [(set_attr "type" "shift")])
5733 ;; This handles the case where
5734 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5735 ;; but combiner "simplifies" it for us.
5736 (define_insn "*lshrsi3_extend2"
5737 [(set (match_operand:DI 0 "register_operand" "=r")
5738 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5739 (match_operand 2 "small_int_operand" "I")
5741 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5743 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5744 return "srl\t%1, %2, %0";
5746 [(set_attr "type" "shift")])
5748 (define_expand "lshrdi3"
5749 [(set (match_operand:DI 0 "register_operand" "=r")
5750 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5751 (match_operand:SI 2 "arith_operand" "rI")))]
5752 "TARGET_ARCH64 || TARGET_V8PLUS"
5754 if (! TARGET_ARCH64)
5756 if (GET_CODE (operands[2]) == CONST_INT)
5758 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5763 (define_insn "*lshrdi3_sp64"
5764 [(set (match_operand:DI 0 "register_operand" "=r")
5765 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5766 (match_operand:SI 2 "arith_operand" "rI")))]
5769 if (GET_CODE (operands[2]) == CONST_INT)
5770 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5771 return "srlx\t%1, %2, %0";
5773 [(set_attr "type" "shift")])
5776 (define_insn "lshrdi3_v8plus"
5777 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5778 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5779 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5780 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5782 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5783 [(set_attr "type" "multi")
5784 (set_attr "length" "5,5,6")])
5787 [(set (match_operand:SI 0 "register_operand" "=r")
5788 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5790 (match_operand:SI 2 "small_int_operand" "I")))]
5791 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5793 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5794 return "srax\t%1, %2, %0";
5796 [(set_attr "type" "shift")])
5799 [(set (match_operand:SI 0 "register_operand" "=r")
5800 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5802 (match_operand:SI 2 "small_int_operand" "I")))]
5803 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5805 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5806 return "srlx\t%1, %2, %0";
5808 [(set_attr "type" "shift")])
5811 [(set (match_operand:SI 0 "register_operand" "=r")
5812 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:SI 2 "small_int_operand" "I")) 4)
5814 (match_operand:SI 3 "small_int_operand" "I")))]
5816 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5817 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5818 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5820 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5822 return "srax\t%1, %2, %0";
5824 [(set_attr "type" "shift")])
5827 [(set (match_operand:SI 0 "register_operand" "=r")
5828 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5829 (match_operand:SI 2 "small_int_operand" "I")) 4)
5830 (match_operand:SI 3 "small_int_operand" "I")))]
5832 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5833 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5834 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5836 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5838 return "srlx\t%1, %2, %0";
5840 [(set_attr "type" "shift")])
5843 ;; Unconditional and other jump instructions.
5846 [(set (pc) (label_ref (match_operand 0 "" "")))]
5848 "* return output_ubranch (operands[0], 0, insn);"
5849 [(set_attr "type" "uncond_branch")])
5851 (define_expand "tablejump"
5852 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5853 (use (label_ref (match_operand 1 "" "")))])]
5856 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5858 /* In pic mode, our address differences are against the base of the
5859 table. Add that base value back in; CSE ought to be able to combine
5860 the two address loads. */
5864 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5866 if (CASE_VECTOR_MODE != Pmode)
5867 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5868 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5869 operands[0] = memory_address (Pmode, tmp);
5873 (define_insn "*tablejump_sp32"
5874 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5875 (use (label_ref (match_operand 1 "" "")))]
5878 [(set_attr "type" "uncond_branch")])
5880 (define_insn "*tablejump_sp64"
5881 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5882 (use (label_ref (match_operand 1 "" "")))]
5885 [(set_attr "type" "uncond_branch")])
5888 ;; Jump to subroutine instructions.
5890 (define_expand "call"
5891 ;; Note that this expression is not used for generating RTL.
5892 ;; All the RTL is generated explicitly below.
5893 [(call (match_operand 0 "call_operand" "")
5894 (match_operand 3 "" "i"))]
5895 ;; operands[2] is next_arg_register
5896 ;; operands[3] is struct_value_size_rtx.
5901 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5903 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5905 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5907 /* This is really a PIC sequence. We want to represent
5908 it as a funny jump so its delay slots can be filled.
5910 ??? But if this really *is* a CALL, will not it clobber the
5911 call-clobbered registers? We lose this if it is a JUMP_INSN.
5912 Why cannot we have delay slots filled if it were a CALL? */
5914 /* We accept negative sizes for untyped calls. */
5915 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5920 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5922 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5928 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5929 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5933 fn_rtx = operands[0];
5935 /* We accept negative sizes for untyped calls. */
5936 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5937 sparc_emit_call_insn
5940 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5942 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
5945 sparc_emit_call_insn
5948 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5949 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
5957 ;; We can't use the same pattern for these two insns, because then registers
5958 ;; in the address may not be properly reloaded.
5960 (define_insn "*call_address_sp32"
5961 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5962 (match_operand 1 "" ""))
5963 (clobber (reg:SI 15))]
5964 ;;- Do not use operand 1 for most machines.
5967 [(set_attr "type" "call")])
5969 (define_insn "*call_symbolic_sp32"
5970 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5971 (match_operand 1 "" ""))
5972 (clobber (reg:SI 15))]
5973 ;;- Do not use operand 1 for most machines.
5976 [(set_attr "type" "call")])
5978 (define_insn "*call_address_sp64"
5979 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
5980 (match_operand 1 "" ""))
5981 (clobber (reg:DI 15))]
5982 ;;- Do not use operand 1 for most machines.
5985 [(set_attr "type" "call")])
5987 (define_insn "*call_symbolic_sp64"
5988 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
5989 (match_operand 1 "" ""))
5990 (clobber (reg:DI 15))]
5991 ;;- Do not use operand 1 for most machines.
5994 [(set_attr "type" "call")])
5996 ;; This is a call that wants a structure value.
5997 ;; There is no such critter for v9 (??? we may need one anyway).
5998 (define_insn "*call_address_struct_value_sp32"
5999 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6000 (match_operand 1 "" ""))
6001 (match_operand 2 "immediate_operand" "")
6002 (clobber (reg:SI 15))]
6003 ;;- Do not use operand 1 for most machines.
6004 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6006 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6007 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6009 [(set_attr "type" "call_no_delay_slot")
6010 (set_attr "length" "3")])
6012 ;; This is a call that wants a structure value.
6013 ;; There is no such critter for v9 (??? we may need one anyway).
6014 (define_insn "*call_symbolic_struct_value_sp32"
6015 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6016 (match_operand 1 "" ""))
6017 (match_operand 2 "immediate_operand" "")
6018 (clobber (reg:SI 15))]
6019 ;;- Do not use operand 1 for most machines.
6020 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6022 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6023 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6025 [(set_attr "type" "call_no_delay_slot")
6026 (set_attr "length" "3")])
6028 ;; This is a call that may want a structure value. This is used for
6030 (define_insn "*call_address_untyped_struct_value_sp32"
6031 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6032 (match_operand 1 "" ""))
6033 (match_operand 2 "immediate_operand" "")
6034 (clobber (reg:SI 15))]
6035 ;;- Do not use operand 1 for most machines.
6036 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6037 "call\t%a0, %1\n\t nop\n\tnop"
6038 [(set_attr "type" "call_no_delay_slot")
6039 (set_attr "length" "3")])
6041 ;; This is a call that may want a structure value. This is used for
6043 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6044 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6045 (match_operand 1 "" ""))
6046 (match_operand 2 "immediate_operand" "")
6047 (clobber (reg:SI 15))]
6048 ;;- Do not use operand 1 for most machines.
6049 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6050 "call\t%a0, %1\n\t nop\n\tnop"
6051 [(set_attr "type" "call_no_delay_slot")
6052 (set_attr "length" "3")])
6054 (define_expand "call_value"
6055 ;; Note that this expression is not used for generating RTL.
6056 ;; All the RTL is generated explicitly below.
6057 [(set (match_operand 0 "register_operand" "=rf")
6058 (call (match_operand 1 "" "")
6059 (match_operand 4 "" "")))]
6060 ;; operand 2 is stack_size_rtx
6061 ;; operand 3 is next_arg_register
6067 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6069 fn_rtx = operands[1];
6072 gen_rtx_SET (VOIDmode, operands[0],
6073 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6074 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6076 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6081 (define_insn "*call_value_address_sp32"
6082 [(set (match_operand 0 "" "=rf")
6083 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6084 (match_operand 2 "" "")))
6085 (clobber (reg:SI 15))]
6086 ;;- Do not use operand 2 for most machines.
6089 [(set_attr "type" "call")])
6091 (define_insn "*call_value_symbolic_sp32"
6092 [(set (match_operand 0 "" "=rf")
6093 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6094 (match_operand 2 "" "")))
6095 (clobber (reg:SI 15))]
6096 ;;- Do not use operand 2 for most machines.
6099 [(set_attr "type" "call")])
6101 (define_insn "*call_value_address_sp64"
6102 [(set (match_operand 0 "" "")
6103 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6104 (match_operand 2 "" "")))
6105 (clobber (reg:DI 15))]
6106 ;;- Do not use operand 2 for most machines.
6109 [(set_attr "type" "call")])
6111 (define_insn "*call_value_symbolic_sp64"
6112 [(set (match_operand 0 "" "")
6113 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6114 (match_operand 2 "" "")))
6115 (clobber (reg:DI 15))]
6116 ;;- Do not use operand 2 for most machines.
6119 [(set_attr "type" "call")])
6121 (define_expand "untyped_call"
6122 [(parallel [(call (match_operand 0 "" "")
6124 (match_operand:BLK 1 "memory_operand" "")
6125 (match_operand 2 "" "")])]
6128 rtx valreg1 = gen_rtx_REG (DImode, 8);
6129 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6130 rtx result = operands[1];
6132 /* Pass constm1 to indicate that it may expect a structure value, but
6133 we don't know what size it is. */
6134 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6136 /* Save the function value registers. */
6137 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6138 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6141 /* The optimizer does not know that the call sets the function value
6142 registers we stored in the result block. We avoid problems by
6143 claiming that all hard registers are used and clobbered at this
6145 emit_insn (gen_blockage ());
6150 ;; Tail call instructions.
6152 (define_expand "sibcall"
6153 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6158 (define_insn "*sibcall_symbolic_sp32"
6159 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6160 (match_operand 1 "" ""))
6163 "* return output_sibcall(insn, operands[0]);"
6164 [(set_attr "type" "sibcall")])
6166 (define_insn "*sibcall_symbolic_sp64"
6167 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6168 (match_operand 1 "" ""))
6171 "* return output_sibcall(insn, operands[0]);"
6172 [(set_attr "type" "sibcall")])
6174 (define_expand "sibcall_value"
6175 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6176 (call (match_operand 1 "" "") (const_int 0)))
6181 (define_insn "*sibcall_value_symbolic_sp32"
6182 [(set (match_operand 0 "" "=rf")
6183 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6184 (match_operand 2 "" "")))
6187 "* return output_sibcall(insn, operands[1]);"
6188 [(set_attr "type" "sibcall")])
6190 (define_insn "*sibcall_value_symbolic_sp64"
6191 [(set (match_operand 0 "" "")
6192 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6193 (match_operand 2 "" "")))
6196 "* return output_sibcall(insn, operands[1]);"
6197 [(set_attr "type" "sibcall")])
6200 ;; Special instructions.
6202 (define_expand "prologue"
6206 sparc_expand_prologue ();
6210 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6211 ;; backend automatically emits the required call frame debugging information
6212 ;; while it is parsing it. Therefore, the pattern should not be modified
6213 ;; without first studying the impact of the changes on the debug info.
6214 ;; [(set (%fp) (%sp))
6215 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6216 ;; (set (%i7) (%o7))]
6218 (define_insn "save_register_window<P:mode>"
6219 [(set (reg:P 30) (reg:P 14))
6220 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6221 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6222 (set (reg:P 31) (reg:P 15))]
6224 "save\t%%sp, %0, %%sp"
6225 [(set_attr "type" "savew")])
6227 (define_expand "epilogue"
6231 sparc_expand_epilogue ();
6234 (define_expand "sibcall_epilogue"
6238 sparc_expand_epilogue ();
6242 (define_expand "return"
6244 "sparc_can_use_return_insn_p ()"
6247 (define_insn "*return_internal"
6250 "* return output_return (insn);"
6251 [(set_attr "type" "return")
6252 (set (attr "length")
6253 (cond [(eq_attr "leaf_function" "true")
6254 (if_then_else (eq_attr "empty_delay_slot" "true")
6257 (eq_attr "calls_eh_return" "true")
6258 (if_then_else (eq_attr "delayed_branch" "true")
6259 (if_then_else (eq_attr "isa" "v9")
6262 (if_then_else (eq_attr "isa" "v9")
6265 (eq_attr "empty_delay_slot" "true")
6266 (if_then_else (eq_attr "delayed_branch" "true")
6271 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6272 ;; all of memory. This blocks insns from being moved across this point.
6274 (define_insn "blockage"
6275 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6278 [(set_attr "length" "0")])
6280 (define_expand "probe_stack"
6281 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6285 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6288 ;; Prepare to return any type including a structure value.
6290 (define_expand "untyped_return"
6291 [(match_operand:BLK 0 "memory_operand" "")
6292 (match_operand 1 "" "")]
6295 rtx valreg1 = gen_rtx_REG (DImode, 24);
6296 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6297 rtx result = operands[0];
6299 if (! TARGET_ARCH64)
6301 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6303 rtx value = gen_reg_rtx (SImode);
6305 /* Fetch the instruction where we will return to and see if it's an unimp
6306 instruction (the most significant 10 bits will be zero). If so,
6307 update the return address to skip the unimp instruction. */
6308 emit_move_insn (value,
6309 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6310 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6311 emit_insn (gen_update_return (rtnreg, value));
6314 /* Reload the function value registers. */
6315 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6316 emit_move_insn (valreg2,
6317 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6319 /* Put USE insns before the return. */
6323 /* Construct the return. */
6324 expand_naked_return ();
6329 ;; Adjust the return address conditionally. If the value of op1 is equal
6330 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6331 ;; This is technically *half* the check required by the 32-bit SPARC
6332 ;; psABI. This check only ensures that an "unimp" insn was written by
6333 ;; the caller, but doesn't check to see if the expected size matches
6334 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6335 ;; only used by the above code "untyped_return".
6337 (define_insn "update_return"
6338 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6339 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6342 if (flag_delayed_branch)
6343 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6345 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6347 [(set (attr "type") (const_string "multi"))
6348 (set (attr "length")
6349 (if_then_else (eq_attr "delayed_branch" "true")
6358 (define_expand "indirect_jump"
6359 [(set (pc) (match_operand 0 "address_operand" "p"))]
6363 (define_insn "*branch_sp32"
6364 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6367 [(set_attr "type" "uncond_branch")])
6369 (define_insn "*branch_sp64"
6370 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6373 [(set_attr "type" "uncond_branch")])
6375 (define_expand "nonlocal_goto"
6376 [(match_operand:SI 0 "general_operand" "")
6377 (match_operand:SI 1 "general_operand" "")
6378 (match_operand:SI 2 "general_operand" "")
6379 (match_operand:SI 3 "" "")]
6382 rtx lab = operands[1];
6383 rtx stack = operands[2];
6384 rtx fp = operands[3];
6387 /* Trap instruction to flush all the register windows. */
6388 emit_insn (gen_flush_register_windows ());
6390 /* Load the fp value for the containing fn into %fp. This is needed
6391 because STACK refers to %fp. Note that virtual register instantiation
6392 fails if the virtual %fp isn't set from a register. */
6393 if (GET_CODE (fp) != REG)
6394 fp = force_reg (Pmode, fp);
6395 emit_move_insn (virtual_stack_vars_rtx, fp);
6397 /* Find the containing function's current nonlocal goto handler,
6398 which will do any cleanups and then jump to the label. */
6399 labreg = gen_rtx_REG (Pmode, 8);
6400 emit_move_insn (labreg, lab);
6402 /* Restore %fp from stack pointer value for containing function.
6403 The restore insn that follows will move this to %sp,
6404 and reload the appropriate value into %fp. */
6405 emit_move_insn (hard_frame_pointer_rtx, stack);
6407 emit_use (stack_pointer_rtx);
6409 /* ??? The V9-specific version was disabled in rev 1.65. */
6410 emit_jump_insn (gen_goto_handler_and_restore (labreg));
6415 ;; Special trap insn to flush register windows.
6416 (define_insn "flush_register_windows"
6417 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6419 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6420 [(set_attr "type" "flushw")])
6422 (define_insn "goto_handler_and_restore"
6423 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6424 "GET_MODE (operands[0]) == Pmode"
6426 if (flag_delayed_branch)
6427 return "jmp\t%0\n\t restore";
6429 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6431 [(set (attr "type") (const_string "multi"))
6432 (set (attr "length")
6433 (if_then_else (eq_attr "delayed_branch" "true")
6437 ;; For __builtin_setjmp we need to flush register windows iff the function
6438 ;; calls alloca as well, because otherwise the register window might be
6439 ;; saved after %sp adjustment and thus setjmp would crash
6440 (define_expand "builtin_setjmp_setup"
6441 [(match_operand 0 "register_operand" "r")]
6444 emit_insn (gen_do_builtin_setjmp_setup ());
6448 (define_insn "do_builtin_setjmp_setup"
6449 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6452 if (!cfun->calls_alloca)
6456 fputs ("\tflushw\n", asm_out_file);
6458 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6459 TARGET_ARCH64 ? 'x' : 'w',
6460 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6461 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6462 TARGET_ARCH64 ? 'x' : 'w',
6463 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6464 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6465 TARGET_ARCH64 ? 'x' : 'w',
6466 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6469 [(set_attr "type" "multi")
6470 (set (attr "length")
6471 (cond [(eq_attr "calls_alloca" "false")
6473 (eq_attr "isa" "!v9")
6475 (eq_attr "pic" "true")
6476 (const_int 4)] (const_int 3)))])
6478 ;; Pattern for use after a setjmp to store FP and the return register
6479 ;; into the stack area.
6481 (define_expand "setjmp"
6487 mem = gen_rtx_MEM (Pmode,
6488 plus_constant (stack_pointer_rtx,
6489 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6490 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6492 mem = gen_rtx_MEM (Pmode,
6493 plus_constant (stack_pointer_rtx,
6494 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6495 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6499 ;; Special pattern for the FLUSH instruction.
6501 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6502 ; of the define_insn otherwise missing a mode. We make "flush", aka
6503 ; gen_flush, the default one since sparc_initialize_trampoline uses
6504 ; it on SImode mem values.
6506 (define_insn "flush"
6507 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6509 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6510 [(set_attr "type" "iflush")])
6512 (define_insn "flushdi"
6513 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6515 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6516 [(set_attr "type" "iflush")])
6519 ;; Find first set instructions.
6521 ;; The scan instruction searches from the most significant bit while ffs
6522 ;; searches from the least significant bit. The bit index and treatment of
6523 ;; zero also differ. It takes at least 7 instructions to get the proper
6524 ;; result. Here is an obvious 8 instruction sequence.
6527 (define_insn "ffssi2"
6528 [(set (match_operand:SI 0 "register_operand" "=&r")
6529 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6530 (clobber (match_scratch:SI 2 "=&r"))]
6531 "TARGET_SPARCLITE || TARGET_SPARCLET"
6533 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";
6535 [(set_attr "type" "multi")
6536 (set_attr "length" "8")])
6538 ;; ??? This should be a define expand, so that the extra instruction have
6539 ;; a chance of being optimized away.
6541 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6542 ;; does, but no one uses that and we don't have a switch for it.
6544 ;(define_insn "ffsdi2"
6545 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6546 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6547 ; (clobber (match_scratch:DI 2 "=&r"))]
6549 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6550 ; [(set_attr "type" "multi")
6551 ; (set_attr "length" "4")])
6555 ;; Peepholes go at the end.
6557 ;; Optimize consecutive loads or stores into ldd and std when possible.
6558 ;; The conditions in which we do this are very restricted and are
6559 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6562 [(set (match_operand:SI 0 "memory_operand" "")
6564 (set (match_operand:SI 1 "memory_operand" "")
6567 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6570 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6573 [(set (match_operand:SI 0 "memory_operand" "")
6575 (set (match_operand:SI 1 "memory_operand" "")
6578 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6581 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6584 [(set (match_operand:SI 0 "register_operand" "")
6585 (match_operand:SI 1 "memory_operand" ""))
6586 (set (match_operand:SI 2 "register_operand" "")
6587 (match_operand:SI 3 "memory_operand" ""))]
6588 "registers_ok_for_ldd_peep (operands[0], operands[2])
6589 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6592 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6593 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6596 [(set (match_operand:SI 0 "memory_operand" "")
6597 (match_operand:SI 1 "register_operand" ""))
6598 (set (match_operand:SI 2 "memory_operand" "")
6599 (match_operand:SI 3 "register_operand" ""))]
6600 "registers_ok_for_ldd_peep (operands[1], operands[3])
6601 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6604 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6605 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6608 [(set (match_operand:SF 0 "register_operand" "")
6609 (match_operand:SF 1 "memory_operand" ""))
6610 (set (match_operand:SF 2 "register_operand" "")
6611 (match_operand:SF 3 "memory_operand" ""))]
6612 "registers_ok_for_ldd_peep (operands[0], operands[2])
6613 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6616 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6617 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6620 [(set (match_operand:SF 0 "memory_operand" "")
6621 (match_operand:SF 1 "register_operand" ""))
6622 (set (match_operand:SF 2 "memory_operand" "")
6623 (match_operand:SF 3 "register_operand" ""))]
6624 "registers_ok_for_ldd_peep (operands[1], operands[3])
6625 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6628 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6629 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6632 [(set (match_operand:SI 0 "register_operand" "")
6633 (match_operand:SI 1 "memory_operand" ""))
6634 (set (match_operand:SI 2 "register_operand" "")
6635 (match_operand:SI 3 "memory_operand" ""))]
6636 "registers_ok_for_ldd_peep (operands[2], operands[0])
6637 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6640 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6641 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6644 [(set (match_operand:SI 0 "memory_operand" "")
6645 (match_operand:SI 1 "register_operand" ""))
6646 (set (match_operand:SI 2 "memory_operand" "")
6647 (match_operand:SI 3 "register_operand" ""))]
6648 "registers_ok_for_ldd_peep (operands[3], operands[1])
6649 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6652 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6653 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6657 [(set (match_operand:SF 0 "register_operand" "")
6658 (match_operand:SF 1 "memory_operand" ""))
6659 (set (match_operand:SF 2 "register_operand" "")
6660 (match_operand:SF 3 "memory_operand" ""))]
6661 "registers_ok_for_ldd_peep (operands[2], operands[0])
6662 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6665 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6666 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6669 [(set (match_operand:SF 0 "memory_operand" "")
6670 (match_operand:SF 1 "register_operand" ""))
6671 (set (match_operand:SF 2 "memory_operand" "")
6672 (match_operand:SF 3 "register_operand" ""))]
6673 "registers_ok_for_ldd_peep (operands[3], operands[1])
6674 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6677 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6678 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6680 ;; Optimize the case of following a reg-reg move with a test
6681 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6682 ;; This can result from a float to fix conversion.
6685 [(set (match_operand:SI 0 "register_operand" "")
6686 (match_operand:SI 1 "register_operand" ""))
6688 (compare:CC (match_operand:SI 2 "register_operand" "")
6690 "(rtx_equal_p (operands[2], operands[0])
6691 || rtx_equal_p (operands[2], operands[1]))
6692 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6693 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6694 [(parallel [(set (match_dup 0) (match_dup 1))
6696 (compare:CC (match_dup 1) (const_int 0)))])]
6700 [(set (match_operand:DI 0 "register_operand" "")
6701 (match_operand:DI 1 "register_operand" ""))
6703 (compare:CCX (match_operand:DI 2 "register_operand" "")
6706 && (rtx_equal_p (operands[2], operands[0])
6707 || rtx_equal_p (operands[2], operands[1]))
6708 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6709 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6710 [(parallel [(set (match_dup 0) (match_dup 1))
6712 (compare:CCX (match_dup 1) (const_int 0)))])]
6716 ;; Prefetch instructions.
6718 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6719 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6720 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6722 (define_expand "prefetch"
6723 [(match_operand 0 "address_operand" "")
6724 (match_operand 1 "const_int_operand" "")
6725 (match_operand 2 "const_int_operand" "")]
6729 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6731 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6735 (define_insn "prefetch_64"
6736 [(prefetch (match_operand:DI 0 "address_operand" "p")
6737 (match_operand:DI 1 "const_int_operand" "n")
6738 (match_operand:DI 2 "const_int_operand" "n"))]
6741 static const char * const prefetch_instr[2][2] = {
6743 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6744 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6747 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6748 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6751 int read_or_write = INTVAL (operands[1]);
6752 int locality = INTVAL (operands[2]);
6754 gcc_assert (read_or_write == 0 || read_or_write == 1);
6755 gcc_assert (locality >= 0 && locality < 4);
6756 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6758 [(set_attr "type" "load")])
6760 (define_insn "prefetch_32"
6761 [(prefetch (match_operand:SI 0 "address_operand" "p")
6762 (match_operand:SI 1 "const_int_operand" "n")
6763 (match_operand:SI 2 "const_int_operand" "n"))]
6766 static const char * const prefetch_instr[2][2] = {
6768 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6769 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6772 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6773 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6776 int read_or_write = INTVAL (operands[1]);
6777 int locality = INTVAL (operands[2]);
6779 gcc_assert (read_or_write == 0 || read_or_write == 1);
6780 gcc_assert (locality >= 0 && locality < 4);
6781 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6783 [(set_attr "type" "load")])
6786 ;; Trap instructions.
6789 [(trap_if (const_int 1) (const_int 5))]
6792 [(set_attr "type" "trap")])
6794 (define_expand "ctrapsi4"
6795 [(trap_if (match_operator 0 "noov_compare_operator"
6796 [(match_operand:SI 1 "compare_operand" "")
6797 (match_operand:SI 2 "arith_operand" "")])
6798 (match_operand 3 ""))]
6800 "operands[1] = gen_compare_reg (operands[0]);
6801 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6803 operands[2] = const0_rtx;")
6805 (define_expand "ctrapdi4"
6806 [(trap_if (match_operator 0 "noov_compare_operator"
6807 [(match_operand:DI 1 "compare_operand" "")
6808 (match_operand:DI 2 "arith_operand" "")])
6809 (match_operand 3 ""))]
6811 "operands[1] = gen_compare_reg (operands[0]);
6812 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6814 operands[2] = const0_rtx;")
6818 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6819 (match_operand:SI 1 "arith_operand" "rM"))]
6823 return "t%C0\t%%icc, %1";
6827 [(set_attr "type" "trap")])
6830 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6831 (match_operand:SI 1 "arith_operand" "rM"))]
6834 [(set_attr "type" "trap")])
6837 ;; TLS support instructions.
6839 (define_insn "tgd_hi22"
6840 [(set (match_operand:SI 0 "register_operand" "=r")
6841 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6844 "sethi\\t%%tgd_hi22(%a1), %0")
6846 (define_insn "tgd_lo10"
6847 [(set (match_operand:SI 0 "register_operand" "=r")
6848 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6849 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6852 "add\\t%1, %%tgd_lo10(%a2), %0")
6854 (define_insn "tgd_add32"
6855 [(set (match_operand:SI 0 "register_operand" "=r")
6856 (plus:SI (match_operand:SI 1 "register_operand" "r")
6857 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6858 (match_operand 3 "tgd_symbolic_operand" "")]
6860 "TARGET_TLS && TARGET_ARCH32"
6861 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6863 (define_insn "tgd_add64"
6864 [(set (match_operand:DI 0 "register_operand" "=r")
6865 (plus:DI (match_operand:DI 1 "register_operand" "r")
6866 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6867 (match_operand 3 "tgd_symbolic_operand" "")]
6869 "TARGET_TLS && TARGET_ARCH64"
6870 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6872 (define_insn "tgd_call32"
6873 [(set (match_operand 0 "register_operand" "=r")
6874 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6875 (match_operand 2 "tgd_symbolic_operand" "")]
6877 (match_operand 3 "" "")))
6878 (clobber (reg:SI 15))]
6879 "TARGET_TLS && TARGET_ARCH32"
6880 "call\t%a1, %%tgd_call(%a2)%#"
6881 [(set_attr "type" "call")])
6883 (define_insn "tgd_call64"
6884 [(set (match_operand 0 "register_operand" "=r")
6885 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6886 (match_operand 2 "tgd_symbolic_operand" "")]
6888 (match_operand 3 "" "")))
6889 (clobber (reg:DI 15))]
6890 "TARGET_TLS && TARGET_ARCH64"
6891 "call\t%a1, %%tgd_call(%a2)%#"
6892 [(set_attr "type" "call")])
6894 (define_insn "tldm_hi22"
6895 [(set (match_operand:SI 0 "register_operand" "=r")
6896 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6898 "sethi\\t%%tldm_hi22(%&), %0")
6900 (define_insn "tldm_lo10"
6901 [(set (match_operand:SI 0 "register_operand" "=r")
6902 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6903 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6905 "add\\t%1, %%tldm_lo10(%&), %0")
6907 (define_insn "tldm_add32"
6908 [(set (match_operand:SI 0 "register_operand" "=r")
6909 (plus:SI (match_operand:SI 1 "register_operand" "r")
6910 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6912 "TARGET_TLS && TARGET_ARCH32"
6913 "add\\t%1, %2, %0, %%tldm_add(%&)")
6915 (define_insn "tldm_add64"
6916 [(set (match_operand:DI 0 "register_operand" "=r")
6917 (plus:DI (match_operand:DI 1 "register_operand" "r")
6918 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6920 "TARGET_TLS && TARGET_ARCH64"
6921 "add\\t%1, %2, %0, %%tldm_add(%&)")
6923 (define_insn "tldm_call32"
6924 [(set (match_operand 0 "register_operand" "=r")
6925 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6927 (match_operand 2 "" "")))
6928 (clobber (reg:SI 15))]
6929 "TARGET_TLS && TARGET_ARCH32"
6930 "call\t%a1, %%tldm_call(%&)%#"
6931 [(set_attr "type" "call")])
6933 (define_insn "tldm_call64"
6934 [(set (match_operand 0 "register_operand" "=r")
6935 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
6937 (match_operand 2 "" "")))
6938 (clobber (reg:DI 15))]
6939 "TARGET_TLS && TARGET_ARCH64"
6940 "call\t%a1, %%tldm_call(%&)%#"
6941 [(set_attr "type" "call")])
6943 (define_insn "tldo_hix22"
6944 [(set (match_operand:SI 0 "register_operand" "=r")
6945 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
6948 "sethi\\t%%tldo_hix22(%a1), %0")
6950 (define_insn "tldo_lox10"
6951 [(set (match_operand:SI 0 "register_operand" "=r")
6952 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6953 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
6956 "xor\\t%1, %%tldo_lox10(%a2), %0")
6958 (define_insn "tldo_add32"
6959 [(set (match_operand:SI 0 "register_operand" "=r")
6960 (plus:SI (match_operand:SI 1 "register_operand" "r")
6961 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6962 (match_operand 3 "tld_symbolic_operand" "")]
6964 "TARGET_TLS && TARGET_ARCH32"
6965 "add\\t%1, %2, %0, %%tldo_add(%a3)")
6967 (define_insn "tldo_add64"
6968 [(set (match_operand:DI 0 "register_operand" "=r")
6969 (plus:DI (match_operand:DI 1 "register_operand" "r")
6970 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6971 (match_operand 3 "tld_symbolic_operand" "")]
6973 "TARGET_TLS && TARGET_ARCH64"
6974 "add\\t%1, %2, %0, %%tldo_add(%a3)")
6976 (define_insn "tie_hi22"
6977 [(set (match_operand:SI 0 "register_operand" "=r")
6978 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
6981 "sethi\\t%%tie_hi22(%a1), %0")
6983 (define_insn "tie_lo10"
6984 [(set (match_operand:SI 0 "register_operand" "=r")
6985 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6986 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
6989 "add\\t%1, %%tie_lo10(%a2), %0")
6991 (define_insn "tie_ld32"
6992 [(set (match_operand:SI 0 "register_operand" "=r")
6993 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6994 (match_operand:SI 2 "register_operand" "r")
6995 (match_operand 3 "tie_symbolic_operand" "")]
6997 "TARGET_TLS && TARGET_ARCH32"
6998 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
6999 [(set_attr "type" "load")])
7001 (define_insn "tie_ld64"
7002 [(set (match_operand:DI 0 "register_operand" "=r")
7003 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7004 (match_operand:SI 2 "register_operand" "r")
7005 (match_operand 3 "tie_symbolic_operand" "")]
7007 "TARGET_TLS && TARGET_ARCH64"
7008 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7009 [(set_attr "type" "load")])
7011 (define_insn "tie_add32"
7012 [(set (match_operand:SI 0 "register_operand" "=r")
7013 (plus:SI (match_operand:SI 1 "register_operand" "r")
7014 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7015 (match_operand 3 "tie_symbolic_operand" "")]
7017 "TARGET_SUN_TLS && TARGET_ARCH32"
7018 "add\\t%1, %2, %0, %%tie_add(%a3)")
7020 (define_insn "tie_add64"
7021 [(set (match_operand:DI 0 "register_operand" "=r")
7022 (plus:DI (match_operand:DI 1 "register_operand" "r")
7023 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7024 (match_operand 3 "tie_symbolic_operand" "")]
7026 "TARGET_SUN_TLS && TARGET_ARCH64"
7027 "add\\t%1, %2, %0, %%tie_add(%a3)")
7029 (define_insn "tle_hix22_sp32"
7030 [(set (match_operand:SI 0 "register_operand" "=r")
7031 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7033 "TARGET_TLS && TARGET_ARCH32"
7034 "sethi\\t%%tle_hix22(%a1), %0")
7036 (define_insn "tle_lox10_sp32"
7037 [(set (match_operand:SI 0 "register_operand" "=r")
7038 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7039 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7041 "TARGET_TLS && TARGET_ARCH32"
7042 "xor\\t%1, %%tle_lox10(%a2), %0")
7044 (define_insn "tle_hix22_sp64"
7045 [(set (match_operand:DI 0 "register_operand" "=r")
7046 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7048 "TARGET_TLS && TARGET_ARCH64"
7049 "sethi\\t%%tle_hix22(%a1), %0")
7051 (define_insn "tle_lox10_sp64"
7052 [(set (match_operand:DI 0 "register_operand" "=r")
7053 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7054 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7056 "TARGET_TLS && TARGET_ARCH64"
7057 "xor\\t%1, %%tle_lox10(%a2), %0")
7059 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7060 (define_insn "*tldo_ldub_sp32"
7061 [(set (match_operand:QI 0 "register_operand" "=r")
7062 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7063 (match_operand 3 "tld_symbolic_operand" "")]
7065 (match_operand:SI 1 "register_operand" "r"))))]
7066 "TARGET_TLS && TARGET_ARCH32"
7067 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7068 [(set_attr "type" "load")
7069 (set_attr "us3load_type" "3cycle")])
7071 (define_insn "*tldo_ldub1_sp32"
7072 [(set (match_operand:HI 0 "register_operand" "=r")
7073 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7074 (match_operand 3 "tld_symbolic_operand" "")]
7076 (match_operand:SI 1 "register_operand" "r")))))]
7077 "TARGET_TLS && TARGET_ARCH32"
7078 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7079 [(set_attr "type" "load")
7080 (set_attr "us3load_type" "3cycle")])
7082 (define_insn "*tldo_ldub2_sp32"
7083 [(set (match_operand:SI 0 "register_operand" "=r")
7084 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7085 (match_operand 3 "tld_symbolic_operand" "")]
7087 (match_operand:SI 1 "register_operand" "r")))))]
7088 "TARGET_TLS && TARGET_ARCH32"
7089 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7090 [(set_attr "type" "load")
7091 (set_attr "us3load_type" "3cycle")])
7093 (define_insn "*tldo_ldsb1_sp32"
7094 [(set (match_operand:HI 0 "register_operand" "=r")
7095 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7096 (match_operand 3 "tld_symbolic_operand" "")]
7098 (match_operand:SI 1 "register_operand" "r")))))]
7099 "TARGET_TLS && TARGET_ARCH32"
7100 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7101 [(set_attr "type" "sload")
7102 (set_attr "us3load_type" "3cycle")])
7104 (define_insn "*tldo_ldsb2_sp32"
7105 [(set (match_operand:SI 0 "register_operand" "=r")
7106 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7107 (match_operand 3 "tld_symbolic_operand" "")]
7109 (match_operand:SI 1 "register_operand" "r")))))]
7110 "TARGET_TLS && TARGET_ARCH32"
7111 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7112 [(set_attr "type" "sload")
7113 (set_attr "us3load_type" "3cycle")])
7115 (define_insn "*tldo_ldub_sp64"
7116 [(set (match_operand:QI 0 "register_operand" "=r")
7117 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7118 (match_operand 3 "tld_symbolic_operand" "")]
7120 (match_operand:DI 1 "register_operand" "r"))))]
7121 "TARGET_TLS && TARGET_ARCH64"
7122 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7123 [(set_attr "type" "load")
7124 (set_attr "us3load_type" "3cycle")])
7126 (define_insn "*tldo_ldub1_sp64"
7127 [(set (match_operand:HI 0 "register_operand" "=r")
7128 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7129 (match_operand 3 "tld_symbolic_operand" "")]
7131 (match_operand:DI 1 "register_operand" "r")))))]
7132 "TARGET_TLS && TARGET_ARCH64"
7133 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7134 [(set_attr "type" "load")
7135 (set_attr "us3load_type" "3cycle")])
7137 (define_insn "*tldo_ldub2_sp64"
7138 [(set (match_operand:SI 0 "register_operand" "=r")
7139 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7140 (match_operand 3 "tld_symbolic_operand" "")]
7142 (match_operand:DI 1 "register_operand" "r")))))]
7143 "TARGET_TLS && TARGET_ARCH64"
7144 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7145 [(set_attr "type" "load")
7146 (set_attr "us3load_type" "3cycle")])
7148 (define_insn "*tldo_ldub3_sp64"
7149 [(set (match_operand:DI 0 "register_operand" "=r")
7150 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7151 (match_operand 3 "tld_symbolic_operand" "")]
7153 (match_operand:DI 1 "register_operand" "r")))))]
7154 "TARGET_TLS && TARGET_ARCH64"
7155 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7156 [(set_attr "type" "load")
7157 (set_attr "us3load_type" "3cycle")])
7159 (define_insn "*tldo_ldsb1_sp64"
7160 [(set (match_operand:HI 0 "register_operand" "=r")
7161 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7162 (match_operand 3 "tld_symbolic_operand" "")]
7164 (match_operand:DI 1 "register_operand" "r")))))]
7165 "TARGET_TLS && TARGET_ARCH64"
7166 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7167 [(set_attr "type" "sload")
7168 (set_attr "us3load_type" "3cycle")])
7170 (define_insn "*tldo_ldsb2_sp64"
7171 [(set (match_operand:SI 0 "register_operand" "=r")
7172 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7173 (match_operand 3 "tld_symbolic_operand" "")]
7175 (match_operand:DI 1 "register_operand" "r")))))]
7176 "TARGET_TLS && TARGET_ARCH64"
7177 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7178 [(set_attr "type" "sload")
7179 (set_attr "us3load_type" "3cycle")])
7181 (define_insn "*tldo_ldsb3_sp64"
7182 [(set (match_operand:DI 0 "register_operand" "=r")
7183 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7184 (match_operand 3 "tld_symbolic_operand" "")]
7186 (match_operand:DI 1 "register_operand" "r")))))]
7187 "TARGET_TLS && TARGET_ARCH64"
7188 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7189 [(set_attr "type" "sload")
7190 (set_attr "us3load_type" "3cycle")])
7192 (define_insn "*tldo_lduh_sp32"
7193 [(set (match_operand:HI 0 "register_operand" "=r")
7194 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7195 (match_operand 3 "tld_symbolic_operand" "")]
7197 (match_operand:SI 1 "register_operand" "r"))))]
7198 "TARGET_TLS && TARGET_ARCH32"
7199 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7200 [(set_attr "type" "load")
7201 (set_attr "us3load_type" "3cycle")])
7203 (define_insn "*tldo_lduh1_sp32"
7204 [(set (match_operand:SI 0 "register_operand" "=r")
7205 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7206 (match_operand 3 "tld_symbolic_operand" "")]
7208 (match_operand:SI 1 "register_operand" "r")))))]
7209 "TARGET_TLS && TARGET_ARCH32"
7210 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7211 [(set_attr "type" "load")
7212 (set_attr "us3load_type" "3cycle")])
7214 (define_insn "*tldo_ldsh1_sp32"
7215 [(set (match_operand:SI 0 "register_operand" "=r")
7216 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7217 (match_operand 3 "tld_symbolic_operand" "")]
7219 (match_operand:SI 1 "register_operand" "r")))))]
7220 "TARGET_TLS && TARGET_ARCH32"
7221 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7222 [(set_attr "type" "sload")
7223 (set_attr "us3load_type" "3cycle")])
7225 (define_insn "*tldo_lduh_sp64"
7226 [(set (match_operand:HI 0 "register_operand" "=r")
7227 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7228 (match_operand 3 "tld_symbolic_operand" "")]
7230 (match_operand:DI 1 "register_operand" "r"))))]
7231 "TARGET_TLS && TARGET_ARCH64"
7232 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7233 [(set_attr "type" "load")
7234 (set_attr "us3load_type" "3cycle")])
7236 (define_insn "*tldo_lduh1_sp64"
7237 [(set (match_operand:SI 0 "register_operand" "=r")
7238 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7239 (match_operand 3 "tld_symbolic_operand" "")]
7241 (match_operand:DI 1 "register_operand" "r")))))]
7242 "TARGET_TLS && TARGET_ARCH64"
7243 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7244 [(set_attr "type" "load")
7245 (set_attr "us3load_type" "3cycle")])
7247 (define_insn "*tldo_lduh2_sp64"
7248 [(set (match_operand:DI 0 "register_operand" "=r")
7249 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7250 (match_operand 3 "tld_symbolic_operand" "")]
7252 (match_operand:DI 1 "register_operand" "r")))))]
7253 "TARGET_TLS && TARGET_ARCH64"
7254 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7255 [(set_attr "type" "load")
7256 (set_attr "us3load_type" "3cycle")])
7258 (define_insn "*tldo_ldsh1_sp64"
7259 [(set (match_operand:SI 0 "register_operand" "=r")
7260 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7261 (match_operand 3 "tld_symbolic_operand" "")]
7263 (match_operand:DI 1 "register_operand" "r")))))]
7264 "TARGET_TLS && TARGET_ARCH64"
7265 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7266 [(set_attr "type" "sload")
7267 (set_attr "us3load_type" "3cycle")])
7269 (define_insn "*tldo_ldsh2_sp64"
7270 [(set (match_operand:DI 0 "register_operand" "=r")
7271 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7272 (match_operand 3 "tld_symbolic_operand" "")]
7274 (match_operand:DI 1 "register_operand" "r")))))]
7275 "TARGET_TLS && TARGET_ARCH64"
7276 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7277 [(set_attr "type" "sload")
7278 (set_attr "us3load_type" "3cycle")])
7280 (define_insn "*tldo_lduw_sp32"
7281 [(set (match_operand:SI 0 "register_operand" "=r")
7282 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7283 (match_operand 3 "tld_symbolic_operand" "")]
7285 (match_operand:SI 1 "register_operand" "r"))))]
7286 "TARGET_TLS && TARGET_ARCH32"
7287 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7288 [(set_attr "type" "load")])
7290 (define_insn "*tldo_lduw_sp64"
7291 [(set (match_operand:SI 0 "register_operand" "=r")
7292 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7293 (match_operand 3 "tld_symbolic_operand" "")]
7295 (match_operand:DI 1 "register_operand" "r"))))]
7296 "TARGET_TLS && TARGET_ARCH64"
7297 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7298 [(set_attr "type" "load")])
7300 (define_insn "*tldo_lduw1_sp64"
7301 [(set (match_operand:DI 0 "register_operand" "=r")
7302 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7303 (match_operand 3 "tld_symbolic_operand" "")]
7305 (match_operand:DI 1 "register_operand" "r")))))]
7306 "TARGET_TLS && TARGET_ARCH64"
7307 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7308 [(set_attr "type" "load")])
7310 (define_insn "*tldo_ldsw1_sp64"
7311 [(set (match_operand:DI 0 "register_operand" "=r")
7312 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7313 (match_operand 3 "tld_symbolic_operand" "")]
7315 (match_operand:DI 1 "register_operand" "r")))))]
7316 "TARGET_TLS && TARGET_ARCH64"
7317 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7318 [(set_attr "type" "sload")
7319 (set_attr "us3load_type" "3cycle")])
7321 (define_insn "*tldo_ldx_sp64"
7322 [(set (match_operand:DI 0 "register_operand" "=r")
7323 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7324 (match_operand 3 "tld_symbolic_operand" "")]
7326 (match_operand:DI 1 "register_operand" "r"))))]
7327 "TARGET_TLS && TARGET_ARCH64"
7328 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7329 [(set_attr "type" "load")])
7331 (define_insn "*tldo_stb_sp32"
7332 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7333 (match_operand 3 "tld_symbolic_operand" "")]
7335 (match_operand:SI 1 "register_operand" "r")))
7336 (match_operand:QI 0 "register_operand" "=r"))]
7337 "TARGET_TLS && TARGET_ARCH32"
7338 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7339 [(set_attr "type" "store")])
7341 (define_insn "*tldo_stb_sp64"
7342 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7343 (match_operand 3 "tld_symbolic_operand" "")]
7345 (match_operand:DI 1 "register_operand" "r")))
7346 (match_operand:QI 0 "register_operand" "=r"))]
7347 "TARGET_TLS && TARGET_ARCH64"
7348 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7349 [(set_attr "type" "store")])
7351 (define_insn "*tldo_sth_sp32"
7352 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7353 (match_operand 3 "tld_symbolic_operand" "")]
7355 (match_operand:SI 1 "register_operand" "r")))
7356 (match_operand:HI 0 "register_operand" "=r"))]
7357 "TARGET_TLS && TARGET_ARCH32"
7358 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7359 [(set_attr "type" "store")])
7361 (define_insn "*tldo_sth_sp64"
7362 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7363 (match_operand 3 "tld_symbolic_operand" "")]
7365 (match_operand:DI 1 "register_operand" "r")))
7366 (match_operand:HI 0 "register_operand" "=r"))]
7367 "TARGET_TLS && TARGET_ARCH64"
7368 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7369 [(set_attr "type" "store")])
7371 (define_insn "*tldo_stw_sp32"
7372 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7373 (match_operand 3 "tld_symbolic_operand" "")]
7375 (match_operand:SI 1 "register_operand" "r")))
7376 (match_operand:SI 0 "register_operand" "=r"))]
7377 "TARGET_TLS && TARGET_ARCH32"
7378 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7379 [(set_attr "type" "store")])
7381 (define_insn "*tldo_stw_sp64"
7382 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7383 (match_operand 3 "tld_symbolic_operand" "")]
7385 (match_operand:DI 1 "register_operand" "r")))
7386 (match_operand:SI 0 "register_operand" "=r"))]
7387 "TARGET_TLS && TARGET_ARCH64"
7388 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7389 [(set_attr "type" "store")])
7391 (define_insn "*tldo_stx_sp64"
7392 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7393 (match_operand 3 "tld_symbolic_operand" "")]
7395 (match_operand:DI 1 "register_operand" "r")))
7396 (match_operand:DI 0 "register_operand" "=r"))]
7397 "TARGET_TLS && TARGET_ARCH64"
7398 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7399 [(set_attr "type" "store")])
7402 ;; Stack protector instructions.
7404 (define_expand "stack_protect_set"
7405 [(match_operand 0 "memory_operand" "")
7406 (match_operand 1 "memory_operand" "")]
7409 #ifdef TARGET_THREAD_SSP_OFFSET
7410 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7411 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7412 operands[1] = gen_rtx_MEM (Pmode, addr);
7415 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7417 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7421 (define_insn "stack_protect_setsi"
7422 [(set (match_operand:SI 0 "memory_operand" "=m")
7423 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7424 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7426 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7427 [(set_attr "type" "multi")
7428 (set_attr "length" "3")])
7430 (define_insn "stack_protect_setdi"
7431 [(set (match_operand:DI 0 "memory_operand" "=m")
7432 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7433 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7435 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7436 [(set_attr "type" "multi")
7437 (set_attr "length" "3")])
7439 (define_expand "stack_protect_test"
7440 [(match_operand 0 "memory_operand" "")
7441 (match_operand 1 "memory_operand" "")
7442 (match_operand 2 "" "")]
7446 #ifdef TARGET_THREAD_SSP_OFFSET
7447 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7448 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7449 operands[1] = gen_rtx_MEM (Pmode, addr);
7453 result = gen_reg_rtx (Pmode);
7454 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7455 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7456 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7460 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7461 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7462 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7463 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7468 (define_insn "stack_protect_testsi"
7470 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7471 (match_operand:SI 1 "memory_operand" "m")]
7473 (set (match_scratch:SI 3 "=r") (const_int 0))
7474 (clobber (match_scratch:SI 2 "=&r"))]
7476 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7477 [(set_attr "type" "multi")
7478 (set_attr "length" "4")])
7480 (define_insn "stack_protect_testdi"
7481 [(set (match_operand:DI 0 "register_operand" "=&r")
7482 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7483 (match_operand:DI 2 "memory_operand" "m")]
7485 (set (match_scratch:DI 3 "=r") (const_int 0))]
7487 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7488 [(set_attr "type" "multi")
7489 (set_attr "length" "4")])
7492 ;; Vector instructions.
7494 (define_insn "addv2si3"
7495 [(set (match_operand:V2SI 0 "register_operand" "=e")
7496 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7497 (match_operand:V2SI 2 "register_operand" "e")))]
7499 "fpadd32\t%1, %2, %0"
7500 [(set_attr "type" "fga")
7501 (set_attr "fptype" "double")])
7503 (define_insn "addv4hi3"
7504 [(set (match_operand:V4HI 0 "register_operand" "=e")
7505 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7506 (match_operand:V4HI 2 "register_operand" "e")))]
7508 "fpadd16\t%1, %2, %0"
7509 [(set_attr "type" "fga")
7510 (set_attr "fptype" "double")])
7512 ;; fpadd32s is emitted by the addsi3 pattern.
7514 (define_insn "addv2hi3"
7515 [(set (match_operand:V2HI 0 "register_operand" "=f")
7516 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7517 (match_operand:V2HI 2 "register_operand" "f")))]
7519 "fpadd16s\t%1, %2, %0"
7520 [(set_attr "type" "fga")
7521 (set_attr "fptype" "single")])
7523 (define_insn "subv2si3"
7524 [(set (match_operand:V2SI 0 "register_operand" "=e")
7525 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7526 (match_operand:V2SI 2 "register_operand" "e")))]
7528 "fpsub32\t%1, %2, %0"
7529 [(set_attr "type" "fga")
7530 (set_attr "fptype" "double")])
7532 (define_insn "subv4hi3"
7533 [(set (match_operand:V4HI 0 "register_operand" "=e")
7534 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7535 (match_operand:V4HI 2 "register_operand" "e")))]
7537 "fpsub16\t%1, %2, %0"
7538 [(set_attr "type" "fga")
7539 (set_attr "fptype" "double")])
7541 ;; fpsub32s is emitted by the subsi3 pattern.
7543 (define_insn "subv2hi3"
7544 [(set (match_operand:V2HI 0 "register_operand" "=f")
7545 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7546 (match_operand:V2HI 2 "register_operand" "f")))]
7548 "fpsub16s\t%1, %2, %0"
7549 [(set_attr "type" "fga")
7550 (set_attr "fptype" "single")])
7552 ;; All other logical instructions have integer equivalents so they
7553 ;; are defined together.
7555 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7557 (define_insn "*nand<V64:mode>_vis"
7558 [(set (match_operand:V64 0 "register_operand" "=e")
7559 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7560 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7563 [(set_attr "type" "fga")
7564 (set_attr "fptype" "double")])
7566 (define_insn "*nand<V32:mode>_vis"
7567 [(set (match_operand:V32 0 "register_operand" "=f")
7568 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7569 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7571 "fnands\t%1, %2, %0"
7572 [(set_attr "type" "fga")
7573 (set_attr "fptype" "single")])
7575 ;; Hard to generate VIS instructions. We have builtins for these.
7577 (define_insn "fpack16_vis"
7578 [(set (match_operand:V4QI 0 "register_operand" "=f")
7579 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7583 [(set_attr "type" "fga")
7584 (set_attr "fptype" "double")])
7586 (define_insn "fpackfix_vis"
7587 [(set (match_operand:V2HI 0 "register_operand" "=f")
7588 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7592 [(set_attr "type" "fga")
7593 (set_attr "fptype" "double")])
7595 (define_insn "fpack32_vis"
7596 [(set (match_operand:V8QI 0 "register_operand" "=e")
7597 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7598 (match_operand:V8QI 2 "register_operand" "e")]
7601 "fpack32\t%1, %2, %0"
7602 [(set_attr "type" "fga")
7603 (set_attr "fptype" "double")])
7605 (define_insn "fexpand_vis"
7606 [(set (match_operand:V4HI 0 "register_operand" "=e")
7607 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7611 [(set_attr "type" "fga")
7612 (set_attr "fptype" "double")])
7614 ;; It may be possible to describe this operation as (1 indexed):
7615 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7616 ;; 1,5,10,14,19,23,28,32)
7617 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7618 ;; because vec_merge expects all the operands to be of the same type.
7619 (define_insn "fpmerge_vis"
7620 [(set (match_operand:V8QI 0 "register_operand" "=e")
7621 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7622 (match_operand:V4QI 2 "register_operand" "f")]
7625 "fpmerge\t%1, %2, %0"
7626 [(set_attr "type" "fga")
7627 (set_attr "fptype" "double")])
7629 ;; Partitioned multiply instructions
7630 (define_insn "fmul8x16_vis"
7631 [(set (match_operand:V4HI 0 "register_operand" "=e")
7632 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7633 (match_operand:V4HI 2 "register_operand" "e")))]
7635 "fmul8x16\t%1, %2, %0"
7636 [(set_attr "type" "fpmul")
7637 (set_attr "fptype" "double")])
7639 ;; Only one of the following two insns can be a multiply.
7640 (define_insn "fmul8x16au_vis"
7641 [(set (match_operand:V4HI 0 "register_operand" "=e")
7642 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7643 (match_operand:V2HI 2 "register_operand" "f")))]
7645 "fmul8x16au\t%1, %2, %0"
7646 [(set_attr "type" "fpmul")
7647 (set_attr "fptype" "double")])
7649 (define_insn "fmul8x16al_vis"
7650 [(set (match_operand:V4HI 0 "register_operand" "=e")
7651 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7652 (match_operand:V2HI 2 "register_operand" "f")]
7655 "fmul8x16al\t%1, %2, %0"
7656 [(set_attr "type" "fpmul")
7657 (set_attr "fptype" "double")])
7659 ;; Only one of the following two insns can be a multiply.
7660 (define_insn "fmul8sux16_vis"
7661 [(set (match_operand:V4HI 0 "register_operand" "=e")
7662 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7663 (match_operand:V4HI 2 "register_operand" "e")))]
7665 "fmul8sux16\t%1, %2, %0"
7666 [(set_attr "type" "fpmul")
7667 (set_attr "fptype" "double")])
7669 (define_insn "fmul8ulx16_vis"
7670 [(set (match_operand:V4HI 0 "register_operand" "=e")
7671 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7672 (match_operand:V4HI 2 "register_operand" "e")]
7675 "fmul8ulx16\t%1, %2, %0"
7676 [(set_attr "type" "fpmul")
7677 (set_attr "fptype" "double")])
7679 ;; Only one of the following two insns can be a multiply.
7680 (define_insn "fmuld8sux16_vis"
7681 [(set (match_operand:V2SI 0 "register_operand" "=e")
7682 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7683 (match_operand:V2HI 2 "register_operand" "f")))]
7685 "fmuld8sux16\t%1, %2, %0"
7686 [(set_attr "type" "fpmul")
7687 (set_attr "fptype" "double")])
7689 (define_insn "fmuld8ulx16_vis"
7690 [(set (match_operand:V2SI 0 "register_operand" "=e")
7691 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7692 (match_operand:V2HI 2 "register_operand" "f")]
7695 "fmuld8ulx16\t%1, %2, %0"
7696 [(set_attr "type" "fpmul")
7697 (set_attr "fptype" "double")])
7699 ;; Using faligndata only makes sense after an alignaddr since the choice of
7700 ;; bytes to take out of each operand is dependent on the results of the last
7702 (define_insn "faligndata<V64I:mode>_vis"
7703 [(set (match_operand:V64I 0 "register_operand" "=e")
7704 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7705 (match_operand:V64I 2 "register_operand" "e")]
7708 "faligndata\t%1, %2, %0"
7709 [(set_attr "type" "fga")
7710 (set_attr "fptype" "double")])
7712 (define_insn "alignaddr<P:mode>_vis"
7713 [(set (match_operand:P 0 "register_operand" "=r")
7714 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7715 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7718 "alignaddr\t%r1, %r2, %0")
7720 (define_insn "pdist_vis"
7721 [(set (match_operand:DI 0 "register_operand" "=e")
7722 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7723 (match_operand:V8QI 2 "register_operand" "e")
7724 (match_operand:DI 3 "register_operand" "0")]
7728 [(set_attr "type" "fga")
7729 (set_attr "fptype" "double")])