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, 2010,
4 ;; 2011 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)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
83 (UNSPECV_PROBE_STACK_RANGE 11)
87 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
88 (define_mode_iterator I [QI HI SI DI])
89 (define_mode_iterator F [SF DF TF])
91 ;; We don't define V1SI because SI should work just fine.
92 (define_mode_iterator V32 [SF V2HI V4QI])
93 (define_mode_iterator V32I [SI V2HI V4QI])
95 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
96 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
98 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
99 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
100 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
101 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
102 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
105 ;; Attribute for cpu type.
106 ;; These must match the values for enum processor_type in sparc.h.
127 (const (symbol_ref "sparc_cpu_attr")))
129 ;; Attribute for the instruction set.
130 ;; At present we only need to distinguish v9/!v9, but for clarity we
131 ;; test TARGET_V8 too.
132 (define_attr "isa" "v7,v8,v9,sparclet"
134 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
135 (symbol_ref "TARGET_V8") (const_string "v8")
136 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
137 (const_string "v7"))))
143 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
151 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,
154 multi,savew,flushw,iflush,trap"
155 (const_string "ialu"))
157 ;; True if branch/call has empty delay slot and will emit a nop in it
158 (define_attr "empty_delay_slot" "false,true"
159 (symbol_ref "(empty_delay_slot (insn)
160 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
162 (define_attr "branch_type" "none,icc,fcc,reg"
163 (const_string "none"))
165 (define_attr "pic" "false,true"
166 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
168 (define_attr "calls_alloca" "false,true"
169 (symbol_ref "(cfun->calls_alloca != 0
170 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
172 (define_attr "calls_eh_return" "false,true"
173 (symbol_ref "(crtl->calls_eh_return != 0
174 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
176 (define_attr "leaf_function" "false,true"
177 (symbol_ref "(current_function_uses_only_leaf_regs != 0
178 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
180 (define_attr "delayed_branch" "false,true"
181 (symbol_ref "(flag_delayed_branch != 0
182 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
184 (define_attr "flat" "false,true"
185 (symbol_ref "(TARGET_FLAT != 0
186 ? FLAT_TRUE : FLAT_FALSE)"))
188 ;; Length (in # of insns).
189 ;; Beware that setting a length greater or equal to 3 for conditional branches
190 ;; has a side-effect (see output_cbranch and output_v9branch).
191 (define_attr "length" ""
192 (cond [(eq_attr "type" "uncond_branch,call")
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (eq_attr "type" "sibcall")
197 (if_then_else (eq_attr "leaf_function" "true")
198 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (if_then_else (eq_attr "empty_delay_slot" "true")
204 (eq_attr "branch_type" "icc")
205 (if_then_else (match_operand 0 "noov_compare64_operator" "")
206 (if_then_else (lt (pc) (match_dup 1))
207 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
208 (if_then_else (eq_attr "empty_delay_slot" "true")
211 (if_then_else (eq_attr "empty_delay_slot" "true")
214 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
215 (if_then_else (eq_attr "empty_delay_slot" "true")
218 (if_then_else (eq_attr "empty_delay_slot" "true")
221 (if_then_else (eq_attr "empty_delay_slot" "true")
224 (eq_attr "branch_type" "fcc")
225 (if_then_else (match_operand 0 "fcc0_register_operand" "")
226 (if_then_else (eq_attr "empty_delay_slot" "true")
227 (if_then_else (not (match_test "TARGET_V9"))
230 (if_then_else (not (match_test "TARGET_V9"))
233 (if_then_else (lt (pc) (match_dup 2))
234 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
235 (if_then_else (eq_attr "empty_delay_slot" "true")
238 (if_then_else (eq_attr "empty_delay_slot" "true")
241 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
242 (if_then_else (eq_attr "empty_delay_slot" "true")
245 (if_then_else (eq_attr "empty_delay_slot" "true")
248 (eq_attr "branch_type" "reg")
249 (if_then_else (lt (pc) (match_dup 2))
250 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
251 (if_then_else (eq_attr "empty_delay_slot" "true")
254 (if_then_else (eq_attr "empty_delay_slot" "true")
257 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
258 (if_then_else (eq_attr "empty_delay_slot" "true")
261 (if_then_else (eq_attr "empty_delay_slot" "true")
267 (define_attr "fptype" "single,double"
268 (const_string "single"))
270 ;; UltraSPARC-III integer load type.
271 (define_attr "us3load_type" "2cycle,3cycle"
272 (const_string "2cycle"))
274 (define_asm_attributes
275 [(set_attr "length" "2")
276 (set_attr "type" "multi")])
278 ;; Attributes for instruction and branch scheduling
279 (define_attr "tls_call_delay" "false,true"
280 (symbol_ref "(tls_call_delay (insn)
281 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
283 (define_attr "in_call_delay" "false,true"
284 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
285 (const_string "false")
286 (eq_attr "type" "load,fpload,store,fpstore")
287 (if_then_else (eq_attr "length" "1")
288 (const_string "true")
289 (const_string "false"))]
290 (if_then_else (and (eq_attr "length" "1")
291 (eq_attr "tls_call_delay" "true"))
292 (const_string "true")
293 (const_string "false"))))
295 (define_attr "eligible_for_sibcall_delay" "false,true"
296 (symbol_ref "(eligible_for_sibcall_delay (insn)
297 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
298 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
300 (define_attr "eligible_for_return_delay" "false,true"
301 (symbol_ref "(eligible_for_return_delay (insn)
302 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
303 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
305 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
306 ;; branches. This would allow us to remove the nop always inserted before
307 ;; a floating point branch.
309 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
310 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
311 ;; This is because doing so will add several pipeline stalls to the path
312 ;; that the load/store did not come from. Unfortunately, there is no way
313 ;; to prevent fill_eager_delay_slots from using load/store without completely
314 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
315 ;; because it prevents us from moving back the final store of inner loops.
317 (define_attr "in_branch_delay" "false,true"
318 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
319 (eq_attr "length" "1"))
320 (const_string "true")
321 (const_string "false")))
323 (define_attr "in_uncond_branch_delay" "false,true"
324 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
325 (eq_attr "length" "1"))
326 (const_string "true")
327 (const_string "false")))
329 (define_attr "in_annul_branch_delay" "false,true"
330 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
331 (eq_attr "length" "1"))
332 (const_string "true")
333 (const_string "false")))
335 (define_delay (eq_attr "type" "call")
336 [(eq_attr "in_call_delay" "true") (nil) (nil)])
338 (define_delay (eq_attr "type" "sibcall")
339 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
341 (define_delay (eq_attr "type" "branch")
342 [(eq_attr "in_branch_delay" "true")
343 (nil) (eq_attr "in_annul_branch_delay" "true")])
345 (define_delay (eq_attr "type" "uncond_branch")
346 [(eq_attr "in_uncond_branch_delay" "true")
349 (define_delay (eq_attr "type" "return")
350 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
353 ;; Include SPARC DFA schedulers
355 (include "cypress.md")
356 (include "supersparc.md")
357 (include "hypersparc.md")
359 (include "sparclet.md")
360 (include "ultra1_2.md")
361 (include "ultra3.md")
362 (include "niagara.md")
363 (include "niagara2.md")
366 ;; Operand and operator predicates and constraints
368 (include "predicates.md")
369 (include "constraints.md")
372 ;; Compare instructions.
374 ;; These are just the DEFINE_INSNs to match the patterns and the
375 ;; DEFINE_SPLITs for some of the scc insns that actually require
376 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
378 ;; The compare DEFINE_INSNs.
380 (define_insn "*cmpsi_insn"
382 (compare:CC (match_operand:SI 0 "register_operand" "r")
383 (match_operand:SI 1 "arith_operand" "rI")))]
386 [(set_attr "type" "compare")])
388 (define_insn "*cmpdi_sp64"
390 (compare:CCX (match_operand:DI 0 "register_operand" "r")
391 (match_operand:DI 1 "arith_operand" "rI")))]
394 [(set_attr "type" "compare")])
396 (define_insn "*cmpsf_fpe"
397 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
398 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
399 (match_operand:SF 2 "register_operand" "f")))]
403 return "fcmpes\t%0, %1, %2";
404 return "fcmpes\t%1, %2";
406 [(set_attr "type" "fpcmp")])
408 (define_insn "*cmpdf_fpe"
409 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
410 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
411 (match_operand:DF 2 "register_operand" "e")))]
415 return "fcmped\t%0, %1, %2";
416 return "fcmped\t%1, %2";
418 [(set_attr "type" "fpcmp")
419 (set_attr "fptype" "double")])
421 (define_insn "*cmptf_fpe"
422 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
423 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
424 (match_operand:TF 2 "register_operand" "e")))]
425 "TARGET_FPU && TARGET_HARD_QUAD"
428 return "fcmpeq\t%0, %1, %2";
429 return "fcmpeq\t%1, %2";
431 [(set_attr "type" "fpcmp")])
433 (define_insn "*cmpsf_fp"
434 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
435 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
436 (match_operand:SF 2 "register_operand" "f")))]
440 return "fcmps\t%0, %1, %2";
441 return "fcmps\t%1, %2";
443 [(set_attr "type" "fpcmp")])
445 (define_insn "*cmpdf_fp"
446 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
447 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
448 (match_operand:DF 2 "register_operand" "e")))]
452 return "fcmpd\t%0, %1, %2";
453 return "fcmpd\t%1, %2";
455 [(set_attr "type" "fpcmp")
456 (set_attr "fptype" "double")])
458 (define_insn "*cmptf_fp"
459 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
460 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
461 (match_operand:TF 2 "register_operand" "e")))]
462 "TARGET_FPU && TARGET_HARD_QUAD"
465 return "fcmpq\t%0, %1, %2";
466 return "fcmpq\t%1, %2";
468 [(set_attr "type" "fpcmp")])
470 ;; Next come the scc insns.
472 (define_expand "cstoresi4"
473 [(use (match_operator 1 "comparison_operator"
474 [(match_operand:SI 2 "compare_operand" "")
475 (match_operand:SI 3 "arith_operand" "")]))
476 (clobber (match_operand:SI 0 "register_operand"))]
479 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
480 operands[2] = force_reg (SImode, operands[2]);
481 if (emit_scc_insn (operands)) DONE; else FAIL;
484 (define_expand "cstoredi4"
485 [(use (match_operator 1 "comparison_operator"
486 [(match_operand:DI 2 "compare_operand" "")
487 (match_operand:DI 3 "arith_operand" "")]))
488 (clobber (match_operand:SI 0 "register_operand"))]
491 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
492 operands[2] = force_reg (DImode, operands[2]);
493 if (emit_scc_insn (operands)) DONE; else FAIL;
496 (define_expand "cstore<F:mode>4"
497 [(use (match_operator 1 "comparison_operator"
498 [(match_operand:F 2 "register_operand" "")
499 (match_operand:F 3 "register_operand" "")]))
500 (clobber (match_operand:SI 0 "register_operand"))]
502 { if (emit_scc_insn (operands)) DONE; else FAIL; })
506 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
507 ;; generate addcc/subcc instructions.
509 (define_expand "seqsi_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 (eq:SI (match_dup 3) (const_int 0)))
515 (clobber (reg:CC 100))])]
517 { operands[3] = gen_reg_rtx (SImode); })
519 (define_expand "seqdi_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 (eq:SI (match_dup 3) (const_int 0)))]
526 { operands[3] = gen_reg_rtx (DImode); })
528 (define_expand "snesi_special"
530 (xor:SI (match_operand:SI 1 "register_operand" "")
531 (match_operand:SI 2 "register_operand" "")))
532 (parallel [(set (match_operand:SI 0 "register_operand" "")
533 (ne:SI (match_dup 3) (const_int 0)))
534 (clobber (reg:CC 100))])]
536 { operands[3] = gen_reg_rtx (SImode); })
538 (define_expand "snedi_special"
540 (xor:DI (match_operand:DI 1 "register_operand" "")
541 (match_operand:DI 2 "register_operand" "")))
542 (set (match_operand:SI 0 "register_operand" "")
543 (ne:SI (match_dup 3) (const_int 0)))]
545 { operands[3] = gen_reg_rtx (DImode); })
548 ;; Now the DEFINE_INSNs for the scc cases.
550 ;; The SEQ and SNE patterns are special because they can be done
551 ;; without any branching and do not involve a COMPARE. We want
552 ;; them to always use the splits below so the results can be
555 (define_insn_and_split "*snesi_zero"
556 [(set (match_operand:SI 0 "register_operand" "=r")
557 (ne:SI (match_operand:SI 1 "register_operand" "r")
559 (clobber (reg:CC 100))]
563 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
565 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
567 [(set_attr "length" "2")])
569 (define_insn_and_split "*neg_snesi_zero"
570 [(set (match_operand:SI 0 "register_operand" "=r")
571 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
573 (clobber (reg:CC 100))]
577 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
579 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
581 [(set_attr "length" "2")])
583 (define_insn_and_split "*snesi_zero_extend"
584 [(set (match_operand:DI 0 "register_operand" "=r")
585 (ne:DI (match_operand:SI 1 "register_operand" "r")
587 (clobber (reg:CC 100))]
591 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
594 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
596 (ltu:SI (reg:CC_NOOV 100)
599 [(set_attr "length" "2")])
601 (define_insn_and_split "*snedi_zero"
602 [(set (match_operand:DI 0 "register_operand" "=&r")
603 (ne:DI (match_operand:DI 1 "register_operand" "r")
607 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
608 [(set (match_dup 0) (const_int 0))
609 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
614 [(set_attr "length" "2")])
616 (define_insn_and_split "*neg_snedi_zero"
617 [(set (match_operand:DI 0 "register_operand" "=&r")
618 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
622 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
623 [(set (match_dup 0) (const_int 0))
624 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
629 [(set_attr "length" "2")])
631 (define_insn_and_split "*snedi_zero_trunc"
632 [(set (match_operand:SI 0 "register_operand" "=&r")
633 (ne:SI (match_operand:DI 1 "register_operand" "r")
637 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
638 [(set (match_dup 0) (const_int 0))
639 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
644 [(set_attr "length" "2")])
646 (define_insn_and_split "*seqsi_zero"
647 [(set (match_operand:SI 0 "register_operand" "=r")
648 (eq:SI (match_operand:SI 1 "register_operand" "r")
650 (clobber (reg:CC 100))]
654 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
656 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
658 [(set_attr "length" "2")])
660 (define_insn_and_split "*neg_seqsi_zero"
661 [(set (match_operand:SI 0 "register_operand" "=r")
662 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
664 (clobber (reg:CC 100))]
668 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
670 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
672 [(set_attr "length" "2")])
674 (define_insn_and_split "*seqsi_zero_extend"
675 [(set (match_operand:DI 0 "register_operand" "=r")
676 (eq:DI (match_operand:SI 1 "register_operand" "r")
678 (clobber (reg:CC 100))]
682 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
685 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
687 (ltu:SI (reg:CC_NOOV 100)
690 [(set_attr "length" "2")])
692 (define_insn_and_split "*seqdi_zero"
693 [(set (match_operand:DI 0 "register_operand" "=&r")
694 (eq:DI (match_operand:DI 1 "register_operand" "r")
698 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
699 [(set (match_dup 0) (const_int 0))
700 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
705 [(set_attr "length" "2")])
707 (define_insn_and_split "*neg_seqdi_zero"
708 [(set (match_operand:DI 0 "register_operand" "=&r")
709 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
713 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
714 [(set (match_dup 0) (const_int 0))
715 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
720 [(set_attr "length" "2")])
722 (define_insn_and_split "*seqdi_zero_trunc"
723 [(set (match_operand:SI 0 "register_operand" "=&r")
724 (eq:SI (match_operand:DI 1 "register_operand" "r")
728 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
729 [(set (match_dup 0) (const_int 0))
730 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
735 [(set_attr "length" "2")])
737 ;; We can also do (x + (i == 0)) and related, so put them in.
738 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
741 (define_insn_and_split "*x_plus_i_ne_0"
742 [(set (match_operand:SI 0 "register_operand" "=r")
743 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
745 (match_operand:SI 2 "register_operand" "r")))
746 (clobber (reg:CC 100))]
750 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
752 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
755 [(set_attr "length" "2")])
757 (define_insn_and_split "*x_minus_i_ne_0"
758 [(set (match_operand:SI 0 "register_operand" "=r")
759 (minus:SI (match_operand:SI 2 "register_operand" "r")
760 (ne:SI (match_operand:SI 1 "register_operand" "r")
762 (clobber (reg:CC 100))]
766 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
768 (set (match_dup 0) (minus:SI (match_dup 2)
769 (ltu:SI (reg:CC 100) (const_int 0))))]
771 [(set_attr "length" "2")])
773 (define_insn_and_split "*x_plus_i_eq_0"
774 [(set (match_operand:SI 0 "register_operand" "=r")
775 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
777 (match_operand:SI 2 "register_operand" "r")))
778 (clobber (reg:CC 100))]
782 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
784 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
787 [(set_attr "length" "2")])
789 (define_insn_and_split "*x_minus_i_eq_0"
790 [(set (match_operand:SI 0 "register_operand" "=r")
791 (minus:SI (match_operand:SI 2 "register_operand" "r")
792 (eq:SI (match_operand:SI 1 "register_operand" "r")
794 (clobber (reg:CC 100))]
798 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
800 (set (match_dup 0) (minus:SI (match_dup 2)
801 (geu:SI (reg:CC 100) (const_int 0))))]
803 [(set_attr "length" "2")])
805 ;; We can also do GEU and LTU directly, but these operate after a compare.
806 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
809 (define_insn "*sltu_insn"
810 [(set (match_operand:SI 0 "register_operand" "=r")
811 (ltu:SI (reg:CC 100) (const_int 0)))]
814 [(set_attr "type" "ialuX")])
816 (define_insn "*neg_sltu_insn"
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
821 [(set_attr "type" "ialuX")])
823 ;; ??? Combine should canonicalize these next two to the same pattern.
824 (define_insn "*neg_sltu_minus_x"
825 [(set (match_operand:SI 0 "register_operand" "=r")
826 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
827 (match_operand:SI 1 "arith_operand" "rI")))]
830 [(set_attr "type" "ialuX")])
832 (define_insn "*neg_sltu_plus_x"
833 [(set (match_operand:SI 0 "register_operand" "=r")
834 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
835 (match_operand:SI 1 "arith_operand" "rI"))))]
838 [(set_attr "type" "ialuX")])
840 (define_insn "*sgeu_insn"
841 [(set (match_operand:SI 0 "register_operand" "=r")
842 (geu:SI (reg:CC 100) (const_int 0)))]
845 [(set_attr "type" "ialuX")])
847 (define_insn "*neg_sgeu_insn"
848 [(set (match_operand:SI 0 "register_operand" "=r")
849 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
852 [(set_attr "type" "ialuX")])
854 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
855 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
858 (define_insn "*sltu_plus_x"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
861 (match_operand:SI 1 "arith_operand" "rI")))]
864 [(set_attr "type" "ialuX")])
866 (define_insn "*sltu_plus_x_plus_y"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
869 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
870 (match_operand:SI 2 "arith_operand" "rI"))))]
873 [(set_attr "type" "ialuX")])
875 (define_insn "*x_minus_sltu"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (minus:SI (match_operand:SI 1 "register_operand" "r")
878 (ltu:SI (reg:CC 100) (const_int 0))))]
881 [(set_attr "type" "ialuX")])
883 ;; ??? Combine should canonicalize these next two to the same pattern.
884 (define_insn "*x_minus_y_minus_sltu"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
887 (match_operand:SI 2 "arith_operand" "rI"))
888 (ltu:SI (reg:CC 100) (const_int 0))))]
891 [(set_attr "type" "ialuX")])
893 (define_insn "*x_minus_sltu_plus_y"
894 [(set (match_operand:SI 0 "register_operand" "=r")
895 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
896 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
897 (match_operand:SI 2 "arith_operand" "rI"))))]
900 [(set_attr "type" "ialuX")])
902 (define_insn "*sgeu_plus_x"
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
905 (match_operand:SI 1 "register_operand" "r")))]
908 [(set_attr "type" "ialuX")])
910 (define_insn "*x_minus_sgeu"
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (minus:SI (match_operand:SI 1 "register_operand" "r")
913 (geu:SI (reg:CC 100) (const_int 0))))]
916 [(set_attr "type" "ialuX")])
919 [(set (match_operand:SI 0 "register_operand" "")
920 (match_operator:SI 2 "noov_compare_operator"
921 [(match_operand 1 "icc_or_fcc_register_operand" "")
924 && REGNO (operands[1]) == SPARC_ICC_REG
925 && (GET_MODE (operands[1]) == CCXmode
926 /* 32-bit LTU/GEU are better implemented using addx/subx. */
927 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
928 [(set (match_dup 0) (const_int 0))
930 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
936 ;; These control RTL generation for conditional jump insns
938 (define_expand "cbranchcc4"
940 (if_then_else (match_operator 0 "comparison_operator"
941 [(match_operand 1 "compare_operand" "")
942 (match_operand 2 "const_zero_operand" "")])
943 (label_ref (match_operand 3 "" ""))
948 (define_expand "cbranchsi4"
949 [(use (match_operator 0 "comparison_operator"
950 [(match_operand:SI 1 "compare_operand" "")
951 (match_operand:SI 2 "arith_operand" "")]))
952 (use (match_operand 3 ""))]
955 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
956 operands[1] = force_reg (SImode, operands[1]);
957 emit_conditional_branch_insn (operands);
961 (define_expand "cbranchdi4"
962 [(use (match_operator 0 "comparison_operator"
963 [(match_operand:DI 1 "compare_operand" "")
964 (match_operand:DI 2 "arith_operand" "")]))
965 (use (match_operand 3 ""))]
968 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
969 operands[1] = force_reg (DImode, operands[1]);
970 emit_conditional_branch_insn (operands);
974 (define_expand "cbranch<F:mode>4"
975 [(use (match_operator 0 "comparison_operator"
976 [(match_operand:F 1 "register_operand" "")
977 (match_operand:F 2 "register_operand" "")]))
978 (use (match_operand 3 ""))]
980 { emit_conditional_branch_insn (operands); DONE; })
983 ;; Now match both normal and inverted jump.
985 ;; XXX fpcmp nop braindamage
986 (define_insn "*normal_branch"
988 (if_then_else (match_operator 0 "noov_compare_operator"
989 [(reg 100) (const_int 0)])
990 (label_ref (match_operand 1 "" ""))
994 return output_cbranch (operands[0], operands[1], 1, 0,
995 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
998 [(set_attr "type" "branch")
999 (set_attr "branch_type" "icc")])
1001 ;; XXX fpcmp nop braindamage
1002 (define_insn "*inverted_branch"
1004 (if_then_else (match_operator 0 "noov_compare_operator"
1005 [(reg 100) (const_int 0)])
1007 (label_ref (match_operand 1 "" ""))))]
1010 return output_cbranch (operands[0], operands[1], 1, 1,
1011 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1014 [(set_attr "type" "branch")
1015 (set_attr "branch_type" "icc")])
1017 ;; XXX fpcmp nop braindamage
1018 (define_insn "*normal_fp_branch"
1020 (if_then_else (match_operator 1 "comparison_operator"
1021 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1023 (label_ref (match_operand 2 "" ""))
1027 return output_cbranch (operands[1], operands[2], 2, 0,
1028 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1031 [(set_attr "type" "branch")
1032 (set_attr "branch_type" "fcc")])
1034 ;; XXX fpcmp nop braindamage
1035 (define_insn "*inverted_fp_branch"
1037 (if_then_else (match_operator 1 "comparison_operator"
1038 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1041 (label_ref (match_operand 2 "" ""))))]
1044 return output_cbranch (operands[1], operands[2], 2, 1,
1045 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1048 [(set_attr "type" "branch")
1049 (set_attr "branch_type" "fcc")])
1051 ;; XXX fpcmp nop braindamage
1052 (define_insn "*normal_fpe_branch"
1054 (if_then_else (match_operator 1 "comparison_operator"
1055 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1057 (label_ref (match_operand 2 "" ""))
1061 return output_cbranch (operands[1], operands[2], 2, 0,
1062 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1065 [(set_attr "type" "branch")
1066 (set_attr "branch_type" "fcc")])
1068 ;; XXX fpcmp nop braindamage
1069 (define_insn "*inverted_fpe_branch"
1071 (if_then_else (match_operator 1 "comparison_operator"
1072 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1075 (label_ref (match_operand 2 "" ""))))]
1078 return output_cbranch (operands[1], operands[2], 2, 1,
1079 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1082 [(set_attr "type" "branch")
1083 (set_attr "branch_type" "fcc")])
1085 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1086 ;; in the architecture.
1088 ;; There are no 32 bit brreg insns.
1091 (define_insn "*normal_int_branch_sp64"
1093 (if_then_else (match_operator 0 "v9_register_compare_operator"
1094 [(match_operand:DI 1 "register_operand" "r")
1096 (label_ref (match_operand 2 "" ""))
1100 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1101 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1104 [(set_attr "type" "branch")
1105 (set_attr "branch_type" "reg")])
1108 (define_insn "*inverted_int_branch_sp64"
1110 (if_then_else (match_operator 0 "v9_register_compare_operator"
1111 [(match_operand:DI 1 "register_operand" "r")
1114 (label_ref (match_operand 2 "" ""))))]
1117 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1118 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1121 [(set_attr "type" "branch")
1122 (set_attr "branch_type" "reg")])
1125 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1126 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1127 ;; that adds the PC value at the call point to register #(operand 3).
1129 (define_insn "load_pcrel_sym<P:mode>"
1130 [(set (match_operand:P 0 "register_operand" "=r")
1131 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1132 (match_operand:P 2 "call_address_operand" "")
1133 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1134 (clobber (reg:P 15))]
1135 "REGNO (operands[0]) == INTVAL (operands[3])"
1137 if (flag_delayed_branch)
1138 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1140 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1142 [(set (attr "type") (const_string "multi"))
1143 (set (attr "length")
1144 (if_then_else (eq_attr "delayed_branch" "true")
1149 ;; Integer move instructions
1151 (define_expand "movqi"
1152 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1153 (match_operand:QI 1 "general_operand" ""))]
1156 if (sparc_expand_move (QImode, operands))
1160 (define_insn "*movqi_insn"
1161 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1162 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1163 "(register_operand (operands[0], QImode)
1164 || register_or_zero_operand (operands[1], QImode))"
1169 [(set_attr "type" "*,load,store")
1170 (set_attr "us3load_type" "*,3cycle,*")])
1172 (define_expand "movhi"
1173 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1174 (match_operand:HI 1 "general_operand" ""))]
1177 if (sparc_expand_move (HImode, operands))
1181 (define_insn "*movhi_insn"
1182 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1183 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1184 "(register_operand (operands[0], HImode)
1185 || register_or_zero_operand (operands[1], HImode))"
1188 sethi\t%%hi(%a1), %0
1191 [(set_attr "type" "*,*,load,store")
1192 (set_attr "us3load_type" "*,*,3cycle,*")])
1194 ;; We always work with constants here.
1195 (define_insn "*movhi_lo_sum"
1196 [(set (match_operand:HI 0 "register_operand" "=r")
1197 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1198 (match_operand:HI 2 "small_int_operand" "I")))]
1202 (define_expand "movsi"
1203 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1204 (match_operand:SI 1 "general_operand" ""))]
1207 if (sparc_expand_move (SImode, operands))
1211 (define_insn "*movsi_insn"
1212 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1213 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1214 "(register_operand (operands[0], SImode)
1215 || register_or_zero_operand (operands[1], SImode))"
1218 sethi\t%%hi(%a1), %0
1225 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1227 (define_insn "*movsi_lo_sum"
1228 [(set (match_operand:SI 0 "register_operand" "=r")
1229 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1230 (match_operand:SI 2 "immediate_operand" "in")))]
1232 "or\t%1, %%lo(%a2), %0")
1234 (define_insn "*movsi_high"
1235 [(set (match_operand:SI 0 "register_operand" "=r")
1236 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1238 "sethi\t%%hi(%a1), %0")
1240 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1241 ;; so that CSE won't optimize the address computation away.
1242 (define_insn "movsi_lo_sum_pic"
1243 [(set (match_operand:SI 0 "register_operand" "=r")
1244 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1245 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1248 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1249 return "xor\t%1, %%gdop_lox10(%a2), %0";
1251 return "or\t%1, %%lo(%a2), %0";
1255 (define_insn "movsi_high_pic"
1256 [(set (match_operand:SI 0 "register_operand" "=r")
1257 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1258 "flag_pic && check_pic (1)"
1260 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1261 return "sethi\t%%gdop_hix22(%a1), %0";
1263 return "sethi\t%%hi(%a1), %0";
1267 (define_insn "movsi_pic_gotdata_op"
1268 [(set (match_operand:SI 0 "register_operand" "=r")
1269 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1270 (match_operand:SI 2 "register_operand" "r")
1271 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1272 "flag_pic && check_pic (1)"
1274 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1275 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1277 return "ld\t[%1 + %2], %0";
1280 [(set_attr "type" "load")])
1282 (define_expand "movsi_pic_label_ref"
1283 [(set (match_dup 3) (high:SI
1284 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1285 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1286 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1287 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1288 (set (match_operand:SI 0 "register_operand" "=r")
1289 (minus:SI (match_dup 5) (match_dup 4)))]
1292 crtl->uses_pic_offset_table = 1;
1293 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1294 if (!can_create_pseudo_p ())
1296 operands[3] = operands[0];
1297 operands[4] = operands[0];
1301 operands[3] = gen_reg_rtx (SImode);
1302 operands[4] = gen_reg_rtx (SImode);
1304 operands[5] = pic_offset_table_rtx;
1307 (define_insn "*movsi_high_pic_label_ref"
1308 [(set (match_operand:SI 0 "register_operand" "=r")
1310 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1311 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1313 "sethi\t%%hi(%a2-(%a1-.)), %0")
1315 (define_insn "*movsi_lo_sum_pic_label_ref"
1316 [(set (match_operand:SI 0 "register_operand" "=r")
1317 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1318 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1319 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1321 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1323 ;; Set up the PIC register for VxWorks.
1325 (define_expand "vxworks_load_got"
1327 (high:SI (match_dup 1)))
1329 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1331 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1332 "TARGET_VXWORKS_RTP"
1334 operands[0] = pic_offset_table_rtx;
1335 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1336 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1339 (define_expand "movdi"
1340 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1341 (match_operand:DI 1 "general_operand" ""))]
1344 if (sparc_expand_move (DImode, operands))
1348 ;; Be careful, fmovd does not exist when !v9.
1349 ;; We match MEM moves directly when we have correct even
1350 ;; numbered registers, but fall into splits otherwise.
1351 ;; The constraint ordering here is really important to
1352 ;; avoid insane problems in reload, especially for patterns
1355 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1356 ;; (const_int -5016)))
1360 (define_insn "*movdi_insn_sp32"
1361 [(set (match_operand:DI 0 "nonimmediate_operand"
1362 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1363 (match_operand:DI 1 "input_operand"
1364 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1366 && (register_operand (operands[0], DImode)
1367 || register_or_zero_operand (operands[1], DImode))"
1381 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1382 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1384 (define_insn "*movdi_insn_sp32_v9"
1385 [(set (match_operand:DI 0 "nonimmediate_operand"
1386 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1387 (match_operand:DI 1 "input_operand"
1388 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1391 && (register_operand (operands[0], DImode)
1392 || register_or_zero_operand (operands[1], DImode))"
1409 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1410 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1411 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1413 (define_insn "*movdi_insn_sp64"
1414 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1415 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1417 && (register_operand (operands[0], DImode)
1418 || register_or_zero_operand (operands[1], DImode))"
1421 sethi\t%%hi(%a1), %0
1428 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1429 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1431 (define_expand "movdi_pic_label_ref"
1432 [(set (match_dup 3) (high:DI
1433 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1434 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1435 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1436 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1437 (set (match_operand:DI 0 "register_operand" "=r")
1438 (minus:DI (match_dup 5) (match_dup 4)))]
1439 "TARGET_ARCH64 && flag_pic"
1441 crtl->uses_pic_offset_table = 1;
1442 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1443 if (!can_create_pseudo_p ())
1445 operands[3] = operands[0];
1446 operands[4] = operands[0];
1450 operands[3] = gen_reg_rtx (DImode);
1451 operands[4] = gen_reg_rtx (DImode);
1453 operands[5] = pic_offset_table_rtx;
1456 (define_insn "*movdi_high_pic_label_ref"
1457 [(set (match_operand:DI 0 "register_operand" "=r")
1459 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1460 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1461 "TARGET_ARCH64 && flag_pic"
1462 "sethi\t%%hi(%a2-(%a1-.)), %0")
1464 (define_insn "*movdi_lo_sum_pic_label_ref"
1465 [(set (match_operand:DI 0 "register_operand" "=r")
1466 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1467 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1468 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1469 "TARGET_ARCH64 && flag_pic"
1470 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1472 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1473 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1475 (define_insn "movdi_lo_sum_pic"
1476 [(set (match_operand:DI 0 "register_operand" "=r")
1477 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1478 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1479 "TARGET_ARCH64 && flag_pic"
1481 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1482 return "xor\t%1, %%gdop_lox10(%a2), %0";
1484 return "or\t%1, %%lo(%a2), %0";
1488 (define_insn "movdi_high_pic"
1489 [(set (match_operand:DI 0 "register_operand" "=r")
1490 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1491 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1493 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1494 return "sethi\t%%gdop_hix22(%a1), %0";
1496 return "sethi\t%%hi(%a1), %0";
1500 (define_insn "movdi_pic_gotdata_op"
1501 [(set (match_operand:DI 0 "register_operand" "=r")
1502 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1503 (match_operand:DI 2 "register_operand" "r")
1504 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1505 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1507 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1508 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1510 return "ldx\t[%1 + %2], %0";
1513 [(set_attr "type" "load")])
1515 (define_insn "*sethi_di_medlow_embmedany_pic"
1516 [(set (match_operand:DI 0 "register_operand" "=r")
1517 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1518 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1519 "sethi\t%%hi(%a1), %0")
1521 (define_insn "*sethi_di_medlow"
1522 [(set (match_operand:DI 0 "register_operand" "=r")
1523 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1524 "TARGET_CM_MEDLOW && check_pic (1)"
1525 "sethi\t%%hi(%a1), %0")
1527 (define_insn "*losum_di_medlow"
1528 [(set (match_operand:DI 0 "register_operand" "=r")
1529 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1530 (match_operand:DI 2 "symbolic_operand" "")))]
1532 "or\t%1, %%lo(%a2), %0")
1534 (define_insn "seth44"
1535 [(set (match_operand:DI 0 "register_operand" "=r")
1536 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1538 "sethi\t%%h44(%a1), %0")
1540 (define_insn "setm44"
1541 [(set (match_operand:DI 0 "register_operand" "=r")
1542 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1543 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1545 "or\t%1, %%m44(%a2), %0")
1547 (define_insn "setl44"
1548 [(set (match_operand:DI 0 "register_operand" "=r")
1549 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1550 (match_operand:DI 2 "symbolic_operand" "")))]
1552 "or\t%1, %%l44(%a2), %0")
1554 (define_insn "sethh"
1555 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1558 "sethi\t%%hh(%a1), %0")
1560 (define_insn "setlm"
1561 [(set (match_operand:DI 0 "register_operand" "=r")
1562 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1564 "sethi\t%%lm(%a1), %0")
1566 (define_insn "sethm"
1567 [(set (match_operand:DI 0 "register_operand" "=r")
1568 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1569 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1571 "or\t%1, %%hm(%a2), %0")
1573 (define_insn "setlo"
1574 [(set (match_operand:DI 0 "register_operand" "=r")
1575 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1576 (match_operand:DI 2 "symbolic_operand" "")))]
1578 "or\t%1, %%lo(%a2), %0")
1580 (define_insn "embmedany_sethi"
1581 [(set (match_operand:DI 0 "register_operand" "=r")
1582 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1583 "TARGET_CM_EMBMEDANY && check_pic (1)"
1584 "sethi\t%%hi(%a1), %0")
1586 (define_insn "embmedany_losum"
1587 [(set (match_operand:DI 0 "register_operand" "=r")
1588 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1589 (match_operand:DI 2 "data_segment_operand" "")))]
1590 "TARGET_CM_EMBMEDANY"
1591 "add\t%1, %%lo(%a2), %0")
1593 (define_insn "embmedany_brsum"
1594 [(set (match_operand:DI 0 "register_operand" "=r")
1595 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1596 "TARGET_CM_EMBMEDANY"
1599 (define_insn "embmedany_textuhi"
1600 [(set (match_operand:DI 0 "register_operand" "=r")
1601 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1602 "TARGET_CM_EMBMEDANY && check_pic (1)"
1603 "sethi\t%%uhi(%a1), %0")
1605 (define_insn "embmedany_texthi"
1606 [(set (match_operand:DI 0 "register_operand" "=r")
1607 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1608 "TARGET_CM_EMBMEDANY && check_pic (1)"
1609 "sethi\t%%hi(%a1), %0")
1611 (define_insn "embmedany_textulo"
1612 [(set (match_operand:DI 0 "register_operand" "=r")
1613 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1614 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1615 "TARGET_CM_EMBMEDANY"
1616 "or\t%1, %%ulo(%a2), %0")
1618 (define_insn "embmedany_textlo"
1619 [(set (match_operand:DI 0 "register_operand" "=r")
1620 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1621 (match_operand:DI 2 "text_segment_operand" "")))]
1622 "TARGET_CM_EMBMEDANY"
1623 "or\t%1, %%lo(%a2), %0")
1625 ;; Now some patterns to help reload out a bit.
1626 (define_expand "reload_indi"
1627 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1628 (match_operand:DI 1 "immediate_operand" "")
1629 (match_operand:TI 2 "register_operand" "=&r")])]
1631 || TARGET_CM_EMBMEDANY)
1634 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1638 (define_expand "reload_outdi"
1639 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1640 (match_operand:DI 1 "immediate_operand" "")
1641 (match_operand:TI 2 "register_operand" "=&r")])]
1643 || TARGET_CM_EMBMEDANY)
1646 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1650 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1652 [(set (match_operand:DI 0 "register_operand" "")
1653 (match_operand:DI 1 "const_int_operand" ""))]
1654 "! TARGET_ARCH64 && reload_completed"
1655 [(clobber (const_int 0))]
1657 #if HOST_BITS_PER_WIDE_INT == 32
1658 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1659 (INTVAL (operands[1]) < 0) ?
1662 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1665 unsigned int low, high;
1667 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1668 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1669 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1671 /* Slick... but this trick loses if this subreg constant part
1672 can be done in one insn. */
1674 && ! SPARC_SETHI32_P (high)
1675 && ! SPARC_SIMM13_P (high))
1676 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1677 gen_highpart (SImode, operands[0])));
1679 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1685 [(set (match_operand:DI 0 "register_operand" "")
1686 (match_operand:DI 1 "const_double_operand" ""))]
1690 && ((GET_CODE (operands[0]) == REG
1691 && REGNO (operands[0]) < 32)
1692 || (GET_CODE (operands[0]) == SUBREG
1693 && GET_CODE (SUBREG_REG (operands[0])) == REG
1694 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1695 [(clobber (const_int 0))]
1697 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1698 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1700 /* Slick... but this trick loses if this subreg constant part
1701 can be done in one insn. */
1702 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1703 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1704 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1706 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1707 gen_highpart (SImode, operands[0])));
1711 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1712 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1718 [(set (match_operand:DI 0 "register_operand" "")
1719 (match_operand:DI 1 "register_operand" ""))]
1723 && ((GET_CODE (operands[0]) == REG
1724 && REGNO (operands[0]) < 32)
1725 || (GET_CODE (operands[0]) == SUBREG
1726 && GET_CODE (SUBREG_REG (operands[0])) == REG
1727 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1728 [(clobber (const_int 0))]
1730 rtx set_dest = operands[0];
1731 rtx set_src = operands[1];
1735 dest1 = gen_highpart (SImode, set_dest);
1736 dest2 = gen_lowpart (SImode, set_dest);
1737 src1 = gen_highpart (SImode, set_src);
1738 src2 = gen_lowpart (SImode, set_src);
1740 /* Now emit using the real source and destination we found, swapping
1741 the order if we detect overlap. */
1742 if (reg_overlap_mentioned_p (dest1, src2))
1744 emit_insn (gen_movsi (dest2, src2));
1745 emit_insn (gen_movsi (dest1, src1));
1749 emit_insn (gen_movsi (dest1, src1));
1750 emit_insn (gen_movsi (dest2, src2));
1755 ;; Now handle the cases of memory moves from/to non-even
1756 ;; DI mode register pairs.
1758 [(set (match_operand:DI 0 "register_operand" "")
1759 (match_operand:DI 1 "memory_operand" ""))]
1762 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1763 [(clobber (const_int 0))]
1765 rtx word0 = adjust_address (operands[1], SImode, 0);
1766 rtx word1 = adjust_address (operands[1], SImode, 4);
1767 rtx high_part = gen_highpart (SImode, operands[0]);
1768 rtx low_part = gen_lowpart (SImode, operands[0]);
1770 if (reg_overlap_mentioned_p (high_part, word1))
1772 emit_insn (gen_movsi (low_part, word1));
1773 emit_insn (gen_movsi (high_part, word0));
1777 emit_insn (gen_movsi (high_part, word0));
1778 emit_insn (gen_movsi (low_part, word1));
1784 [(set (match_operand:DI 0 "memory_operand" "")
1785 (match_operand:DI 1 "register_operand" ""))]
1788 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1789 [(clobber (const_int 0))]
1791 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1792 gen_highpart (SImode, operands[1])));
1793 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1794 gen_lowpart (SImode, operands[1])));
1799 [(set (match_operand:DI 0 "memory_operand" "")
1800 (match_operand:DI 1 "const_zero_operand" ""))]
1804 && ! mem_min_alignment (operands[0], 8)))
1805 && offsettable_memref_p (operands[0])"
1806 [(clobber (const_int 0))]
1808 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1809 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1814 ;; Floating point and vector move instructions
1816 ;; Yes, you guessed it right, the former movsf expander.
1817 (define_expand "mov<V32:mode>"
1818 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1819 (match_operand:V32 1 "general_operand" ""))]
1820 "<V32:MODE>mode == SFmode || TARGET_VIS"
1822 if (sparc_expand_move (<V32:MODE>mode, operands))
1826 (define_insn "*movsf_insn"
1827 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1828 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1830 && (register_operand (operands[0], <V32:MODE>mode)
1831 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1833 if (GET_CODE (operands[1]) == CONST_DOUBLE
1834 && (which_alternative == 2
1835 || which_alternative == 3
1836 || which_alternative == 4))
1841 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1842 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1843 operands[1] = GEN_INT (i);
1846 switch (which_alternative)
1849 return "fzeros\t%0";
1851 return "fmovs\t%1, %0";
1853 return "mov\t%1, %0";
1855 return "sethi\t%%hi(%a1), %0";
1860 return "ld\t%1, %0";
1863 return "st\t%r1, %0";
1868 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1870 ;; Exactly the same as above, except that all `f' cases are deleted.
1871 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1874 (define_insn "*movsf_insn_no_fpu"
1875 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1876 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1878 && (register_operand (operands[0], SFmode)
1879 || register_or_zero_operand (operands[1], SFmode))"
1881 if (GET_CODE (operands[1]) == CONST_DOUBLE
1882 && (which_alternative == 0
1883 || which_alternative == 1
1884 || which_alternative == 2))
1889 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1890 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1891 operands[1] = GEN_INT (i);
1894 switch (which_alternative)
1897 return "mov\t%1, %0";
1899 return "sethi\t%%hi(%a1), %0";
1903 return "ld\t%1, %0";
1905 return "st\t%r1, %0";
1910 [(set_attr "type" "*,*,*,load,store")])
1912 ;; The following 3 patterns build SFmode constants in integer registers.
1914 (define_insn "*movsf_lo_sum"
1915 [(set (match_operand:SF 0 "register_operand" "=r")
1916 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1917 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1923 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1924 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1925 operands[2] = GEN_INT (i);
1926 return "or\t%1, %%lo(%a2), %0";
1929 (define_insn "*movsf_high"
1930 [(set (match_operand:SF 0 "register_operand" "=r")
1931 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1937 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1938 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1939 operands[1] = GEN_INT (i);
1940 return "sethi\t%%hi(%1), %0";
1944 [(set (match_operand:SF 0 "register_operand" "")
1945 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1946 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1947 [(set (match_dup 0) (high:SF (match_dup 1)))
1948 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1950 ;; Yes, you again guessed it right, the former movdf expander.
1951 (define_expand "mov<V64:mode>"
1952 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1953 (match_operand:V64 1 "general_operand" ""))]
1954 "<V64:MODE>mode == DFmode || TARGET_VIS"
1956 if (sparc_expand_move (<V64:MODE>mode, operands))
1960 ;; Be careful, fmovd does not exist when !v9.
1961 (define_insn "*movdf_insn_sp32"
1962 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1963 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1966 && (register_operand (operands[0], DFmode)
1967 || register_or_zero_operand (operands[1], DFmode))"
1979 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1980 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1982 (define_insn "*movdf_insn_sp32_no_fpu"
1983 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1984 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1987 && (register_operand (operands[0], DFmode)
1988 || register_or_zero_operand (operands[1], DFmode))"
1995 [(set_attr "type" "load,store,*,*,*")
1996 (set_attr "length" "*,*,2,2,2")])
1998 ;; We have available v9 double floats but not 64-bit integer registers.
1999 (define_insn "*movdf_insn_sp32_v9"
2000 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2001 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2005 && (register_operand (operands[0], <V64:MODE>mode)
2006 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2018 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2019 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2020 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2022 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2023 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2024 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2028 && (register_operand (operands[0], DFmode)
2029 || register_or_zero_operand (operands[1], DFmode))"
2036 [(set_attr "type" "load,store,store,*,*")
2037 (set_attr "length" "*,*,*,2,2")])
2039 ;; We have available both v9 double floats and 64-bit integer registers.
2040 (define_insn "*movdf_insn_sp64"
2041 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2042 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2045 && (register_operand (operands[0], <V64:MODE>mode)
2046 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2056 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2057 (set_attr "length" "*,*,*,*,*,*,*,2")
2058 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2060 (define_insn "*movdf_insn_sp64_no_fpu"
2061 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2062 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2065 && (register_operand (operands[0], DFmode)
2066 || register_or_zero_operand (operands[1], DFmode))"
2071 [(set_attr "type" "*,load,store")])
2073 ;; This pattern builds V64mode constants in integer registers.
2075 [(set (match_operand:V64 0 "register_operand" "")
2076 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2078 && (GET_CODE (operands[0]) == REG
2079 && REGNO (operands[0]) < 32)
2080 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2081 && reload_completed"
2082 [(clobber (const_int 0))]
2084 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2088 #if HOST_BITS_PER_WIDE_INT == 32
2091 enum machine_mode mode = GET_MODE (operands[1]);
2092 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2093 emit_insn (gen_movdi (operands[0], tem));
2098 enum machine_mode mode = GET_MODE (operands[1]);
2099 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2100 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2102 gcc_assert (GET_CODE (hi) == CONST_INT);
2103 gcc_assert (GET_CODE (lo) == CONST_INT);
2105 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2107 /* Slick... but this trick loses if this subreg constant part
2108 can be done in one insn. */
2110 && ! SPARC_SETHI32_P (INTVAL (hi))
2111 && ! SPARC_SIMM13_P (INTVAL (hi)))
2113 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2114 gen_highpart (SImode, operands[0])));
2118 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2124 ;; Ok, now the splits to handle all the multi insn and
2125 ;; mis-aligned memory address cases.
2126 ;; In these splits please take note that we must be
2127 ;; careful when V9 but not ARCH64 because the integer
2128 ;; register DFmode cases must be handled.
2130 [(set (match_operand:V64 0 "register_operand" "")
2131 (match_operand:V64 1 "register_operand" ""))]
2134 && ((GET_CODE (operands[0]) == REG
2135 && REGNO (operands[0]) < 32)
2136 || (GET_CODE (operands[0]) == SUBREG
2137 && GET_CODE (SUBREG_REG (operands[0])) == REG
2138 && REGNO (SUBREG_REG (operands[0])) < 32))))
2139 && reload_completed"
2140 [(clobber (const_int 0))]
2142 rtx set_dest = operands[0];
2143 rtx set_src = operands[1];
2146 enum machine_mode half_mode;
2148 /* We can be expanded for DFmode or integral vector modes. */
2149 if (<V64:MODE>mode == DFmode)
2154 dest1 = gen_highpart (half_mode, set_dest);
2155 dest2 = gen_lowpart (half_mode, set_dest);
2156 src1 = gen_highpart (half_mode, set_src);
2157 src2 = gen_lowpart (half_mode, set_src);
2159 /* Now emit using the real source and destination we found, swapping
2160 the order if we detect overlap. */
2161 if (reg_overlap_mentioned_p (dest1, src2))
2163 emit_move_insn_1 (dest2, src2);
2164 emit_move_insn_1 (dest1, src1);
2168 emit_move_insn_1 (dest1, src1);
2169 emit_move_insn_1 (dest2, src2);
2175 [(set (match_operand:V64 0 "register_operand" "")
2176 (match_operand:V64 1 "memory_operand" ""))]
2179 && (((REGNO (operands[0]) % 2) != 0)
2180 || ! mem_min_alignment (operands[1], 8))
2181 && offsettable_memref_p (operands[1])"
2182 [(clobber (const_int 0))]
2184 enum machine_mode half_mode;
2187 /* We can be expanded for DFmode or integral vector modes. */
2188 if (<V64:MODE>mode == DFmode)
2193 word0 = adjust_address (operands[1], half_mode, 0);
2194 word1 = adjust_address (operands[1], half_mode, 4);
2196 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2198 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2199 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2203 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2204 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2210 [(set (match_operand:V64 0 "memory_operand" "")
2211 (match_operand:V64 1 "register_operand" ""))]
2214 && (((REGNO (operands[1]) % 2) != 0)
2215 || ! mem_min_alignment (operands[0], 8))
2216 && offsettable_memref_p (operands[0])"
2217 [(clobber (const_int 0))]
2219 enum machine_mode half_mode;
2222 /* We can be expanded for DFmode or integral vector modes. */
2223 if (<V64:MODE>mode == DFmode)
2228 word0 = adjust_address (operands[0], half_mode, 0);
2229 word1 = adjust_address (operands[0], half_mode, 4);
2231 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2232 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2237 [(set (match_operand:V64 0 "memory_operand" "")
2238 (match_operand:V64 1 "const_zero_operand" ""))]
2242 && ! mem_min_alignment (operands[0], 8)))
2243 && offsettable_memref_p (operands[0])"
2244 [(clobber (const_int 0))]
2246 enum machine_mode half_mode;
2249 /* We can be expanded for DFmode or integral vector modes. */
2250 if (<V64:MODE>mode == DFmode)
2255 dest1 = adjust_address (operands[0], half_mode, 0);
2256 dest2 = adjust_address (operands[0], half_mode, 4);
2258 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2259 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2264 [(set (match_operand:V64 0 "register_operand" "")
2265 (match_operand:V64 1 "const_zero_operand" ""))]
2268 && ((GET_CODE (operands[0]) == REG
2269 && REGNO (operands[0]) < 32)
2270 || (GET_CODE (operands[0]) == SUBREG
2271 && GET_CODE (SUBREG_REG (operands[0])) == REG
2272 && REGNO (SUBREG_REG (operands[0])) < 32))"
2273 [(clobber (const_int 0))]
2275 enum machine_mode half_mode;
2276 rtx set_dest = operands[0];
2279 /* We can be expanded for DFmode or integral vector modes. */
2280 if (<V64:MODE>mode == DFmode)
2285 dest1 = gen_highpart (half_mode, set_dest);
2286 dest2 = gen_lowpart (half_mode, set_dest);
2287 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2288 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2292 (define_expand "movtf"
2293 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2294 (match_operand:TF 1 "general_operand" ""))]
2297 if (sparc_expand_move (TFmode, operands))
2301 (define_insn "*movtf_insn_sp32"
2302 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2303 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2306 && (register_operand (operands[0], TFmode)
2307 || register_or_zero_operand (operands[1], TFmode))"
2309 [(set_attr "length" "4")])
2311 ;; Exactly the same as above, except that all `e' cases are deleted.
2312 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2315 (define_insn "*movtf_insn_sp32_no_fpu"
2316 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2317 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2320 && (register_operand (operands[0], TFmode)
2321 || register_or_zero_operand (operands[1], TFmode))"
2323 [(set_attr "length" "4")])
2325 (define_insn "*movtf_insn_sp64"
2326 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2327 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2330 && ! TARGET_HARD_QUAD
2331 && (register_operand (operands[0], TFmode)
2332 || register_or_zero_operand (operands[1], TFmode))"
2334 [(set_attr "length" "2")])
2336 (define_insn "*movtf_insn_sp64_hq"
2337 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2338 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2342 && (register_operand (operands[0], TFmode)
2343 || register_or_zero_operand (operands[1], TFmode))"
2351 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2352 (set_attr "length" "2,*,*,*,2,2")])
2354 (define_insn "*movtf_insn_sp64_no_fpu"
2355 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2356 (match_operand:TF 1 "input_operand" "orG,rG"))]
2359 && (register_operand (operands[0], TFmode)
2360 || register_or_zero_operand (operands[1], TFmode))"
2362 [(set_attr "length" "2")])
2364 ;; Now all the splits to handle multi-insn TF mode moves.
2366 [(set (match_operand:TF 0 "register_operand" "")
2367 (match_operand:TF 1 "register_operand" ""))]
2371 && ! TARGET_HARD_QUAD)
2372 || ! fp_register_operand (operands[0], TFmode))"
2373 [(clobber (const_int 0))]
2375 rtx set_dest = operands[0];
2376 rtx set_src = operands[1];
2380 dest1 = gen_df_reg (set_dest, 0);
2381 dest2 = gen_df_reg (set_dest, 1);
2382 src1 = gen_df_reg (set_src, 0);
2383 src2 = gen_df_reg (set_src, 1);
2385 /* Now emit using the real source and destination we found, swapping
2386 the order if we detect overlap. */
2387 if (reg_overlap_mentioned_p (dest1, src2))
2389 emit_insn (gen_movdf (dest2, src2));
2390 emit_insn (gen_movdf (dest1, src1));
2394 emit_insn (gen_movdf (dest1, src1));
2395 emit_insn (gen_movdf (dest2, src2));
2401 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2402 (match_operand:TF 1 "const_zero_operand" ""))]
2404 [(clobber (const_int 0))]
2406 rtx set_dest = operands[0];
2409 switch (GET_CODE (set_dest))
2412 dest1 = gen_df_reg (set_dest, 0);
2413 dest2 = gen_df_reg (set_dest, 1);
2416 dest1 = adjust_address (set_dest, DFmode, 0);
2417 dest2 = adjust_address (set_dest, DFmode, 8);
2423 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2424 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2429 [(set (match_operand:TF 0 "register_operand" "")
2430 (match_operand:TF 1 "memory_operand" ""))]
2432 && offsettable_memref_p (operands[1])
2434 || ! TARGET_HARD_QUAD
2435 || ! fp_register_operand (operands[0], TFmode)))"
2436 [(clobber (const_int 0))]
2438 rtx word0 = adjust_address (operands[1], DFmode, 0);
2439 rtx word1 = adjust_address (operands[1], DFmode, 8);
2440 rtx set_dest, dest1, dest2;
2442 set_dest = operands[0];
2444 dest1 = gen_df_reg (set_dest, 0);
2445 dest2 = gen_df_reg (set_dest, 1);
2447 /* Now output, ordering such that we don't clobber any registers
2448 mentioned in the address. */
2449 if (reg_overlap_mentioned_p (dest1, word1))
2452 emit_insn (gen_movdf (dest2, word1));
2453 emit_insn (gen_movdf (dest1, word0));
2457 emit_insn (gen_movdf (dest1, word0));
2458 emit_insn (gen_movdf (dest2, word1));
2464 [(set (match_operand:TF 0 "memory_operand" "")
2465 (match_operand:TF 1 "register_operand" ""))]
2467 && offsettable_memref_p (operands[0])
2469 || ! TARGET_HARD_QUAD
2470 || ! fp_register_operand (operands[1], TFmode)))"
2471 [(clobber (const_int 0))]
2473 rtx set_src = operands[1];
2475 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2476 gen_df_reg (set_src, 0)));
2477 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2478 gen_df_reg (set_src, 1)));
2483 ;; SPARC-V9 conditional move instructions
2485 ;; We can handle larger constants here for some flavors, but for now we keep
2486 ;; it simple and only allow those constants supported by all flavors.
2487 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2488 ;; 3 contains the constant if one is present, but we handle either for
2489 ;; generality (sparc.c puts a constant in operand 2).
2491 (define_expand "mov<I:mode>cc"
2492 [(set (match_operand:I 0 "register_operand" "")
2493 (if_then_else:I (match_operand 1 "comparison_operator" "")
2494 (match_operand:I 2 "arith10_operand" "")
2495 (match_operand:I 3 "arith10_operand" "")))]
2496 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2498 enum rtx_code code = GET_CODE (operands[1]);
2501 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2505 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2507 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2508 GET_CODE (operands[1]));
2510 if (XEXP (operands[1], 1) == const0_rtx
2511 && GET_CODE (XEXP (operands[1], 0)) == REG
2512 && GET_MODE (XEXP (operands[1], 0)) == DImode
2513 && v9_regcmp_p (code))
2514 cc_reg = XEXP (operands[1], 0);
2516 cc_reg = gen_compare_reg (operands[1]);
2518 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2521 (define_expand "mov<F:mode>cc"
2522 [(set (match_operand:F 0 "register_operand" "")
2523 (if_then_else:F (match_operand 1 "comparison_operator" "")
2524 (match_operand:F 2 "register_operand" "")
2525 (match_operand:F 3 "register_operand" "")))]
2526 "TARGET_V9 && TARGET_FPU"
2528 enum rtx_code code = GET_CODE (operands[1]);
2531 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2535 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2537 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2538 GET_CODE (operands[1]));
2540 if (XEXP (operands[1], 1) == const0_rtx
2541 && GET_CODE (XEXP (operands[1], 0)) == REG
2542 && GET_MODE (XEXP (operands[1], 0)) == DImode
2543 && v9_regcmp_p (code))
2544 cc_reg = XEXP (operands[1], 0);
2546 cc_reg = gen_compare_reg (operands[1]);
2548 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2551 ;; Conditional move define_insns
2553 (define_insn "*mov<I:mode>_cc_v9"
2554 [(set (match_operand:I 0 "register_operand" "=r,r")
2555 (if_then_else:I (match_operator 1 "comparison_operator"
2556 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2558 (match_operand:I 3 "arith11_operand" "rL,0")
2559 (match_operand:I 4 "arith11_operand" "0,rL")))]
2560 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2563 mov%c1\t%x2, %4, %0"
2564 [(set_attr "type" "cmove")])
2566 (define_insn "*mov<I:mode>_cc_reg_sp64"
2567 [(set (match_operand:I 0 "register_operand" "=r,r")
2568 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2569 [(match_operand:DI 2 "register_operand" "r,r")
2571 (match_operand:I 3 "arith10_operand" "rM,0")
2572 (match_operand:I 4 "arith10_operand" "0,rM")))]
2575 movr%D1\t%2, %r3, %0
2576 movr%d1\t%2, %r4, %0"
2577 [(set_attr "type" "cmove")])
2579 (define_insn "*movsf_cc_v9"
2580 [(set (match_operand:SF 0 "register_operand" "=f,f")
2581 (if_then_else:SF (match_operator 1 "comparison_operator"
2582 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2584 (match_operand:SF 3 "register_operand" "f,0")
2585 (match_operand:SF 4 "register_operand" "0,f")))]
2586 "TARGET_V9 && TARGET_FPU"
2588 fmovs%C1\t%x2, %3, %0
2589 fmovs%c1\t%x2, %4, %0"
2590 [(set_attr "type" "fpcmove")])
2592 (define_insn "*movsf_cc_reg_sp64"
2593 [(set (match_operand:SF 0 "register_operand" "=f,f")
2594 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2595 [(match_operand:DI 2 "register_operand" "r,r")
2597 (match_operand:SF 3 "register_operand" "f,0")
2598 (match_operand:SF 4 "register_operand" "0,f")))]
2599 "TARGET_ARCH64 && TARGET_FPU"
2601 fmovrs%D1\t%2, %3, %0
2602 fmovrs%d1\t%2, %4, %0"
2603 [(set_attr "type" "fpcrmove")])
2605 ;; Named because invoked by movtf_cc_v9
2606 (define_insn "movdf_cc_v9"
2607 [(set (match_operand:DF 0 "register_operand" "=e,e")
2608 (if_then_else:DF (match_operator 1 "comparison_operator"
2609 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2611 (match_operand:DF 3 "register_operand" "e,0")
2612 (match_operand:DF 4 "register_operand" "0,e")))]
2613 "TARGET_V9 && TARGET_FPU"
2615 fmovd%C1\t%x2, %3, %0
2616 fmovd%c1\t%x2, %4, %0"
2617 [(set_attr "type" "fpcmove")
2618 (set_attr "fptype" "double")])
2620 ;; Named because invoked by movtf_cc_reg_sp64
2621 (define_insn "movdf_cc_reg_sp64"
2622 [(set (match_operand:DF 0 "register_operand" "=e,e")
2623 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2624 [(match_operand:DI 2 "register_operand" "r,r")
2626 (match_operand:DF 3 "register_operand" "e,0")
2627 (match_operand:DF 4 "register_operand" "0,e")))]
2628 "TARGET_ARCH64 && TARGET_FPU"
2630 fmovrd%D1\t%2, %3, %0
2631 fmovrd%d1\t%2, %4, %0"
2632 [(set_attr "type" "fpcrmove")
2633 (set_attr "fptype" "double")])
2635 (define_insn "*movtf_cc_hq_v9"
2636 [(set (match_operand:TF 0 "register_operand" "=e,e")
2637 (if_then_else:TF (match_operator 1 "comparison_operator"
2638 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2640 (match_operand:TF 3 "register_operand" "e,0")
2641 (match_operand:TF 4 "register_operand" "0,e")))]
2642 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2644 fmovq%C1\t%x2, %3, %0
2645 fmovq%c1\t%x2, %4, %0"
2646 [(set_attr "type" "fpcmove")])
2648 (define_insn "*movtf_cc_reg_hq_sp64"
2649 [(set (match_operand:TF 0 "register_operand" "=e,e")
2650 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2651 [(match_operand:DI 2 "register_operand" "r,r")
2653 (match_operand:TF 3 "register_operand" "e,0")
2654 (match_operand:TF 4 "register_operand" "0,e")))]
2655 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2657 fmovrq%D1\t%2, %3, %0
2658 fmovrq%d1\t%2, %4, %0"
2659 [(set_attr "type" "fpcrmove")])
2661 (define_insn_and_split "*movtf_cc_v9"
2662 [(set (match_operand:TF 0 "register_operand" "=e,e")
2663 (if_then_else:TF (match_operator 1 "comparison_operator"
2664 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2666 (match_operand:TF 3 "register_operand" "e,0")
2667 (match_operand:TF 4 "register_operand" "0,e")))]
2668 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2670 "&& reload_completed"
2671 [(clobber (const_int 0))]
2673 rtx set_dest = operands[0];
2674 rtx set_srca = operands[3];
2675 rtx set_srcb = operands[4];
2676 int third = rtx_equal_p (set_dest, set_srca);
2678 rtx srca1, srca2, srcb1, srcb2;
2680 dest1 = gen_df_reg (set_dest, 0);
2681 dest2 = gen_df_reg (set_dest, 1);
2682 srca1 = gen_df_reg (set_srca, 0);
2683 srca2 = gen_df_reg (set_srca, 1);
2684 srcb1 = gen_df_reg (set_srcb, 0);
2685 srcb2 = gen_df_reg (set_srcb, 1);
2687 /* Now emit using the real source and destination we found, swapping
2688 the order if we detect overlap. */
2689 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2690 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2692 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2693 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2697 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2698 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2702 [(set_attr "length" "2")])
2704 (define_insn_and_split "*movtf_cc_reg_sp64"
2705 [(set (match_operand:TF 0 "register_operand" "=e,e")
2706 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2707 [(match_operand:DI 2 "register_operand" "r,r")
2709 (match_operand:TF 3 "register_operand" "e,0")
2710 (match_operand:TF 4 "register_operand" "0,e")))]
2711 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2713 "&& reload_completed"
2714 [(clobber (const_int 0))]
2716 rtx set_dest = operands[0];
2717 rtx set_srca = operands[3];
2718 rtx set_srcb = operands[4];
2719 int third = rtx_equal_p (set_dest, set_srca);
2721 rtx srca1, srca2, srcb1, srcb2;
2723 dest1 = gen_df_reg (set_dest, 0);
2724 dest2 = gen_df_reg (set_dest, 1);
2725 srca1 = gen_df_reg (set_srca, 0);
2726 srca2 = gen_df_reg (set_srca, 1);
2727 srcb1 = gen_df_reg (set_srcb, 0);
2728 srcb2 = gen_df_reg (set_srcb, 1);
2730 /* Now emit using the real source and destination we found, swapping
2731 the order if we detect overlap. */
2732 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2733 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2735 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2736 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2740 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2741 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2745 [(set_attr "length" "2")])
2748 ;; Zero-extension instructions
2750 ;; These patterns originally accepted general_operands, however, slightly
2751 ;; better code is generated by only accepting register_operands, and then
2752 ;; letting combine generate the ldu[hb] insns.
2754 (define_expand "zero_extendhisi2"
2755 [(set (match_operand:SI 0 "register_operand" "")
2756 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2759 rtx temp = gen_reg_rtx (SImode);
2760 rtx shift_16 = GEN_INT (16);
2761 int op1_subbyte = 0;
2763 if (GET_CODE (operand1) == SUBREG)
2765 op1_subbyte = SUBREG_BYTE (operand1);
2766 op1_subbyte /= GET_MODE_SIZE (SImode);
2767 op1_subbyte *= GET_MODE_SIZE (SImode);
2768 operand1 = XEXP (operand1, 0);
2771 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2773 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2777 (define_insn "*zero_extendhisi2_insn"
2778 [(set (match_operand:SI 0 "register_operand" "=r")
2779 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2782 [(set_attr "type" "load")
2783 (set_attr "us3load_type" "3cycle")])
2785 (define_expand "zero_extendqihi2"
2786 [(set (match_operand:HI 0 "register_operand" "")
2787 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2791 (define_insn "*zero_extendqihi2_insn"
2792 [(set (match_operand:HI 0 "register_operand" "=r,r")
2793 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2794 "GET_CODE (operands[1]) != CONST_INT"
2798 [(set_attr "type" "*,load")
2799 (set_attr "us3load_type" "*,3cycle")])
2801 (define_expand "zero_extendqisi2"
2802 [(set (match_operand:SI 0 "register_operand" "")
2803 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2807 (define_insn "*zero_extendqisi2_insn"
2808 [(set (match_operand:SI 0 "register_operand" "=r,r")
2809 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2810 "GET_CODE (operands[1]) != CONST_INT"
2814 [(set_attr "type" "*,load")
2815 (set_attr "us3load_type" "*,3cycle")])
2817 (define_expand "zero_extendqidi2"
2818 [(set (match_operand:DI 0 "register_operand" "")
2819 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2823 (define_insn "*zero_extendqidi2_insn"
2824 [(set (match_operand:DI 0 "register_operand" "=r,r")
2825 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2826 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2830 [(set_attr "type" "*,load")
2831 (set_attr "us3load_type" "*,3cycle")])
2833 (define_expand "zero_extendhidi2"
2834 [(set (match_operand:DI 0 "register_operand" "")
2835 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2838 rtx temp = gen_reg_rtx (DImode);
2839 rtx shift_48 = GEN_INT (48);
2840 int op1_subbyte = 0;
2842 if (GET_CODE (operand1) == SUBREG)
2844 op1_subbyte = SUBREG_BYTE (operand1);
2845 op1_subbyte /= GET_MODE_SIZE (DImode);
2846 op1_subbyte *= GET_MODE_SIZE (DImode);
2847 operand1 = XEXP (operand1, 0);
2850 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2852 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2856 (define_insn "*zero_extendhidi2_insn"
2857 [(set (match_operand:DI 0 "register_operand" "=r")
2858 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2861 [(set_attr "type" "load")
2862 (set_attr "us3load_type" "3cycle")])
2864 ;; ??? Write truncdisi pattern using sra?
2866 (define_expand "zero_extendsidi2"
2867 [(set (match_operand:DI 0 "register_operand" "")
2868 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2872 (define_insn "*zero_extendsidi2_insn_sp64"
2873 [(set (match_operand:DI 0 "register_operand" "=r,r")
2874 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2875 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2879 [(set_attr "type" "shift,load")])
2881 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2882 [(set (match_operand:DI 0 "register_operand" "=r")
2883 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2886 "&& reload_completed"
2887 [(set (match_dup 2) (match_dup 3))
2888 (set (match_dup 4) (match_dup 5))]
2892 dest1 = gen_highpart (SImode, operands[0]);
2893 dest2 = gen_lowpart (SImode, operands[0]);
2895 /* Swap the order in case of overlap. */
2896 if (REGNO (dest1) == REGNO (operands[1]))
2898 operands[2] = dest2;
2899 operands[3] = operands[1];
2900 operands[4] = dest1;
2901 operands[5] = const0_rtx;
2905 operands[2] = dest1;
2906 operands[3] = const0_rtx;
2907 operands[4] = dest2;
2908 operands[5] = operands[1];
2911 [(set_attr "length" "2")])
2913 ;; Simplify comparisons of extended values.
2915 (define_insn "*cmp_zero_extendqisi2"
2917 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2920 "andcc\t%0, 0xff, %%g0"
2921 [(set_attr "type" "compare")])
2923 (define_insn "*cmp_zero_qi"
2925 (compare:CC (match_operand:QI 0 "register_operand" "r")
2928 "andcc\t%0, 0xff, %%g0"
2929 [(set_attr "type" "compare")])
2931 (define_insn "*cmp_zero_extendqisi2_set"
2933 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2935 (set (match_operand:SI 0 "register_operand" "=r")
2936 (zero_extend:SI (match_dup 1)))]
2938 "andcc\t%1, 0xff, %0"
2939 [(set_attr "type" "compare")])
2941 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2943 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2946 (set (match_operand:SI 0 "register_operand" "=r")
2947 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2949 "andcc\t%1, 0xff, %0"
2950 [(set_attr "type" "compare")])
2952 (define_insn "*cmp_zero_extendqidi2"
2954 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2957 "andcc\t%0, 0xff, %%g0"
2958 [(set_attr "type" "compare")])
2960 (define_insn "*cmp_zero_qi_sp64"
2962 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2965 "andcc\t%0, 0xff, %%g0"
2966 [(set_attr "type" "compare")])
2968 (define_insn "*cmp_zero_extendqidi2_set"
2970 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2972 (set (match_operand:DI 0 "register_operand" "=r")
2973 (zero_extend:DI (match_dup 1)))]
2975 "andcc\t%1, 0xff, %0"
2976 [(set_attr "type" "compare")])
2978 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2980 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2983 (set (match_operand:DI 0 "register_operand" "=r")
2984 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2986 "andcc\t%1, 0xff, %0"
2987 [(set_attr "type" "compare")])
2989 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2991 (define_insn "*cmp_siqi_trunc"
2993 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2996 "andcc\t%0, 0xff, %%g0"
2997 [(set_attr "type" "compare")])
2999 (define_insn "*cmp_siqi_trunc_set"
3001 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3003 (set (match_operand:QI 0 "register_operand" "=r")
3004 (subreg:QI (match_dup 1) 3))]
3006 "andcc\t%1, 0xff, %0"
3007 [(set_attr "type" "compare")])
3009 (define_insn "*cmp_diqi_trunc"
3011 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3014 "andcc\t%0, 0xff, %%g0"
3015 [(set_attr "type" "compare")])
3017 (define_insn "*cmp_diqi_trunc_set"
3019 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3021 (set (match_operand:QI 0 "register_operand" "=r")
3022 (subreg:QI (match_dup 1) 7))]
3024 "andcc\t%1, 0xff, %0"
3025 [(set_attr "type" "compare")])
3028 ;; Sign-extension instructions
3030 ;; These patterns originally accepted general_operands, however, slightly
3031 ;; better code is generated by only accepting register_operands, and then
3032 ;; letting combine generate the lds[hb] insns.
3034 (define_expand "extendhisi2"
3035 [(set (match_operand:SI 0 "register_operand" "")
3036 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3039 rtx temp = gen_reg_rtx (SImode);
3040 rtx shift_16 = GEN_INT (16);
3041 int op1_subbyte = 0;
3043 if (GET_CODE (operand1) == SUBREG)
3045 op1_subbyte = SUBREG_BYTE (operand1);
3046 op1_subbyte /= GET_MODE_SIZE (SImode);
3047 op1_subbyte *= GET_MODE_SIZE (SImode);
3048 operand1 = XEXP (operand1, 0);
3051 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3053 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3057 (define_insn "*sign_extendhisi2_insn"
3058 [(set (match_operand:SI 0 "register_operand" "=r")
3059 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3062 [(set_attr "type" "sload")
3063 (set_attr "us3load_type" "3cycle")])
3065 (define_expand "extendqihi2"
3066 [(set (match_operand:HI 0 "register_operand" "")
3067 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3070 rtx temp = gen_reg_rtx (SImode);
3071 rtx shift_24 = GEN_INT (24);
3072 int op1_subbyte = 0;
3073 int op0_subbyte = 0;
3075 if (GET_CODE (operand1) == SUBREG)
3077 op1_subbyte = SUBREG_BYTE (operand1);
3078 op1_subbyte /= GET_MODE_SIZE (SImode);
3079 op1_subbyte *= GET_MODE_SIZE (SImode);
3080 operand1 = XEXP (operand1, 0);
3082 if (GET_CODE (operand0) == SUBREG)
3084 op0_subbyte = SUBREG_BYTE (operand0);
3085 op0_subbyte /= GET_MODE_SIZE (SImode);
3086 op0_subbyte *= GET_MODE_SIZE (SImode);
3087 operand0 = XEXP (operand0, 0);
3089 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3091 if (GET_MODE (operand0) != SImode)
3092 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3093 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3097 (define_insn "*sign_extendqihi2_insn"
3098 [(set (match_operand:HI 0 "register_operand" "=r")
3099 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3102 [(set_attr "type" "sload")
3103 (set_attr "us3load_type" "3cycle")])
3105 (define_expand "extendqisi2"
3106 [(set (match_operand:SI 0 "register_operand" "")
3107 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3110 rtx temp = gen_reg_rtx (SImode);
3111 rtx shift_24 = GEN_INT (24);
3112 int op1_subbyte = 0;
3114 if (GET_CODE (operand1) == SUBREG)
3116 op1_subbyte = SUBREG_BYTE (operand1);
3117 op1_subbyte /= GET_MODE_SIZE (SImode);
3118 op1_subbyte *= GET_MODE_SIZE (SImode);
3119 operand1 = XEXP (operand1, 0);
3122 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3124 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3128 (define_insn "*sign_extendqisi2_insn"
3129 [(set (match_operand:SI 0 "register_operand" "=r")
3130 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3133 [(set_attr "type" "sload")
3134 (set_attr "us3load_type" "3cycle")])
3136 (define_expand "extendqidi2"
3137 [(set (match_operand:DI 0 "register_operand" "")
3138 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3141 rtx temp = gen_reg_rtx (DImode);
3142 rtx shift_56 = GEN_INT (56);
3143 int op1_subbyte = 0;
3145 if (GET_CODE (operand1) == SUBREG)
3147 op1_subbyte = SUBREG_BYTE (operand1);
3148 op1_subbyte /= GET_MODE_SIZE (DImode);
3149 op1_subbyte *= GET_MODE_SIZE (DImode);
3150 operand1 = XEXP (operand1, 0);
3153 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3155 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3159 (define_insn "*sign_extendqidi2_insn"
3160 [(set (match_operand:DI 0 "register_operand" "=r")
3161 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3164 [(set_attr "type" "sload")
3165 (set_attr "us3load_type" "3cycle")])
3167 (define_expand "extendhidi2"
3168 [(set (match_operand:DI 0 "register_operand" "")
3169 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3172 rtx temp = gen_reg_rtx (DImode);
3173 rtx shift_48 = GEN_INT (48);
3174 int op1_subbyte = 0;
3176 if (GET_CODE (operand1) == SUBREG)
3178 op1_subbyte = SUBREG_BYTE (operand1);
3179 op1_subbyte /= GET_MODE_SIZE (DImode);
3180 op1_subbyte *= GET_MODE_SIZE (DImode);
3181 operand1 = XEXP (operand1, 0);
3184 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3186 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3190 (define_insn "*sign_extendhidi2_insn"
3191 [(set (match_operand:DI 0 "register_operand" "=r")
3192 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3195 [(set_attr "type" "sload")
3196 (set_attr "us3load_type" "3cycle")])
3198 (define_expand "extendsidi2"
3199 [(set (match_operand:DI 0 "register_operand" "")
3200 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3204 (define_insn "*sign_extendsidi2_insn"
3205 [(set (match_operand:DI 0 "register_operand" "=r,r")
3206 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3211 [(set_attr "type" "shift,sload")
3212 (set_attr "us3load_type" "*,3cycle")])
3215 ;; Special pattern for optimizing bit-field compares. This is needed
3216 ;; because combine uses this as a canonical form.
3218 (define_insn "*cmp_zero_extract"
3221 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3222 (match_operand:SI 1 "small_int_operand" "I")
3223 (match_operand:SI 2 "small_int_operand" "I"))
3225 "INTVAL (operands[2]) > 19"
3227 int len = INTVAL (operands[1]);
3228 int pos = 32 - INTVAL (operands[2]) - len;
3229 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3230 operands[1] = GEN_INT (mask);
3231 return "andcc\t%0, %1, %%g0";
3233 [(set_attr "type" "compare")])
3235 (define_insn "*cmp_zero_extract_sp64"
3238 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3239 (match_operand:SI 1 "small_int_operand" "I")
3240 (match_operand:SI 2 "small_int_operand" "I"))
3242 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3244 int len = INTVAL (operands[1]);
3245 int pos = 64 - INTVAL (operands[2]) - len;
3246 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3247 operands[1] = GEN_INT (mask);
3248 return "andcc\t%0, %1, %%g0";
3250 [(set_attr "type" "compare")])
3253 ;; Conversions between float, double and long double.
3255 (define_insn "extendsfdf2"
3256 [(set (match_operand:DF 0 "register_operand" "=e")
3258 (match_operand:SF 1 "register_operand" "f")))]
3261 [(set_attr "type" "fp")
3262 (set_attr "fptype" "double")])
3264 (define_expand "extendsftf2"
3265 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3267 (match_operand:SF 1 "register_operand" "")))]
3268 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3269 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3271 (define_insn "*extendsftf2_hq"
3272 [(set (match_operand:TF 0 "register_operand" "=e")
3274 (match_operand:SF 1 "register_operand" "f")))]
3275 "TARGET_FPU && TARGET_HARD_QUAD"
3277 [(set_attr "type" "fp")])
3279 (define_expand "extenddftf2"
3280 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3282 (match_operand:DF 1 "register_operand" "")))]
3283 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3284 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3286 (define_insn "*extenddftf2_hq"
3287 [(set (match_operand:TF 0 "register_operand" "=e")
3289 (match_operand:DF 1 "register_operand" "e")))]
3290 "TARGET_FPU && TARGET_HARD_QUAD"
3292 [(set_attr "type" "fp")])
3294 (define_insn "truncdfsf2"
3295 [(set (match_operand:SF 0 "register_operand" "=f")
3297 (match_operand:DF 1 "register_operand" "e")))]
3300 [(set_attr "type" "fp")
3301 (set_attr "fptype" "double")])
3303 (define_expand "trunctfsf2"
3304 [(set (match_operand:SF 0 "register_operand" "")
3306 (match_operand:TF 1 "general_operand" "")))]
3307 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3308 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3310 (define_insn "*trunctfsf2_hq"
3311 [(set (match_operand:SF 0 "register_operand" "=f")
3313 (match_operand:TF 1 "register_operand" "e")))]
3314 "TARGET_FPU && TARGET_HARD_QUAD"
3316 [(set_attr "type" "fp")])
3318 (define_expand "trunctfdf2"
3319 [(set (match_operand:DF 0 "register_operand" "")
3321 (match_operand:TF 1 "general_operand" "")))]
3322 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3323 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3325 (define_insn "*trunctfdf2_hq"
3326 [(set (match_operand:DF 0 "register_operand" "=e")
3328 (match_operand:TF 1 "register_operand" "e")))]
3329 "TARGET_FPU && TARGET_HARD_QUAD"
3331 [(set_attr "type" "fp")])
3334 ;; Conversion between fixed point and floating point.
3336 (define_insn "floatsisf2"
3337 [(set (match_operand:SF 0 "register_operand" "=f")
3338 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3341 [(set_attr "type" "fp")
3342 (set_attr "fptype" "double")])
3344 (define_insn "floatsidf2"
3345 [(set (match_operand:DF 0 "register_operand" "=e")
3346 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3349 [(set_attr "type" "fp")
3350 (set_attr "fptype" "double")])
3352 (define_expand "floatsitf2"
3353 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3354 (float:TF (match_operand:SI 1 "register_operand" "")))]
3355 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3356 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3358 (define_insn "*floatsitf2_hq"
3359 [(set (match_operand:TF 0 "register_operand" "=e")
3360 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3361 "TARGET_FPU && TARGET_HARD_QUAD"
3363 [(set_attr "type" "fp")])
3365 (define_expand "floatunssitf2"
3366 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3367 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3368 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3369 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3371 ;; Now the same for 64 bit sources.
3373 (define_insn "floatdisf2"
3374 [(set (match_operand:SF 0 "register_operand" "=f")
3375 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3376 "TARGET_V9 && TARGET_FPU"
3378 [(set_attr "type" "fp")
3379 (set_attr "fptype" "double")])
3381 (define_expand "floatunsdisf2"
3382 [(use (match_operand:SF 0 "register_operand" ""))
3383 (use (match_operand:DI 1 "general_operand" ""))]
3384 "TARGET_ARCH64 && TARGET_FPU"
3385 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3387 (define_insn "floatdidf2"
3388 [(set (match_operand:DF 0 "register_operand" "=e")
3389 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3390 "TARGET_V9 && TARGET_FPU"
3392 [(set_attr "type" "fp")
3393 (set_attr "fptype" "double")])
3395 (define_expand "floatunsdidf2"
3396 [(use (match_operand:DF 0 "register_operand" ""))
3397 (use (match_operand:DI 1 "general_operand" ""))]
3398 "TARGET_ARCH64 && TARGET_FPU"
3399 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3401 (define_expand "floatditf2"
3402 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3403 (float:TF (match_operand:DI 1 "register_operand" "")))]
3404 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3405 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3407 (define_insn "*floatditf2_hq"
3408 [(set (match_operand:TF 0 "register_operand" "=e")
3409 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3410 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3412 [(set_attr "type" "fp")])
3414 (define_expand "floatunsditf2"
3415 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3416 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3417 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3418 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3420 ;; Convert a float to an actual integer.
3421 ;; Truncation is performed as part of the conversion.
3423 (define_insn "fix_truncsfsi2"
3424 [(set (match_operand:SI 0 "register_operand" "=f")
3425 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3428 [(set_attr "type" "fp")
3429 (set_attr "fptype" "double")])
3431 (define_insn "fix_truncdfsi2"
3432 [(set (match_operand:SI 0 "register_operand" "=f")
3433 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3436 [(set_attr "type" "fp")
3437 (set_attr "fptype" "double")])
3439 (define_expand "fix_trunctfsi2"
3440 [(set (match_operand:SI 0 "register_operand" "")
3441 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3442 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3443 "emit_tfmode_cvt (FIX, operands); DONE;")
3445 (define_insn "*fix_trunctfsi2_hq"
3446 [(set (match_operand:SI 0 "register_operand" "=f")
3447 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3448 "TARGET_FPU && TARGET_HARD_QUAD"
3450 [(set_attr "type" "fp")])
3452 (define_expand "fixuns_trunctfsi2"
3453 [(set (match_operand:SI 0 "register_operand" "")
3454 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3455 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3456 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3458 ;; Now the same, for V9 targets
3460 (define_insn "fix_truncsfdi2"
3461 [(set (match_operand:DI 0 "register_operand" "=e")
3462 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3463 "TARGET_V9 && TARGET_FPU"
3465 [(set_attr "type" "fp")
3466 (set_attr "fptype" "double")])
3468 (define_expand "fixuns_truncsfdi2"
3469 [(use (match_operand:DI 0 "register_operand" ""))
3470 (use (match_operand:SF 1 "general_operand" ""))]
3471 "TARGET_ARCH64 && TARGET_FPU"
3472 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3474 (define_insn "fix_truncdfdi2"
3475 [(set (match_operand:DI 0 "register_operand" "=e")
3476 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3477 "TARGET_V9 && TARGET_FPU"
3479 [(set_attr "type" "fp")
3480 (set_attr "fptype" "double")])
3482 (define_expand "fixuns_truncdfdi2"
3483 [(use (match_operand:DI 0 "register_operand" ""))
3484 (use (match_operand:DF 1 "general_operand" ""))]
3485 "TARGET_ARCH64 && TARGET_FPU"
3486 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3488 (define_expand "fix_trunctfdi2"
3489 [(set (match_operand:DI 0 "register_operand" "")
3490 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3491 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3492 "emit_tfmode_cvt (FIX, operands); DONE;")
3494 (define_insn "*fix_trunctfdi2_hq"
3495 [(set (match_operand:DI 0 "register_operand" "=e")
3496 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3497 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3499 [(set_attr "type" "fp")])
3501 (define_expand "fixuns_trunctfdi2"
3502 [(set (match_operand:DI 0 "register_operand" "")
3503 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3504 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3505 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3508 ;; Integer addition/subtraction instructions.
3510 (define_expand "adddi3"
3511 [(set (match_operand:DI 0 "register_operand" "")
3512 (plus:DI (match_operand:DI 1 "register_operand" "")
3513 (match_operand:DI 2 "arith_double_add_operand" "")))]
3516 if (! TARGET_ARCH64)
3518 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3519 gen_rtx_SET (VOIDmode, operands[0],
3520 gen_rtx_PLUS (DImode, operands[1],
3522 gen_rtx_CLOBBER (VOIDmode,
3523 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3528 (define_insn_and_split "*adddi3_insn_sp32"
3529 [(set (match_operand:DI 0 "register_operand" "=r")
3530 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3531 (match_operand:DI 2 "arith_double_operand" "rHI")))
3532 (clobber (reg:CC 100))]
3535 "&& reload_completed"
3536 [(parallel [(set (reg:CC_NOOV 100)
3537 (compare:CC_NOOV (plus:SI (match_dup 4)
3541 (plus:SI (match_dup 4) (match_dup 5)))])
3543 (plus:SI (plus:SI (match_dup 7)
3545 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3547 operands[3] = gen_lowpart (SImode, operands[0]);
3548 operands[4] = gen_lowpart (SImode, operands[1]);
3549 operands[5] = gen_lowpart (SImode, operands[2]);
3550 operands[6] = gen_highpart (SImode, operands[0]);
3551 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3552 #if HOST_BITS_PER_WIDE_INT == 32
3553 if (GET_CODE (operands[2]) == CONST_INT)
3555 if (INTVAL (operands[2]) < 0)
3556 operands[8] = constm1_rtx;
3558 operands[8] = const0_rtx;
3562 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3564 [(set_attr "length" "2")])
3566 ;; LTU here means "carry set"
3568 [(set (match_operand:SI 0 "register_operand" "=r")
3569 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3570 (match_operand:SI 2 "arith_operand" "rI"))
3571 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3574 [(set_attr "type" "ialuX")])
3576 (define_insn_and_split "*addx_extend_sp32"
3577 [(set (match_operand:DI 0 "register_operand" "=r")
3578 (zero_extend:DI (plus:SI (plus:SI
3579 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3580 (match_operand:SI 2 "arith_operand" "rI"))
3581 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3584 "&& reload_completed"
3585 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3586 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3587 (set (match_dup 4) (const_int 0))]
3588 "operands[3] = gen_lowpart (SImode, operands[0]);
3589 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3590 [(set_attr "length" "2")])
3592 (define_insn "*addx_extend_sp64"
3593 [(set (match_operand:DI 0 "register_operand" "=r")
3594 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3595 (match_operand:SI 2 "arith_operand" "rI"))
3596 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3599 [(set_attr "type" "ialuX")])
3601 (define_insn_and_split "*adddi3_extend_sp32"
3602 [(set (match_operand:DI 0 "register_operand" "=r")
3603 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3604 (match_operand:DI 2 "register_operand" "r")))
3605 (clobber (reg:CC 100))]
3608 "&& reload_completed"
3609 [(parallel [(set (reg:CC_NOOV 100)
3610 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3612 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3614 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3615 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3616 "operands[3] = gen_lowpart (SImode, operands[2]);
3617 operands[4] = gen_highpart (SImode, operands[2]);
3618 operands[5] = gen_lowpart (SImode, operands[0]);
3619 operands[6] = gen_highpart (SImode, operands[0]);"
3620 [(set_attr "length" "2")])
3622 (define_insn "*adddi3_sp64"
3623 [(set (match_operand:DI 0 "register_operand" "=r,r")
3624 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3625 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3631 (define_insn "addsi3"
3632 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3633 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3634 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3639 fpadd32s\t%1, %2, %0"
3640 [(set_attr "type" "*,*,fga")
3641 (set_attr "fptype" "*,*,single")])
3643 (define_insn "*cmp_cc_plus"
3644 [(set (reg:CC_NOOV 100)
3645 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3646 (match_operand:SI 1 "arith_operand" "rI"))
3649 "addcc\t%0, %1, %%g0"
3650 [(set_attr "type" "compare")])
3652 (define_insn "*cmp_ccx_plus"
3653 [(set (reg:CCX_NOOV 100)
3654 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3655 (match_operand:DI 1 "arith_operand" "rI"))
3658 "addcc\t%0, %1, %%g0"
3659 [(set_attr "type" "compare")])
3661 (define_insn "*cmp_cc_plus_set"
3662 [(set (reg:CC_NOOV 100)
3663 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3664 (match_operand:SI 2 "arith_operand" "rI"))
3666 (set (match_operand:SI 0 "register_operand" "=r")
3667 (plus:SI (match_dup 1) (match_dup 2)))]
3670 [(set_attr "type" "compare")])
3672 (define_insn "*cmp_ccx_plus_set"
3673 [(set (reg:CCX_NOOV 100)
3674 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3675 (match_operand:DI 2 "arith_operand" "rI"))
3677 (set (match_operand:DI 0 "register_operand" "=r")
3678 (plus:DI (match_dup 1) (match_dup 2)))]
3681 [(set_attr "type" "compare")])
3683 (define_expand "subdi3"
3684 [(set (match_operand:DI 0 "register_operand" "")
3685 (minus:DI (match_operand:DI 1 "register_operand" "")
3686 (match_operand:DI 2 "arith_double_add_operand" "")))]
3689 if (! TARGET_ARCH64)
3691 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3692 gen_rtx_SET (VOIDmode, operands[0],
3693 gen_rtx_MINUS (DImode, operands[1],
3695 gen_rtx_CLOBBER (VOIDmode,
3696 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3701 (define_insn_and_split "*subdi3_insn_sp32"
3702 [(set (match_operand:DI 0 "register_operand" "=r")
3703 (minus:DI (match_operand:DI 1 "register_operand" "r")
3704 (match_operand:DI 2 "arith_double_operand" "rHI")))
3705 (clobber (reg:CC 100))]
3708 "&& reload_completed"
3709 [(parallel [(set (reg:CC_NOOV 100)
3710 (compare:CC_NOOV (minus:SI (match_dup 4)
3714 (minus:SI (match_dup 4) (match_dup 5)))])
3716 (minus:SI (minus:SI (match_dup 7)
3718 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3720 operands[3] = gen_lowpart (SImode, operands[0]);
3721 operands[4] = gen_lowpart (SImode, operands[1]);
3722 operands[5] = gen_lowpart (SImode, operands[2]);
3723 operands[6] = gen_highpart (SImode, operands[0]);
3724 operands[7] = gen_highpart (SImode, operands[1]);
3725 #if HOST_BITS_PER_WIDE_INT == 32
3726 if (GET_CODE (operands[2]) == CONST_INT)
3728 if (INTVAL (operands[2]) < 0)
3729 operands[8] = constm1_rtx;
3731 operands[8] = const0_rtx;
3735 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3737 [(set_attr "length" "2")])
3739 ;; LTU here means "carry set"
3741 [(set (match_operand:SI 0 "register_operand" "=r")
3742 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3743 (match_operand:SI 2 "arith_operand" "rI"))
3744 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3747 [(set_attr "type" "ialuX")])
3749 (define_insn "*subx_extend_sp64"
3750 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3752 (match_operand:SI 2 "arith_operand" "rI"))
3753 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3756 [(set_attr "type" "ialuX")])
3758 (define_insn_and_split "*subx_extend"
3759 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3761 (match_operand:SI 2 "arith_operand" "rI"))
3762 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3765 "&& reload_completed"
3766 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3767 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3768 (set (match_dup 4) (const_int 0))]
3769 "operands[3] = gen_lowpart (SImode, operands[0]);
3770 operands[4] = gen_highpart (SImode, operands[0]);"
3771 [(set_attr "length" "2")])
3773 (define_insn_and_split "*subdi3_extend_sp32"
3774 [(set (match_operand:DI 0 "register_operand" "=r")
3775 (minus:DI (match_operand:DI 1 "register_operand" "r")
3776 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3777 (clobber (reg:CC 100))]
3780 "&& reload_completed"
3781 [(parallel [(set (reg:CC_NOOV 100)
3782 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3784 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3786 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3787 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3788 "operands[3] = gen_lowpart (SImode, operands[1]);
3789 operands[4] = gen_highpart (SImode, operands[1]);
3790 operands[5] = gen_lowpart (SImode, operands[0]);
3791 operands[6] = gen_highpart (SImode, operands[0]);"
3792 [(set_attr "length" "2")])
3794 (define_insn "*subdi3_sp64"
3795 [(set (match_operand:DI 0 "register_operand" "=r,r")
3796 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3797 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3803 (define_insn "subsi3"
3804 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3805 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3806 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3811 fpsub32s\t%1, %2, %0"
3812 [(set_attr "type" "*,*,fga")
3813 (set_attr "fptype" "*,*,single")])
3815 (define_insn "*cmp_minus_cc"
3816 [(set (reg:CC_NOOV 100)
3817 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3818 (match_operand:SI 1 "arith_operand" "rI"))
3821 "subcc\t%r0, %1, %%g0"
3822 [(set_attr "type" "compare")])
3824 (define_insn "*cmp_minus_ccx"
3825 [(set (reg:CCX_NOOV 100)
3826 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3827 (match_operand:DI 1 "arith_operand" "rI"))
3830 "subcc\t%0, %1, %%g0"
3831 [(set_attr "type" "compare")])
3833 (define_insn "cmp_minus_cc_set"
3834 [(set (reg:CC_NOOV 100)
3835 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3836 (match_operand:SI 2 "arith_operand" "rI"))
3838 (set (match_operand:SI 0 "register_operand" "=r")
3839 (minus:SI (match_dup 1) (match_dup 2)))]
3841 "subcc\t%r1, %2, %0"
3842 [(set_attr "type" "compare")])
3844 (define_insn "*cmp_minus_ccx_set"
3845 [(set (reg:CCX_NOOV 100)
3846 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3847 (match_operand:DI 2 "arith_operand" "rI"))
3849 (set (match_operand:DI 0 "register_operand" "=r")
3850 (minus:DI (match_dup 1) (match_dup 2)))]
3853 [(set_attr "type" "compare")])
3856 ;; Integer multiply/divide instructions.
3858 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3859 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3861 (define_insn "mulsi3"
3862 [(set (match_operand:SI 0 "register_operand" "=r")
3863 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3864 (match_operand:SI 2 "arith_operand" "rI")))]
3867 [(set_attr "type" "imul")])
3869 (define_expand "muldi3"
3870 [(set (match_operand:DI 0 "register_operand" "")
3871 (mult:DI (match_operand:DI 1 "arith_operand" "")
3872 (match_operand:DI 2 "arith_operand" "")))]
3873 "TARGET_ARCH64 || TARGET_V8PLUS"
3877 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3882 (define_insn "*muldi3_sp64"
3883 [(set (match_operand:DI 0 "register_operand" "=r")
3884 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3885 (match_operand:DI 2 "arith_operand" "rI")))]
3888 [(set_attr "type" "imul")])
3890 ;; V8plus wide multiply.
3892 (define_insn "muldi3_v8plus"
3893 [(set (match_operand:DI 0 "register_operand" "=r,h")
3894 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3895 (match_operand:DI 2 "arith_operand" "rI,rI")))
3896 (clobber (match_scratch:SI 3 "=&h,X"))
3897 (clobber (match_scratch:SI 4 "=&h,X"))]
3900 if (sparc_check_64 (operands[1], insn) <= 0)
3901 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3902 if (which_alternative == 1)
3903 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3904 if (GET_CODE (operands[2]) == CONST_INT)
3906 if (which_alternative == 1)
3907 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3909 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";
3911 else if (rtx_equal_p (operands[1], operands[2]))
3913 if (which_alternative == 1)
3914 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3916 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";
3918 if (sparc_check_64 (operands[2], insn) <= 0)
3919 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3920 if (which_alternative == 1)
3921 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";
3923 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";
3925 [(set_attr "type" "multi")
3926 (set_attr "length" "9,8")])
3928 (define_insn "*cmp_mul_set"
3930 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3931 (match_operand:SI 2 "arith_operand" "rI"))
3933 (set (match_operand:SI 0 "register_operand" "=r")
3934 (mult:SI (match_dup 1) (match_dup 2)))]
3935 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3936 "smulcc\t%1, %2, %0"
3937 [(set_attr "type" "imul")])
3939 (define_expand "mulsidi3"
3940 [(set (match_operand:DI 0 "register_operand" "")
3941 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3942 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3945 if (CONSTANT_P (operands[2]))
3948 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3950 else if (TARGET_ARCH32)
3951 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3954 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3960 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3965 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3966 ;; registers can hold 64-bit values in the V8plus environment.
3968 (define_insn "mulsidi3_v8plus"
3969 [(set (match_operand:DI 0 "register_operand" "=h,r")
3970 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3971 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3972 (clobber (match_scratch:SI 3 "=X,&h"))]
3975 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3976 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3977 [(set_attr "type" "multi")
3978 (set_attr "length" "2,3")])
3981 (define_insn "const_mulsidi3_v8plus"
3982 [(set (match_operand:DI 0 "register_operand" "=h,r")
3983 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3984 (match_operand:DI 2 "small_int_operand" "I,I")))
3985 (clobber (match_scratch:SI 3 "=X,&h"))]
3988 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3989 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3990 [(set_attr "type" "multi")
3991 (set_attr "length" "2,3")])
3994 (define_insn "*mulsidi3_sp32"
3995 [(set (match_operand:DI 0 "register_operand" "=r")
3996 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3997 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4000 return TARGET_SPARCLET
4001 ? "smuld\t%1, %2, %L0"
4002 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4005 (if_then_else (eq_attr "isa" "sparclet")
4006 (const_string "imul") (const_string "multi")))
4007 (set (attr "length")
4008 (if_then_else (eq_attr "isa" "sparclet")
4009 (const_int 1) (const_int 2)))])
4011 (define_insn "*mulsidi3_sp64"
4012 [(set (match_operand:DI 0 "register_operand" "=r")
4013 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4014 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4015 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4017 [(set_attr "type" "imul")])
4019 ;; Extra pattern, because sign_extend of a constant isn't valid.
4022 (define_insn "const_mulsidi3_sp32"
4023 [(set (match_operand:DI 0 "register_operand" "=r")
4024 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4025 (match_operand:DI 2 "small_int_operand" "I")))]
4028 return TARGET_SPARCLET
4029 ? "smuld\t%1, %2, %L0"
4030 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4033 (if_then_else (eq_attr "isa" "sparclet")
4034 (const_string "imul") (const_string "multi")))
4035 (set (attr "length")
4036 (if_then_else (eq_attr "isa" "sparclet")
4037 (const_int 1) (const_int 2)))])
4039 (define_insn "const_mulsidi3_sp64"
4040 [(set (match_operand:DI 0 "register_operand" "=r")
4041 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4042 (match_operand:DI 2 "small_int_operand" "I")))]
4043 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4045 [(set_attr "type" "imul")])
4047 (define_expand "smulsi3_highpart"
4048 [(set (match_operand:SI 0 "register_operand" "")
4050 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4051 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4053 "TARGET_HARD_MUL && TARGET_ARCH32"
4055 if (CONSTANT_P (operands[2]))
4059 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4065 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4070 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4071 operands[2], GEN_INT (32)));
4077 (define_insn "smulsi3_highpart_v8plus"
4078 [(set (match_operand:SI 0 "register_operand" "=h,r")
4080 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4081 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4082 (match_operand:SI 3 "small_int_operand" "I,I"))))
4083 (clobber (match_scratch:SI 4 "=X,&h"))]
4086 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4087 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4088 [(set_attr "type" "multi")
4089 (set_attr "length" "2")])
4091 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4094 [(set (match_operand:SI 0 "register_operand" "=h,r")
4097 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4098 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4099 (match_operand:SI 3 "small_int_operand" "I,I"))
4101 (clobber (match_scratch:SI 4 "=X,&h"))]
4104 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4105 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4106 [(set_attr "type" "multi")
4107 (set_attr "length" "2")])
4110 (define_insn "const_smulsi3_highpart_v8plus"
4111 [(set (match_operand:SI 0 "register_operand" "=h,r")
4113 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4114 (match_operand:DI 2 "small_int_operand" "I,I"))
4115 (match_operand:SI 3 "small_int_operand" "I,I"))))
4116 (clobber (match_scratch:SI 4 "=X,&h"))]
4119 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4120 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4121 [(set_attr "type" "multi")
4122 (set_attr "length" "2")])
4125 (define_insn "*smulsi3_highpart_sp32"
4126 [(set (match_operand:SI 0 "register_operand" "=r")
4128 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4129 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4132 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4133 [(set_attr "type" "multi")
4134 (set_attr "length" "2")])
4137 (define_insn "const_smulsi3_highpart"
4138 [(set (match_operand:SI 0 "register_operand" "=r")
4140 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4141 (match_operand:DI 2 "small_int_operand" "i"))
4144 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4145 [(set_attr "type" "multi")
4146 (set_attr "length" "2")])
4148 (define_expand "umulsidi3"
4149 [(set (match_operand:DI 0 "register_operand" "")
4150 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4151 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4154 if (CONSTANT_P (operands[2]))
4157 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4159 else if (TARGET_ARCH32)
4160 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4163 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4169 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4175 (define_insn "umulsidi3_v8plus"
4176 [(set (match_operand:DI 0 "register_operand" "=h,r")
4177 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4178 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4179 (clobber (match_scratch:SI 3 "=X,&h"))]
4182 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4183 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4184 [(set_attr "type" "multi")
4185 (set_attr "length" "2,3")])
4188 (define_insn "*umulsidi3_sp32"
4189 [(set (match_operand:DI 0 "register_operand" "=r")
4190 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4191 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4194 return TARGET_SPARCLET
4195 ? "umuld\t%1, %2, %L0"
4196 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4199 (if_then_else (eq_attr "isa" "sparclet")
4200 (const_string "imul") (const_string "multi")))
4201 (set (attr "length")
4202 (if_then_else (eq_attr "isa" "sparclet")
4203 (const_int 1) (const_int 2)))])
4205 (define_insn "*umulsidi3_sp64"
4206 [(set (match_operand:DI 0 "register_operand" "=r")
4207 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4208 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4209 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4211 [(set_attr "type" "imul")])
4213 ;; Extra pattern, because sign_extend of a constant isn't valid.
4216 (define_insn "const_umulsidi3_sp32"
4217 [(set (match_operand:DI 0 "register_operand" "=r")
4218 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4219 (match_operand:DI 2 "uns_small_int_operand" "")))]
4222 return TARGET_SPARCLET
4223 ? "umuld\t%1, %s2, %L0"
4224 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4227 (if_then_else (eq_attr "isa" "sparclet")
4228 (const_string "imul") (const_string "multi")))
4229 (set (attr "length")
4230 (if_then_else (eq_attr "isa" "sparclet")
4231 (const_int 1) (const_int 2)))])
4233 (define_insn "const_umulsidi3_sp64"
4234 [(set (match_operand:DI 0 "register_operand" "=r")
4235 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4236 (match_operand:DI 2 "uns_small_int_operand" "")))]
4237 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4239 [(set_attr "type" "imul")])
4242 (define_insn "const_umulsidi3_v8plus"
4243 [(set (match_operand:DI 0 "register_operand" "=h,r")
4244 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4245 (match_operand:DI 2 "uns_small_int_operand" "")))
4246 (clobber (match_scratch:SI 3 "=X,h"))]
4249 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4250 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4251 [(set_attr "type" "multi")
4252 (set_attr "length" "2,3")])
4254 (define_expand "umulsi3_highpart"
4255 [(set (match_operand:SI 0 "register_operand" "")
4257 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4258 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4260 "TARGET_HARD_MUL && TARGET_ARCH32"
4262 if (CONSTANT_P (operands[2]))
4266 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4272 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4277 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4278 operands[2], GEN_INT (32)));
4284 (define_insn "umulsi3_highpart_v8plus"
4285 [(set (match_operand:SI 0 "register_operand" "=h,r")
4287 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4288 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4289 (match_operand:SI 3 "small_int_operand" "I,I"))))
4290 (clobber (match_scratch:SI 4 "=X,h"))]
4293 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4294 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4295 [(set_attr "type" "multi")
4296 (set_attr "length" "2")])
4299 (define_insn "const_umulsi3_highpart_v8plus"
4300 [(set (match_operand:SI 0 "register_operand" "=h,r")
4302 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4303 (match_operand:DI 2 "uns_small_int_operand" ""))
4304 (match_operand:SI 3 "small_int_operand" "I,I"))))
4305 (clobber (match_scratch:SI 4 "=X,h"))]
4308 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4309 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4310 [(set_attr "type" "multi")
4311 (set_attr "length" "2")])
4314 (define_insn "*umulsi3_highpart_sp32"
4315 [(set (match_operand:SI 0 "register_operand" "=r")
4317 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4318 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4321 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4322 [(set_attr "type" "multi")
4323 (set_attr "length" "2")])
4326 (define_insn "const_umulsi3_highpart"
4327 [(set (match_operand:SI 0 "register_operand" "=r")
4329 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4330 (match_operand:DI 2 "uns_small_int_operand" ""))
4333 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4334 [(set_attr "type" "multi")
4335 (set_attr "length" "2")])
4337 (define_expand "divsi3"
4338 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4339 (div:SI (match_operand:SI 1 "register_operand" "")
4340 (match_operand:SI 2 "input_operand" "")))
4341 (clobber (match_scratch:SI 3 ""))])]
4342 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4346 operands[3] = gen_reg_rtx(SImode);
4347 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4348 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4354 ;; The V8 architecture specifies that there must be at least 3 instructions
4355 ;; between a write to the Y register and a use of it for correct results.
4356 ;; We try to fill one of them with a simple constant or a memory load.
4358 (define_insn "divsi3_sp32"
4359 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4360 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4361 (match_operand:SI 2 "input_operand" "rI,K,m")))
4362 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4363 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4365 output_asm_insn ("sra\t%1, 31, %3", operands);
4366 output_asm_insn ("wr\t%3, 0, %%y", operands);
4368 switch (which_alternative)
4372 return "sdiv\t%1, %2, %0";
4374 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4377 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4379 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4382 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4384 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4389 [(set_attr "type" "multi")
4390 (set (attr "length")
4391 (if_then_else (eq_attr "isa" "v9")
4392 (const_int 4) (const_int 6)))])
4394 (define_insn "divsi3_sp64"
4395 [(set (match_operand:SI 0 "register_operand" "=r")
4396 (div:SI (match_operand:SI 1 "register_operand" "r")
4397 (match_operand:SI 2 "input_operand" "rI")))
4398 (use (match_operand:SI 3 "register_operand" "r"))]
4399 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4400 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4401 [(set_attr "type" "multi")
4402 (set_attr "length" "2")])
4404 (define_insn "divdi3"
4405 [(set (match_operand:DI 0 "register_operand" "=r")
4406 (div:DI (match_operand:DI 1 "register_operand" "r")
4407 (match_operand:DI 2 "arith_operand" "rI")))]
4410 [(set_attr "type" "idiv")])
4412 (define_insn "*cmp_sdiv_cc_set"
4414 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4415 (match_operand:SI 2 "arith_operand" "rI"))
4417 (set (match_operand:SI 0 "register_operand" "=r")
4418 (div:SI (match_dup 1) (match_dup 2)))
4419 (clobber (match_scratch:SI 3 "=&r"))]
4420 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4422 output_asm_insn ("sra\t%1, 31, %3", operands);
4423 output_asm_insn ("wr\t%3, 0, %%y", operands);
4426 return "sdivcc\t%1, %2, %0";
4428 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4430 [(set_attr "type" "multi")
4431 (set (attr "length")
4432 (if_then_else (eq_attr "isa" "v9")
4433 (const_int 3) (const_int 6)))])
4436 (define_expand "udivsi3"
4437 [(set (match_operand:SI 0 "register_operand" "")
4438 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4439 (match_operand:SI 2 "input_operand" "")))]
4440 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4443 ;; The V8 architecture specifies that there must be at least 3 instructions
4444 ;; between a write to the Y register and a use of it for correct results.
4445 ;; We try to fill one of them with a simple constant or a memory load.
4447 (define_insn "udivsi3_sp32"
4448 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4449 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4450 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4451 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4453 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4455 switch (which_alternative)
4459 return "udiv\t%1, %2, %0";
4461 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4464 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4466 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4469 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4471 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4474 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4476 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4481 [(set_attr "type" "multi")
4482 (set (attr "length")
4483 (if_then_else (eq_attr "isa" "v9")
4484 (const_int 3) (const_int 5)))])
4486 (define_insn "udivsi3_sp64"
4487 [(set (match_operand:SI 0 "register_operand" "=r")
4488 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4489 (match_operand:SI 2 "input_operand" "rI")))]
4490 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4491 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4492 [(set_attr "type" "multi")
4493 (set_attr "length" "2")])
4495 (define_insn "udivdi3"
4496 [(set (match_operand:DI 0 "register_operand" "=r")
4497 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4498 (match_operand:DI 2 "arith_operand" "rI")))]
4501 [(set_attr "type" "idiv")])
4503 (define_insn "*cmp_udiv_cc_set"
4505 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4506 (match_operand:SI 2 "arith_operand" "rI"))
4508 (set (match_operand:SI 0 "register_operand" "=r")
4509 (udiv:SI (match_dup 1) (match_dup 2)))]
4510 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4512 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4515 return "udivcc\t%1, %2, %0";
4517 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4519 [(set_attr "type" "multi")
4520 (set (attr "length")
4521 (if_then_else (eq_attr "isa" "v9")
4522 (const_int 2) (const_int 5)))])
4524 ; sparclet multiply/accumulate insns
4526 (define_insn "*smacsi"
4527 [(set (match_operand:SI 0 "register_operand" "=r")
4528 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4529 (match_operand:SI 2 "arith_operand" "rI"))
4530 (match_operand:SI 3 "register_operand" "0")))]
4533 [(set_attr "type" "imul")])
4535 (define_insn "*smacdi"
4536 [(set (match_operand:DI 0 "register_operand" "=r")
4537 (plus:DI (mult:DI (sign_extend:DI
4538 (match_operand:SI 1 "register_operand" "%r"))
4540 (match_operand:SI 2 "register_operand" "r")))
4541 (match_operand:DI 3 "register_operand" "0")))]
4543 "smacd\t%1, %2, %L0"
4544 [(set_attr "type" "imul")])
4546 (define_insn "*umacdi"
4547 [(set (match_operand:DI 0 "register_operand" "=r")
4548 (plus:DI (mult:DI (zero_extend:DI
4549 (match_operand:SI 1 "register_operand" "%r"))
4551 (match_operand:SI 2 "register_operand" "r")))
4552 (match_operand:DI 3 "register_operand" "0")))]
4554 "umacd\t%1, %2, %L0"
4555 [(set_attr "type" "imul")])
4558 ;; Boolean instructions.
4560 ;; We define DImode `and' so with DImode `not' we can get
4561 ;; DImode `andn'. Other combinations are possible.
4563 (define_expand "and<V64I:mode>3"
4564 [(set (match_operand:V64I 0 "register_operand" "")
4565 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4566 (match_operand:V64I 2 "arith_double_operand" "")))]
4570 (define_insn "*and<V64I:mode>3_sp32"
4571 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4572 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4573 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4578 [(set_attr "type" "*,fga")
4579 (set_attr "length" "2,*")
4580 (set_attr "fptype" "*,double")])
4582 (define_insn "*and<V64I:mode>3_sp64"
4583 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4584 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4585 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4590 [(set_attr "type" "*,fga")
4591 (set_attr "fptype" "*,double")])
4593 (define_insn "and<V32I:mode>3"
4594 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4595 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4596 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4601 [(set_attr "type" "*,fga")
4602 (set_attr "fptype" "*,single")])
4605 [(set (match_operand:SI 0 "register_operand" "")
4606 (and:SI (match_operand:SI 1 "register_operand" "")
4607 (match_operand:SI 2 "const_compl_high_operand" "")))
4608 (clobber (match_operand:SI 3 "register_operand" ""))]
4610 [(set (match_dup 3) (match_dup 4))
4611 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4613 operands[4] = GEN_INT (~INTVAL (operands[2]));
4616 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4617 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4618 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4619 (match_operand:V64I 2 "register_operand" "r,b")))]
4623 fandnot1\t%1, %2, %0"
4624 "&& reload_completed
4625 && ((GET_CODE (operands[0]) == REG
4626 && REGNO (operands[0]) < 32)
4627 || (GET_CODE (operands[0]) == SUBREG
4628 && GET_CODE (SUBREG_REG (operands[0])) == REG
4629 && REGNO (SUBREG_REG (operands[0])) < 32))"
4630 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4631 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4632 "operands[3] = gen_highpart (SImode, operands[0]);
4633 operands[4] = gen_highpart (SImode, operands[1]);
4634 operands[5] = gen_highpart (SImode, operands[2]);
4635 operands[6] = gen_lowpart (SImode, operands[0]);
4636 operands[7] = gen_lowpart (SImode, operands[1]);
4637 operands[8] = gen_lowpart (SImode, operands[2]);"
4638 [(set_attr "type" "*,fga")
4639 (set_attr "length" "2,*")
4640 (set_attr "fptype" "*,double")])
4642 (define_insn "*and_not_<V64I:mode>_sp64"
4643 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4644 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4645 (match_operand:V64I 2 "register_operand" "r,b")))]
4649 fandnot1\t%1, %2, %0"
4650 [(set_attr "type" "*,fga")
4651 (set_attr "fptype" "*,double")])
4653 (define_insn "*and_not_<V32I:mode>"
4654 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4655 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4656 (match_operand:V32I 2 "register_operand" "r,d")))]
4660 fandnot1s\t%1, %2, %0"
4661 [(set_attr "type" "*,fga")
4662 (set_attr "fptype" "*,single")])
4664 (define_expand "ior<V64I:mode>3"
4665 [(set (match_operand:V64I 0 "register_operand" "")
4666 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4667 (match_operand:V64I 2 "arith_double_operand" "")))]
4671 (define_insn "*ior<V64I:mode>3_sp32"
4672 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4673 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4674 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4679 [(set_attr "type" "*,fga")
4680 (set_attr "length" "2,*")
4681 (set_attr "fptype" "*,double")])
4683 (define_insn "*ior<V64I:mode>3_sp64"
4684 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4685 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4686 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4691 [(set_attr "type" "*,fga")
4692 (set_attr "fptype" "*,double")])
4694 (define_insn "ior<V32I:mode>3"
4695 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4696 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4697 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4702 [(set_attr "type" "*,fga")
4703 (set_attr "fptype" "*,single")])
4706 [(set (match_operand:SI 0 "register_operand" "")
4707 (ior:SI (match_operand:SI 1 "register_operand" "")
4708 (match_operand:SI 2 "const_compl_high_operand" "")))
4709 (clobber (match_operand:SI 3 "register_operand" ""))]
4711 [(set (match_dup 3) (match_dup 4))
4712 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4714 operands[4] = GEN_INT (~INTVAL (operands[2]));
4717 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4718 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4719 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4720 (match_operand:V64I 2 "register_operand" "r,b")))]
4724 fornot1\t%1, %2, %0"
4725 "&& reload_completed
4726 && ((GET_CODE (operands[0]) == REG
4727 && REGNO (operands[0]) < 32)
4728 || (GET_CODE (operands[0]) == SUBREG
4729 && GET_CODE (SUBREG_REG (operands[0])) == REG
4730 && REGNO (SUBREG_REG (operands[0])) < 32))"
4731 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4732 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4733 "operands[3] = gen_highpart (SImode, operands[0]);
4734 operands[4] = gen_highpart (SImode, operands[1]);
4735 operands[5] = gen_highpart (SImode, operands[2]);
4736 operands[6] = gen_lowpart (SImode, operands[0]);
4737 operands[7] = gen_lowpart (SImode, operands[1]);
4738 operands[8] = gen_lowpart (SImode, operands[2]);"
4739 [(set_attr "type" "*,fga")
4740 (set_attr "length" "2,*")
4741 (set_attr "fptype" "*,double")])
4743 (define_insn "*or_not_<V64I:mode>_sp64"
4744 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4745 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4746 (match_operand:V64I 2 "register_operand" "r,b")))]
4750 fornot1\t%1, %2, %0"
4751 [(set_attr "type" "*,fga")
4752 (set_attr "fptype" "*,double")])
4754 (define_insn "*or_not_<V32I:mode>"
4755 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4756 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4757 (match_operand:V32I 2 "register_operand" "r,d")))]
4761 fornot1s\t%1, %2, %0"
4762 [(set_attr "type" "*,fga")
4763 (set_attr "fptype" "*,single")])
4765 (define_expand "xor<V64I:mode>3"
4766 [(set (match_operand:V64I 0 "register_operand" "")
4767 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4768 (match_operand:V64I 2 "arith_double_operand" "")))]
4772 (define_insn "*xor<V64I:mode>3_sp32"
4773 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4774 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4775 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4780 [(set_attr "type" "*,fga")
4781 (set_attr "length" "2,*")
4782 (set_attr "fptype" "*,double")])
4784 (define_insn "*xor<V64I:mode>3_sp64"
4785 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4786 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4787 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4792 [(set_attr "type" "*,fga")
4793 (set_attr "fptype" "*,double")])
4795 (define_insn "xor<V32I:mode>3"
4796 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4797 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4798 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4803 [(set_attr "type" "*,fga")
4804 (set_attr "fptype" "*,single")])
4807 [(set (match_operand:SI 0 "register_operand" "")
4808 (xor:SI (match_operand:SI 1 "register_operand" "")
4809 (match_operand:SI 2 "const_compl_high_operand" "")))
4810 (clobber (match_operand:SI 3 "register_operand" ""))]
4812 [(set (match_dup 3) (match_dup 4))
4813 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4815 operands[4] = GEN_INT (~INTVAL (operands[2]));
4819 [(set (match_operand:SI 0 "register_operand" "")
4820 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4821 (match_operand:SI 2 "const_compl_high_operand" ""))))
4822 (clobber (match_operand:SI 3 "register_operand" ""))]
4824 [(set (match_dup 3) (match_dup 4))
4825 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4827 operands[4] = GEN_INT (~INTVAL (operands[2]));
4830 ;; Split DImode logical operations requiring two instructions.
4832 [(set (match_operand:V64I 0 "register_operand" "")
4833 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4834 [(match_operand:V64I 2 "register_operand" "")
4835 (match_operand:V64I 3 "arith_double_operand" "")]))]
4838 && ((GET_CODE (operands[0]) == REG
4839 && REGNO (operands[0]) < 32)
4840 || (GET_CODE (operands[0]) == SUBREG
4841 && GET_CODE (SUBREG_REG (operands[0])) == REG
4842 && REGNO (SUBREG_REG (operands[0])) < 32))"
4843 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4844 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4846 operands[4] = gen_highpart (SImode, operands[0]);
4847 operands[5] = gen_lowpart (SImode, operands[0]);
4848 operands[6] = gen_highpart (SImode, operands[2]);
4849 operands[7] = gen_lowpart (SImode, operands[2]);
4850 #if HOST_BITS_PER_WIDE_INT == 32
4851 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4853 if (INTVAL (operands[3]) < 0)
4854 operands[8] = constm1_rtx;
4856 operands[8] = const0_rtx;
4860 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4861 operands[9] = gen_lowpart (SImode, operands[3]);
4864 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4865 ;; Combine now canonicalizes to the rightmost expression.
4866 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4867 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4868 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4869 (match_operand:V64I 2 "register_operand" "r,b"))))]
4874 "&& reload_completed
4875 && ((GET_CODE (operands[0]) == REG
4876 && REGNO (operands[0]) < 32)
4877 || (GET_CODE (operands[0]) == SUBREG
4878 && GET_CODE (SUBREG_REG (operands[0])) == REG
4879 && REGNO (SUBREG_REG (operands[0])) < 32))"
4880 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4881 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4882 "operands[3] = gen_highpart (SImode, operands[0]);
4883 operands[4] = gen_highpart (SImode, operands[1]);
4884 operands[5] = gen_highpart (SImode, operands[2]);
4885 operands[6] = gen_lowpart (SImode, operands[0]);
4886 operands[7] = gen_lowpart (SImode, operands[1]);
4887 operands[8] = gen_lowpart (SImode, operands[2]);"
4888 [(set_attr "type" "*,fga")
4889 (set_attr "length" "2,*")
4890 (set_attr "fptype" "*,double")])
4892 (define_insn "*xor_not_<V64I:mode>_sp64"
4893 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4894 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4895 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4900 [(set_attr "type" "*,fga")
4901 (set_attr "fptype" "*,double")])
4903 (define_insn "*xor_not_<V32I:mode>"
4904 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4905 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4906 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4911 [(set_attr "type" "*,fga")
4912 (set_attr "fptype" "*,single")])
4914 ;; These correspond to the above in the case where we also (or only)
4915 ;; want to set the condition code.
4917 (define_insn "*cmp_cc_arith_op"
4920 (match_operator:SI 2 "cc_arith_operator"
4921 [(match_operand:SI 0 "arith_operand" "%r")
4922 (match_operand:SI 1 "arith_operand" "rI")])
4925 "%A2cc\t%0, %1, %%g0"
4926 [(set_attr "type" "compare")])
4928 (define_insn "*cmp_ccx_arith_op"
4931 (match_operator:DI 2 "cc_arith_operator"
4932 [(match_operand:DI 0 "arith_operand" "%r")
4933 (match_operand:DI 1 "arith_operand" "rI")])
4936 "%A2cc\t%0, %1, %%g0"
4937 [(set_attr "type" "compare")])
4939 (define_insn "*cmp_cc_arith_op_set"
4942 (match_operator:SI 3 "cc_arith_operator"
4943 [(match_operand:SI 1 "arith_operand" "%r")
4944 (match_operand:SI 2 "arith_operand" "rI")])
4946 (set (match_operand:SI 0 "register_operand" "=r")
4947 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4948 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4950 [(set_attr "type" "compare")])
4952 (define_insn "*cmp_ccx_arith_op_set"
4955 (match_operator:DI 3 "cc_arith_operator"
4956 [(match_operand:DI 1 "arith_operand" "%r")
4957 (match_operand:DI 2 "arith_operand" "rI")])
4959 (set (match_operand:DI 0 "register_operand" "=r")
4960 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4961 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4963 [(set_attr "type" "compare")])
4965 (define_insn "*cmp_cc_xor_not"
4968 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4969 (match_operand:SI 1 "arith_operand" "rI")))
4972 "xnorcc\t%r0, %1, %%g0"
4973 [(set_attr "type" "compare")])
4975 (define_insn "*cmp_ccx_xor_not"
4978 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4979 (match_operand:DI 1 "arith_operand" "rI")))
4982 "xnorcc\t%r0, %1, %%g0"
4983 [(set_attr "type" "compare")])
4985 (define_insn "*cmp_cc_xor_not_set"
4988 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4989 (match_operand:SI 2 "arith_operand" "rI")))
4991 (set (match_operand:SI 0 "register_operand" "=r")
4992 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4994 "xnorcc\t%r1, %2, %0"
4995 [(set_attr "type" "compare")])
4997 (define_insn "*cmp_ccx_xor_not_set"
5000 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5001 (match_operand:DI 2 "arith_operand" "rI")))
5003 (set (match_operand:DI 0 "register_operand" "=r")
5004 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5006 "xnorcc\t%r1, %2, %0"
5007 [(set_attr "type" "compare")])
5009 (define_insn "*cmp_cc_arith_op_not"
5012 (match_operator:SI 2 "cc_arith_not_operator"
5013 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5014 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5017 "%B2cc\t%r1, %0, %%g0"
5018 [(set_attr "type" "compare")])
5020 (define_insn "*cmp_ccx_arith_op_not"
5023 (match_operator:DI 2 "cc_arith_not_operator"
5024 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5025 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5028 "%B2cc\t%r1, %0, %%g0"
5029 [(set_attr "type" "compare")])
5031 (define_insn "*cmp_cc_arith_op_not_set"
5034 (match_operator:SI 3 "cc_arith_not_operator"
5035 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5036 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5038 (set (match_operand:SI 0 "register_operand" "=r")
5039 (match_operator:SI 4 "cc_arith_not_operator"
5040 [(not:SI (match_dup 1)) (match_dup 2)]))]
5041 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5042 "%B3cc\t%r2, %1, %0"
5043 [(set_attr "type" "compare")])
5045 (define_insn "*cmp_ccx_arith_op_not_set"
5048 (match_operator:DI 3 "cc_arith_not_operator"
5049 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5050 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5052 (set (match_operand:DI 0 "register_operand" "=r")
5053 (match_operator:DI 4 "cc_arith_not_operator"
5054 [(not:DI (match_dup 1)) (match_dup 2)]))]
5055 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5056 "%B3cc\t%r2, %1, %0"
5057 [(set_attr "type" "compare")])
5059 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5060 ;; does not know how to make it work for constants.
5062 (define_expand "negdi2"
5063 [(set (match_operand:DI 0 "register_operand" "=r")
5064 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5067 if (! TARGET_ARCH64)
5069 emit_insn (gen_rtx_PARALLEL
5072 gen_rtx_SET (VOIDmode, operand0,
5073 gen_rtx_NEG (DImode, operand1)),
5074 gen_rtx_CLOBBER (VOIDmode,
5075 gen_rtx_REG (CCmode,
5081 (define_insn_and_split "*negdi2_sp32"
5082 [(set (match_operand:DI 0 "register_operand" "=r")
5083 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5084 (clobber (reg:CC 100))]
5087 "&& reload_completed"
5088 [(parallel [(set (reg:CC_NOOV 100)
5089 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5091 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5092 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5093 (ltu:SI (reg:CC 100) (const_int 0))))]
5094 "operands[2] = gen_highpart (SImode, operands[0]);
5095 operands[3] = gen_highpart (SImode, operands[1]);
5096 operands[4] = gen_lowpart (SImode, operands[0]);
5097 operands[5] = gen_lowpart (SImode, operands[1]);"
5098 [(set_attr "length" "2")])
5100 (define_insn "*negdi2_sp64"
5101 [(set (match_operand:DI 0 "register_operand" "=r")
5102 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5104 "sub\t%%g0, %1, %0")
5106 (define_insn "negsi2"
5107 [(set (match_operand:SI 0 "register_operand" "=r")
5108 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5110 "sub\t%%g0, %1, %0")
5112 (define_insn "*cmp_cc_neg"
5113 [(set (reg:CC_NOOV 100)
5114 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5117 "subcc\t%%g0, %0, %%g0"
5118 [(set_attr "type" "compare")])
5120 (define_insn "*cmp_ccx_neg"
5121 [(set (reg:CCX_NOOV 100)
5122 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5125 "subcc\t%%g0, %0, %%g0"
5126 [(set_attr "type" "compare")])
5128 (define_insn "*cmp_cc_set_neg"
5129 [(set (reg:CC_NOOV 100)
5130 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5132 (set (match_operand:SI 0 "register_operand" "=r")
5133 (neg:SI (match_dup 1)))]
5135 "subcc\t%%g0, %1, %0"
5136 [(set_attr "type" "compare")])
5138 (define_insn "*cmp_ccx_set_neg"
5139 [(set (reg:CCX_NOOV 100)
5140 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5142 (set (match_operand:DI 0 "register_operand" "=r")
5143 (neg:DI (match_dup 1)))]
5145 "subcc\t%%g0, %1, %0"
5146 [(set_attr "type" "compare")])
5148 ;; We cannot use the "not" pseudo insn because the Sun assembler
5149 ;; does not know how to make it work for constants.
5150 (define_expand "one_cmpl<V64I:mode>2"
5151 [(set (match_operand:V64I 0 "register_operand" "")
5152 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5156 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5157 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5158 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5163 "&& reload_completed
5164 && ((GET_CODE (operands[0]) == REG
5165 && REGNO (operands[0]) < 32)
5166 || (GET_CODE (operands[0]) == SUBREG
5167 && GET_CODE (SUBREG_REG (operands[0])) == REG
5168 && REGNO (SUBREG_REG (operands[0])) < 32))"
5169 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5170 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5171 "operands[2] = gen_highpart (SImode, operands[0]);
5172 operands[3] = gen_highpart (SImode, operands[1]);
5173 operands[4] = gen_lowpart (SImode, operands[0]);
5174 operands[5] = gen_lowpart (SImode, operands[1]);"
5175 [(set_attr "type" "*,fga")
5176 (set_attr "length" "2,*")
5177 (set_attr "fptype" "*,double")])
5179 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5180 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5181 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5186 [(set_attr "type" "*,fga")
5187 (set_attr "fptype" "*,double")])
5189 (define_insn "one_cmpl<V32I:mode>2"
5190 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5191 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5196 [(set_attr "type" "*,fga")
5197 (set_attr "fptype" "*,single")])
5199 (define_insn "*cmp_cc_not"
5201 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5204 "xnorcc\t%%g0, %0, %%g0"
5205 [(set_attr "type" "compare")])
5207 (define_insn "*cmp_ccx_not"
5209 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5212 "xnorcc\t%%g0, %0, %%g0"
5213 [(set_attr "type" "compare")])
5215 (define_insn "*cmp_cc_set_not"
5217 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5219 (set (match_operand:SI 0 "register_operand" "=r")
5220 (not:SI (match_dup 1)))]
5222 "xnorcc\t%%g0, %1, %0"
5223 [(set_attr "type" "compare")])
5225 (define_insn "*cmp_ccx_set_not"
5227 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5229 (set (match_operand:DI 0 "register_operand" "=r")
5230 (not:DI (match_dup 1)))]
5232 "xnorcc\t%%g0, %1, %0"
5233 [(set_attr "type" "compare")])
5235 (define_insn "*cmp_cc_set"
5236 [(set (match_operand:SI 0 "register_operand" "=r")
5237 (match_operand:SI 1 "register_operand" "r"))
5239 (compare:CC (match_dup 1)
5243 [(set_attr "type" "compare")])
5245 (define_insn "*cmp_ccx_set64"
5246 [(set (match_operand:DI 0 "register_operand" "=r")
5247 (match_operand:DI 1 "register_operand" "r"))
5249 (compare:CCX (match_dup 1)
5253 [(set_attr "type" "compare")])
5256 ;; Floating point arithmetic instructions.
5258 (define_expand "addtf3"
5259 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5260 (plus:TF (match_operand:TF 1 "general_operand" "")
5261 (match_operand:TF 2 "general_operand" "")))]
5262 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5263 "emit_tfmode_binop (PLUS, operands); DONE;")
5265 (define_insn "*addtf3_hq"
5266 [(set (match_operand:TF 0 "register_operand" "=e")
5267 (plus:TF (match_operand:TF 1 "register_operand" "e")
5268 (match_operand:TF 2 "register_operand" "e")))]
5269 "TARGET_FPU && TARGET_HARD_QUAD"
5271 [(set_attr "type" "fp")])
5273 (define_insn "adddf3"
5274 [(set (match_operand:DF 0 "register_operand" "=e")
5275 (plus:DF (match_operand:DF 1 "register_operand" "e")
5276 (match_operand:DF 2 "register_operand" "e")))]
5279 [(set_attr "type" "fp")
5280 (set_attr "fptype" "double")])
5282 (define_insn "addsf3"
5283 [(set (match_operand:SF 0 "register_operand" "=f")
5284 (plus:SF (match_operand:SF 1 "register_operand" "f")
5285 (match_operand:SF 2 "register_operand" "f")))]
5288 [(set_attr "type" "fp")])
5290 (define_expand "subtf3"
5291 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5292 (minus:TF (match_operand:TF 1 "general_operand" "")
5293 (match_operand:TF 2 "general_operand" "")))]
5294 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5295 "emit_tfmode_binop (MINUS, operands); DONE;")
5297 (define_insn "*subtf3_hq"
5298 [(set (match_operand:TF 0 "register_operand" "=e")
5299 (minus:TF (match_operand:TF 1 "register_operand" "e")
5300 (match_operand:TF 2 "register_operand" "e")))]
5301 "TARGET_FPU && TARGET_HARD_QUAD"
5303 [(set_attr "type" "fp")])
5305 (define_insn "subdf3"
5306 [(set (match_operand:DF 0 "register_operand" "=e")
5307 (minus:DF (match_operand:DF 1 "register_operand" "e")
5308 (match_operand:DF 2 "register_operand" "e")))]
5311 [(set_attr "type" "fp")
5312 (set_attr "fptype" "double")])
5314 (define_insn "subsf3"
5315 [(set (match_operand:SF 0 "register_operand" "=f")
5316 (minus:SF (match_operand:SF 1 "register_operand" "f")
5317 (match_operand:SF 2 "register_operand" "f")))]
5320 [(set_attr "type" "fp")])
5322 (define_expand "multf3"
5323 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5324 (mult:TF (match_operand:TF 1 "general_operand" "")
5325 (match_operand:TF 2 "general_operand" "")))]
5326 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5327 "emit_tfmode_binop (MULT, operands); DONE;")
5329 (define_insn "*multf3_hq"
5330 [(set (match_operand:TF 0 "register_operand" "=e")
5331 (mult:TF (match_operand:TF 1 "register_operand" "e")
5332 (match_operand:TF 2 "register_operand" "e")))]
5333 "TARGET_FPU && TARGET_HARD_QUAD"
5335 [(set_attr "type" "fpmul")])
5337 (define_insn "muldf3"
5338 [(set (match_operand:DF 0 "register_operand" "=e")
5339 (mult:DF (match_operand:DF 1 "register_operand" "e")
5340 (match_operand:DF 2 "register_operand" "e")))]
5343 [(set_attr "type" "fpmul")
5344 (set_attr "fptype" "double")])
5346 (define_insn "mulsf3"
5347 [(set (match_operand:SF 0 "register_operand" "=f")
5348 (mult:SF (match_operand:SF 1 "register_operand" "f")
5349 (match_operand:SF 2 "register_operand" "f")))]
5352 [(set_attr "type" "fpmul")])
5354 (define_insn "*muldf3_extend"
5355 [(set (match_operand:DF 0 "register_operand" "=e")
5356 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5357 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5358 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5359 "fsmuld\t%1, %2, %0"
5360 [(set_attr "type" "fpmul")
5361 (set_attr "fptype" "double")])
5363 (define_insn "*multf3_extend"
5364 [(set (match_operand:TF 0 "register_operand" "=e")
5365 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5366 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5367 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5368 "fdmulq\t%1, %2, %0"
5369 [(set_attr "type" "fpmul")])
5371 (define_expand "divtf3"
5372 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5373 (div:TF (match_operand:TF 1 "general_operand" "")
5374 (match_operand:TF 2 "general_operand" "")))]
5375 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5376 "emit_tfmode_binop (DIV, operands); DONE;")
5378 ;; don't have timing for quad-prec. divide.
5379 (define_insn "*divtf3_hq"
5380 [(set (match_operand:TF 0 "register_operand" "=e")
5381 (div:TF (match_operand:TF 1 "register_operand" "e")
5382 (match_operand:TF 2 "register_operand" "e")))]
5383 "TARGET_FPU && TARGET_HARD_QUAD"
5385 [(set_attr "type" "fpdivd")])
5387 (define_insn "divdf3"
5388 [(set (match_operand:DF 0 "register_operand" "=e")
5389 (div:DF (match_operand:DF 1 "register_operand" "e")
5390 (match_operand:DF 2 "register_operand" "e")))]
5393 [(set_attr "type" "fpdivd")
5394 (set_attr "fptype" "double")])
5396 (define_insn "divsf3"
5397 [(set (match_operand:SF 0 "register_operand" "=f")
5398 (div:SF (match_operand:SF 1 "register_operand" "f")
5399 (match_operand:SF 2 "register_operand" "f")))]
5402 [(set_attr "type" "fpdivs")])
5404 (define_expand "negtf2"
5405 [(set (match_operand:TF 0 "register_operand" "=e,e")
5406 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5410 (define_insn_and_split "*negtf2_notv9"
5411 [(set (match_operand:TF 0 "register_operand" "=e,e")
5412 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5413 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5419 "&& reload_completed
5420 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5421 [(set (match_dup 2) (neg:SF (match_dup 3)))
5422 (set (match_dup 4) (match_dup 5))
5423 (set (match_dup 6) (match_dup 7))]
5424 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5425 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5426 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5427 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5428 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5429 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5430 [(set_attr "type" "fpmove,*")
5431 (set_attr "length" "*,2")])
5433 (define_insn_and_split "*negtf2_v9"
5434 [(set (match_operand:TF 0 "register_operand" "=e,e")
5435 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5436 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5437 "TARGET_FPU && TARGET_V9"
5441 "&& reload_completed
5442 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5443 [(set (match_dup 2) (neg:DF (match_dup 3)))
5444 (set (match_dup 4) (match_dup 5))]
5445 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5446 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5447 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5448 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5449 [(set_attr "type" "fpmove,*")
5450 (set_attr "length" "*,2")
5451 (set_attr "fptype" "double")])
5453 (define_expand "negdf2"
5454 [(set (match_operand:DF 0 "register_operand" "")
5455 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5459 (define_insn_and_split "*negdf2_notv9"
5460 [(set (match_operand:DF 0 "register_operand" "=e,e")
5461 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5462 "TARGET_FPU && ! TARGET_V9"
5466 "&& reload_completed
5467 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5468 [(set (match_dup 2) (neg:SF (match_dup 3)))
5469 (set (match_dup 4) (match_dup 5))]
5470 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5471 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5472 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5473 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5474 [(set_attr "type" "fpmove,*")
5475 (set_attr "length" "*,2")])
5477 (define_insn "*negdf2_v9"
5478 [(set (match_operand:DF 0 "register_operand" "=e")
5479 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5480 "TARGET_FPU && TARGET_V9"
5482 [(set_attr "type" "fpmove")
5483 (set_attr "fptype" "double")])
5485 (define_insn "negsf2"
5486 [(set (match_operand:SF 0 "register_operand" "=f")
5487 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5490 [(set_attr "type" "fpmove")])
5492 (define_expand "abstf2"
5493 [(set (match_operand:TF 0 "register_operand" "")
5494 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5498 (define_insn_and_split "*abstf2_notv9"
5499 [(set (match_operand:TF 0 "register_operand" "=e,e")
5500 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5501 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5502 "TARGET_FPU && ! TARGET_V9"
5506 "&& reload_completed
5507 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5508 [(set (match_dup 2) (abs:SF (match_dup 3)))
5509 (set (match_dup 4) (match_dup 5))
5510 (set (match_dup 6) (match_dup 7))]
5511 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5512 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5513 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5514 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5515 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5516 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5517 [(set_attr "type" "fpmove,*")
5518 (set_attr "length" "*,2")])
5520 (define_insn "*abstf2_hq_v9"
5521 [(set (match_operand:TF 0 "register_operand" "=e,e")
5522 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5523 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5527 [(set_attr "type" "fpmove")
5528 (set_attr "fptype" "double,*")])
5530 (define_insn_and_split "*abstf2_v9"
5531 [(set (match_operand:TF 0 "register_operand" "=e,e")
5532 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5533 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5537 "&& reload_completed
5538 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5539 [(set (match_dup 2) (abs:DF (match_dup 3)))
5540 (set (match_dup 4) (match_dup 5))]
5541 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5542 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5543 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5544 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5545 [(set_attr "type" "fpmove,*")
5546 (set_attr "length" "*,2")
5547 (set_attr "fptype" "double,*")])
5549 (define_expand "absdf2"
5550 [(set (match_operand:DF 0 "register_operand" "")
5551 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5555 (define_insn_and_split "*absdf2_notv9"
5556 [(set (match_operand:DF 0 "register_operand" "=e,e")
5557 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5558 "TARGET_FPU && ! TARGET_V9"
5562 "&& reload_completed
5563 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5564 [(set (match_dup 2) (abs:SF (match_dup 3)))
5565 (set (match_dup 4) (match_dup 5))]
5566 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5567 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5568 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5569 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5570 [(set_attr "type" "fpmove,*")
5571 (set_attr "length" "*,2")])
5573 (define_insn "*absdf2_v9"
5574 [(set (match_operand:DF 0 "register_operand" "=e")
5575 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5576 "TARGET_FPU && TARGET_V9"
5578 [(set_attr "type" "fpmove")
5579 (set_attr "fptype" "double")])
5581 (define_insn "abssf2"
5582 [(set (match_operand:SF 0 "register_operand" "=f")
5583 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5586 [(set_attr "type" "fpmove")])
5588 (define_expand "sqrttf2"
5589 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5590 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5591 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5592 "emit_tfmode_unop (SQRT, operands); DONE;")
5594 (define_insn "*sqrttf2_hq"
5595 [(set (match_operand:TF 0 "register_operand" "=e")
5596 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5597 "TARGET_FPU && TARGET_HARD_QUAD"
5599 [(set_attr "type" "fpsqrtd")])
5601 (define_insn "sqrtdf2"
5602 [(set (match_operand:DF 0 "register_operand" "=e")
5603 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5606 [(set_attr "type" "fpsqrtd")
5607 (set_attr "fptype" "double")])
5609 (define_insn "sqrtsf2"
5610 [(set (match_operand:SF 0 "register_operand" "=f")
5611 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5614 [(set_attr "type" "fpsqrts")])
5617 ;; Arithmetic shift instructions.
5619 (define_insn "ashlsi3"
5620 [(set (match_operand:SI 0 "register_operand" "=r")
5621 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5622 (match_operand:SI 2 "arith_operand" "rI")))]
5625 if (GET_CODE (operands[2]) == CONST_INT)
5626 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5627 return "sll\t%1, %2, %0";
5630 (if_then_else (match_operand 2 "const_one_operand" "")
5631 (const_string "ialu") (const_string "shift")))])
5633 (define_expand "ashldi3"
5634 [(set (match_operand:DI 0 "register_operand" "=r")
5635 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5636 (match_operand:SI 2 "arith_operand" "rI")))]
5637 "TARGET_ARCH64 || TARGET_V8PLUS"
5639 if (! TARGET_ARCH64)
5641 if (GET_CODE (operands[2]) == CONST_INT)
5643 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5648 (define_insn "*ashldi3_sp64"
5649 [(set (match_operand:DI 0 "register_operand" "=r")
5650 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5651 (match_operand:SI 2 "arith_operand" "rI")))]
5654 if (GET_CODE (operands[2]) == CONST_INT)
5655 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5656 return "sllx\t%1, %2, %0";
5659 (if_then_else (match_operand 2 "const_one_operand" "")
5660 (const_string "ialu") (const_string "shift")))])
5663 (define_insn "ashldi3_v8plus"
5664 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5665 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5666 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5667 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5669 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5670 [(set_attr "type" "multi")
5671 (set_attr "length" "5,5,6")])
5673 ;; Optimize (1LL<<x)-1
5674 ;; XXX this also needs to be fixed to handle equal subregs
5675 ;; XXX first before we could re-enable it.
5677 ; [(set (match_operand:DI 0 "register_operand" "=h")
5678 ; (plus:DI (ashift:DI (const_int 1)
5679 ; (match_operand:SI 1 "arith_operand" "rI"))
5681 ; "0 && TARGET_V8PLUS"
5683 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5684 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5685 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5687 ; [(set_attr "type" "multi")
5688 ; (set_attr "length" "4")])
5690 (define_insn "*cmp_cc_ashift_1"
5691 [(set (reg:CC_NOOV 100)
5692 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5696 "addcc\t%0, %0, %%g0"
5697 [(set_attr "type" "compare")])
5699 (define_insn "*cmp_cc_set_ashift_1"
5700 [(set (reg:CC_NOOV 100)
5701 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5704 (set (match_operand:SI 0 "register_operand" "=r")
5705 (ashift:SI (match_dup 1) (const_int 1)))]
5708 [(set_attr "type" "compare")])
5710 (define_insn "ashrsi3"
5711 [(set (match_operand:SI 0 "register_operand" "=r")
5712 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5713 (match_operand:SI 2 "arith_operand" "rI")))]
5716 if (GET_CODE (operands[2]) == CONST_INT)
5717 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5718 return "sra\t%1, %2, %0";
5720 [(set_attr "type" "shift")])
5722 (define_insn "*ashrsi3_extend"
5723 [(set (match_operand:DI 0 "register_operand" "=r")
5724 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5725 (match_operand:SI 2 "arith_operand" "r"))))]
5728 [(set_attr "type" "shift")])
5730 ;; This handles the case as above, but with constant shift instead of
5731 ;; register. Combiner "simplifies" it for us a little bit though.
5732 (define_insn "*ashrsi3_extend2"
5733 [(set (match_operand:DI 0 "register_operand" "=r")
5734 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5736 (match_operand:SI 2 "small_int_operand" "I")))]
5737 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5739 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5740 return "sra\t%1, %2, %0";
5742 [(set_attr "type" "shift")])
5744 (define_expand "ashrdi3"
5745 [(set (match_operand:DI 0 "register_operand" "=r")
5746 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5747 (match_operand:SI 2 "arith_operand" "rI")))]
5748 "TARGET_ARCH64 || TARGET_V8PLUS"
5750 if (! TARGET_ARCH64)
5752 if (GET_CODE (operands[2]) == CONST_INT)
5753 FAIL; /* prefer generic code in this case */
5754 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5759 (define_insn "*ashrdi3_sp64"
5760 [(set (match_operand:DI 0 "register_operand" "=r")
5761 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5762 (match_operand:SI 2 "arith_operand" "rI")))]
5766 if (GET_CODE (operands[2]) == CONST_INT)
5767 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5768 return "srax\t%1, %2, %0";
5770 [(set_attr "type" "shift")])
5773 (define_insn "ashrdi3_v8plus"
5774 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5775 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5776 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5777 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5779 "* return output_v8plus_shift (operands, insn, \"srax\");"
5780 [(set_attr "type" "multi")
5781 (set_attr "length" "5,5,6")])
5783 (define_insn "lshrsi3"
5784 [(set (match_operand:SI 0 "register_operand" "=r")
5785 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5786 (match_operand:SI 2 "arith_operand" "rI")))]
5789 if (GET_CODE (operands[2]) == CONST_INT)
5790 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5791 return "srl\t%1, %2, %0";
5793 [(set_attr "type" "shift")])
5795 ;; This handles the case where
5796 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5797 ;; but combiner "simplifies" it for us.
5798 (define_insn "*lshrsi3_extend"
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5801 (match_operand:SI 2 "arith_operand" "r")) 0)
5802 (match_operand 3 "const_int_operand" "")))]
5803 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5805 [(set_attr "type" "shift")])
5807 ;; This handles the case where
5808 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5809 ;; but combiner "simplifies" it for us.
5810 (define_insn "*lshrsi3_extend2"
5811 [(set (match_operand:DI 0 "register_operand" "=r")
5812 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5813 (match_operand 2 "small_int_operand" "I")
5815 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5817 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5818 return "srl\t%1, %2, %0";
5820 [(set_attr "type" "shift")])
5822 (define_expand "lshrdi3"
5823 [(set (match_operand:DI 0 "register_operand" "=r")
5824 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5825 (match_operand:SI 2 "arith_operand" "rI")))]
5826 "TARGET_ARCH64 || TARGET_V8PLUS"
5828 if (! TARGET_ARCH64)
5830 if (GET_CODE (operands[2]) == CONST_INT)
5832 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5837 (define_insn "*lshrdi3_sp64"
5838 [(set (match_operand:DI 0 "register_operand" "=r")
5839 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5840 (match_operand:SI 2 "arith_operand" "rI")))]
5843 if (GET_CODE (operands[2]) == CONST_INT)
5844 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5845 return "srlx\t%1, %2, %0";
5847 [(set_attr "type" "shift")])
5850 (define_insn "lshrdi3_v8plus"
5851 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5852 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5853 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5854 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5856 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5857 [(set_attr "type" "multi")
5858 (set_attr "length" "5,5,6")])
5861 [(set (match_operand:SI 0 "register_operand" "=r")
5862 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5864 (match_operand:SI 2 "small_int_operand" "I")))]
5865 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5867 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5868 return "srax\t%1, %2, %0";
5870 [(set_attr "type" "shift")])
5873 [(set (match_operand:SI 0 "register_operand" "=r")
5874 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5876 (match_operand:SI 2 "small_int_operand" "I")))]
5877 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5879 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5880 return "srlx\t%1, %2, %0";
5882 [(set_attr "type" "shift")])
5885 [(set (match_operand:SI 0 "register_operand" "=r")
5886 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5887 (match_operand:SI 2 "small_int_operand" "I")) 4)
5888 (match_operand:SI 3 "small_int_operand" "I")))]
5890 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5891 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5892 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5894 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5896 return "srax\t%1, %2, %0";
5898 [(set_attr "type" "shift")])
5901 [(set (match_operand:SI 0 "register_operand" "=r")
5902 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5903 (match_operand:SI 2 "small_int_operand" "I")) 4)
5904 (match_operand:SI 3 "small_int_operand" "I")))]
5906 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5907 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5908 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5910 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5912 return "srlx\t%1, %2, %0";
5914 [(set_attr "type" "shift")])
5917 ;; Unconditional and other jump instructions.
5920 [(set (pc) (label_ref (match_operand 0 "" "")))]
5922 "* return output_ubranch (operands[0], 0, insn);"
5923 [(set_attr "type" "uncond_branch")])
5925 (define_expand "tablejump"
5926 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5927 (use (label_ref (match_operand 1 "" "")))])]
5930 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5932 /* In pic mode, our address differences are against the base of the
5933 table. Add that base value back in; CSE ought to be able to combine
5934 the two address loads. */
5938 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5940 if (CASE_VECTOR_MODE != Pmode)
5941 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5942 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5943 operands[0] = memory_address (Pmode, tmp);
5947 (define_insn "*tablejump_sp32"
5948 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5949 (use (label_ref (match_operand 1 "" "")))]
5952 [(set_attr "type" "uncond_branch")])
5954 (define_insn "*tablejump_sp64"
5955 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5956 (use (label_ref (match_operand 1 "" "")))]
5959 [(set_attr "type" "uncond_branch")])
5962 ;; Jump to subroutine instructions.
5964 (define_expand "call"
5965 ;; Note that this expression is not used for generating RTL.
5966 ;; All the RTL is generated explicitly below.
5967 [(call (match_operand 0 "call_operand" "")
5968 (match_operand 3 "" "i"))]
5969 ;; operands[2] is next_arg_register
5970 ;; operands[3] is struct_value_size_rtx.
5975 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5977 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5979 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5981 /* This is really a PIC sequence. We want to represent
5982 it as a funny jump so its delay slots can be filled.
5984 ??? But if this really *is* a CALL, will not it clobber the
5985 call-clobbered registers? We lose this if it is a JUMP_INSN.
5986 Why cannot we have delay slots filled if it were a CALL? */
5988 /* We accept negative sizes for untyped calls. */
5989 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5994 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5996 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6002 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6003 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6007 fn_rtx = operands[0];
6009 /* We accept negative sizes for untyped calls. */
6010 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6011 sparc_emit_call_insn
6014 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6016 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6019 sparc_emit_call_insn
6022 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6023 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6031 ;; We can't use the same pattern for these two insns, because then registers
6032 ;; in the address may not be properly reloaded.
6034 (define_insn "*call_address_sp32"
6035 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6036 (match_operand 1 "" ""))
6037 (clobber (reg:SI 15))]
6038 ;;- Do not use operand 1 for most machines.
6041 [(set_attr "type" "call")])
6043 (define_insn "*call_symbolic_sp32"
6044 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6045 (match_operand 1 "" ""))
6046 (clobber (reg:SI 15))]
6047 ;;- Do not use operand 1 for most machines.
6050 [(set_attr "type" "call")])
6052 (define_insn "*call_address_sp64"
6053 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6054 (match_operand 1 "" ""))
6055 (clobber (reg:DI 15))]
6056 ;;- Do not use operand 1 for most machines.
6059 [(set_attr "type" "call")])
6061 (define_insn "*call_symbolic_sp64"
6062 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6063 (match_operand 1 "" ""))
6064 (clobber (reg:DI 15))]
6065 ;;- Do not use operand 1 for most machines.
6068 [(set_attr "type" "call")])
6070 ;; This is a call that wants a structure value.
6071 ;; There is no such critter for v9 (??? we may need one anyway).
6072 (define_insn "*call_address_struct_value_sp32"
6073 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6074 (match_operand 1 "" ""))
6075 (match_operand 2 "immediate_operand" "")
6076 (clobber (reg:SI 15))]
6077 ;;- Do not use operand 1 for most machines.
6078 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6080 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6081 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6083 [(set_attr "type" "call_no_delay_slot")
6084 (set_attr "length" "3")])
6086 ;; This is a call that wants a structure value.
6087 ;; There is no such critter for v9 (??? we may need one anyway).
6088 (define_insn "*call_symbolic_struct_value_sp32"
6089 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6090 (match_operand 1 "" ""))
6091 (match_operand 2 "immediate_operand" "")
6092 (clobber (reg:SI 15))]
6093 ;;- Do not use operand 1 for most machines.
6094 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6096 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6097 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6099 [(set_attr "type" "call_no_delay_slot")
6100 (set_attr "length" "3")])
6102 ;; This is a call that may want a structure value. This is used for
6104 (define_insn "*call_address_untyped_struct_value_sp32"
6105 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6106 (match_operand 1 "" ""))
6107 (match_operand 2 "immediate_operand" "")
6108 (clobber (reg:SI 15))]
6109 ;;- Do not use operand 1 for most machines.
6110 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6111 "call\t%a0, %1\n\t nop\n\tnop"
6112 [(set_attr "type" "call_no_delay_slot")
6113 (set_attr "length" "3")])
6115 ;; This is a call that may want a structure value. This is used for
6117 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6118 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6119 (match_operand 1 "" ""))
6120 (match_operand 2 "immediate_operand" "")
6121 (clobber (reg:SI 15))]
6122 ;;- Do not use operand 1 for most machines.
6123 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6124 "call\t%a0, %1\n\t nop\n\tnop"
6125 [(set_attr "type" "call_no_delay_slot")
6126 (set_attr "length" "3")])
6128 (define_expand "call_value"
6129 ;; Note that this expression is not used for generating RTL.
6130 ;; All the RTL is generated explicitly below.
6131 [(set (match_operand 0 "register_operand" "=rf")
6132 (call (match_operand 1 "" "")
6133 (match_operand 4 "" "")))]
6134 ;; operand 2 is stack_size_rtx
6135 ;; operand 3 is next_arg_register
6141 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6143 fn_rtx = operands[1];
6146 gen_rtx_SET (VOIDmode, operands[0],
6147 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6148 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6150 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6155 (define_insn "*call_value_address_sp32"
6156 [(set (match_operand 0 "" "=rf")
6157 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6158 (match_operand 2 "" "")))
6159 (clobber (reg:SI 15))]
6160 ;;- Do not use operand 2 for most machines.
6163 [(set_attr "type" "call")])
6165 (define_insn "*call_value_symbolic_sp32"
6166 [(set (match_operand 0 "" "=rf")
6167 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6168 (match_operand 2 "" "")))
6169 (clobber (reg:SI 15))]
6170 ;;- Do not use operand 2 for most machines.
6173 [(set_attr "type" "call")])
6175 (define_insn "*call_value_address_sp64"
6176 [(set (match_operand 0 "" "")
6177 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6178 (match_operand 2 "" "")))
6179 (clobber (reg:DI 15))]
6180 ;;- Do not use operand 2 for most machines.
6183 [(set_attr "type" "call")])
6185 (define_insn "*call_value_symbolic_sp64"
6186 [(set (match_operand 0 "" "")
6187 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6188 (match_operand 2 "" "")))
6189 (clobber (reg:DI 15))]
6190 ;;- Do not use operand 2 for most machines.
6193 [(set_attr "type" "call")])
6195 (define_expand "untyped_call"
6196 [(parallel [(call (match_operand 0 "" "")
6198 (match_operand:BLK 1 "memory_operand" "")
6199 (match_operand 2 "" "")])]
6202 rtx valreg1 = gen_rtx_REG (DImode, 8);
6203 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6204 rtx result = operands[1];
6206 /* Pass constm1 to indicate that it may expect a structure value, but
6207 we don't know what size it is. */
6208 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6210 /* Save the function value registers. */
6211 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6212 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6215 /* The optimizer does not know that the call sets the function value
6216 registers we stored in the result block. We avoid problems by
6217 claiming that all hard registers are used and clobbered at this
6219 emit_insn (gen_blockage ());
6224 ;; Tail call instructions.
6226 (define_expand "sibcall"
6227 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6232 (define_insn "*sibcall_symbolic_sp32"
6233 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6234 (match_operand 1 "" ""))
6237 "* return output_sibcall(insn, operands[0]);"
6238 [(set_attr "type" "sibcall")])
6240 (define_insn "*sibcall_symbolic_sp64"
6241 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6242 (match_operand 1 "" ""))
6245 "* return output_sibcall(insn, operands[0]);"
6246 [(set_attr "type" "sibcall")])
6248 (define_expand "sibcall_value"
6249 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6250 (call (match_operand 1 "" "") (const_int 0)))
6255 (define_insn "*sibcall_value_symbolic_sp32"
6256 [(set (match_operand 0 "" "=rf")
6257 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6258 (match_operand 2 "" "")))
6261 "* return output_sibcall(insn, operands[1]);"
6262 [(set_attr "type" "sibcall")])
6264 (define_insn "*sibcall_value_symbolic_sp64"
6265 [(set (match_operand 0 "" "")
6266 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6267 (match_operand 2 "" "")))
6270 "* return output_sibcall(insn, operands[1]);"
6271 [(set_attr "type" "sibcall")])
6274 ;; Special instructions.
6276 (define_expand "prologue"
6281 sparc_flat_expand_prologue ();
6283 sparc_expand_prologue ();
6287 ;; The "register window save" insn is modelled as follows. The dwarf2
6288 ;; information is manually added in emit_window_save.
6290 (define_insn "window_save"
6292 [(match_operand 0 "arith_operand" "rI")]
6295 "save\t%%sp, %0, %%sp"
6296 [(set_attr "type" "savew")])
6298 (define_expand "epilogue"
6303 sparc_flat_expand_epilogue (false);
6305 sparc_expand_epilogue (false);
6308 (define_expand "sibcall_epilogue"
6313 sparc_flat_expand_epilogue (false);
6315 sparc_expand_epilogue (false);
6319 (define_expand "eh_return"
6320 [(use (match_operand 0 "general_operand" ""))]
6323 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6324 emit_jump_insn (gen_eh_return_internal ());
6329 (define_insn_and_split "eh_return_internal"
6333 "epilogue_completed"
6337 sparc_flat_expand_epilogue (true);
6339 sparc_expand_epilogue (true);
6342 (define_expand "return"
6344 "sparc_can_use_return_insn_p ()"
6347 (define_insn "*return_internal"
6350 "* return output_return (insn);"
6351 [(set_attr "type" "return")
6352 (set (attr "length")
6353 (cond [(eq_attr "calls_eh_return" "true")
6354 (if_then_else (eq_attr "delayed_branch" "true")
6355 (if_then_else (ior (eq_attr "isa" "v9")
6356 (eq_attr "flat" "true"))
6359 (if_then_else (eq_attr "flat" "true")
6362 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6363 (if_then_else (eq_attr "empty_delay_slot" "true")
6366 (eq_attr "empty_delay_slot" "true")
6367 (if_then_else (eq_attr "delayed_branch" "true")
6372 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6373 ;; all of memory. This blocks insns from being moved across this point.
6375 (define_insn "blockage"
6376 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6379 [(set_attr "length" "0")])
6381 (define_expand "probe_stack"
6382 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6386 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6389 (define_insn "probe_stack_range<P:mode>"
6390 [(set (match_operand:P 0 "register_operand" "=r")
6391 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6392 (match_operand:P 2 "register_operand" "r")]
6393 UNSPECV_PROBE_STACK_RANGE))]
6395 "* return output_probe_stack_range (operands[0], operands[2]);"
6396 [(set_attr "type" "multi")])
6398 ;; Prepare to return any type including a structure value.
6400 (define_expand "untyped_return"
6401 [(match_operand:BLK 0 "memory_operand" "")
6402 (match_operand 1 "" "")]
6405 rtx valreg1 = gen_rtx_REG (DImode, 24);
6406 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6407 rtx result = operands[0];
6409 if (! TARGET_ARCH64)
6411 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6412 rtx value = gen_reg_rtx (SImode);
6414 /* Fetch the instruction where we will return to and see if it's an unimp
6415 instruction (the most significant 10 bits will be zero). If so,
6416 update the return address to skip the unimp instruction. */
6417 emit_move_insn (value,
6418 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6419 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6420 emit_insn (gen_update_return (rtnreg, value));
6423 /* Reload the function value registers. */
6424 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6425 emit_move_insn (valreg2,
6426 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6428 /* Put USE insns before the return. */
6432 /* Construct the return. */
6433 expand_naked_return ();
6438 ;; Adjust the return address conditionally. If the value of op1 is equal
6439 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6440 ;; This is technically *half* the check required by the 32-bit SPARC
6441 ;; psABI. This check only ensures that an "unimp" insn was written by
6442 ;; the caller, but doesn't check to see if the expected size matches
6443 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6444 ;; only used by the above code "untyped_return".
6446 (define_insn "update_return"
6447 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6448 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6451 if (flag_delayed_branch)
6452 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6454 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6456 [(set (attr "type") (const_string "multi"))
6457 (set (attr "length")
6458 (if_then_else (eq_attr "delayed_branch" "true")
6467 (define_expand "indirect_jump"
6468 [(set (pc) (match_operand 0 "address_operand" "p"))]
6472 (define_insn "*branch_sp32"
6473 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6476 [(set_attr "type" "uncond_branch")])
6478 (define_insn "*branch_sp64"
6479 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6482 [(set_attr "type" "uncond_branch")])
6484 (define_expand "save_stack_nonlocal"
6485 [(set (match_operand 0 "memory_operand" "")
6486 (match_operand 1 "register_operand" ""))
6487 (set (match_dup 2) (match_dup 3))]
6490 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6491 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6492 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6495 (define_expand "restore_stack_nonlocal"
6496 [(set (match_operand 0 "register_operand" "")
6497 (match_operand 1 "memory_operand" ""))]
6500 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6503 (define_expand "nonlocal_goto"
6504 [(match_operand 0 "general_operand" "")
6505 (match_operand 1 "general_operand" "")
6506 (match_operand 2 "memory_operand" "")
6507 (match_operand 3 "memory_operand" "")]
6510 rtx r_label = copy_to_reg (operands[1]);
6511 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6512 rtx r_fp = operands[3];
6513 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6515 /* We need to flush all the register windows so that their contents will
6516 be re-synchronized by the restore insn of the target function. */
6518 emit_insn (gen_flush_register_windows ());
6520 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6521 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6523 /* Restore frame pointer for containing function. */
6524 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6525 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6527 /* USE of hard_frame_pointer_rtx added for consistency;
6528 not clear if really needed. */
6529 emit_use (hard_frame_pointer_rtx);
6530 emit_use (stack_pointer_rtx);
6532 /* We need to smuggle the load of %i7 as it is a fixed register. */
6533 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6538 (define_insn "nonlocal_goto_internal"
6539 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6540 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6541 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6543 if (flag_delayed_branch)
6546 return "jmp\t%0\n\t ldx\t%1, %%i7";
6548 return "jmp\t%0\n\t ld\t%1, %%i7";
6553 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6555 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6558 [(set (attr "type") (const_string "multi"))
6559 (set (attr "length")
6560 (if_then_else (eq_attr "delayed_branch" "true")
6564 (define_expand "builtin_setjmp_receiver"
6565 [(label_ref (match_operand 0 "" ""))]
6568 load_got_register ();
6572 ;; Special insn to flush register windows.
6574 (define_insn "flush_register_windows"
6575 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6577 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6578 [(set_attr "type" "flushw")])
6580 ;; Special pattern for the FLUSH instruction.
6582 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6583 ; of the define_insn otherwise missing a mode. We make "flush", aka
6584 ; gen_flush, the default one since sparc_initialize_trampoline uses
6585 ; it on SImode mem values.
6587 (define_insn "flush"
6588 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6590 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6591 [(set_attr "type" "iflush")])
6593 (define_insn "flushdi"
6594 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6596 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6597 [(set_attr "type" "iflush")])
6600 ;; Find first set instructions.
6602 ;; The scan instruction searches from the most significant bit while ffs
6603 ;; searches from the least significant bit. The bit index and treatment of
6604 ;; zero also differ. It takes at least 7 instructions to get the proper
6605 ;; result. Here is an obvious 8 instruction sequence.
6608 (define_insn "ffssi2"
6609 [(set (match_operand:SI 0 "register_operand" "=&r")
6610 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6611 (clobber (match_scratch:SI 2 "=&r"))]
6612 "TARGET_SPARCLITE || TARGET_SPARCLET"
6614 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";
6616 [(set_attr "type" "multi")
6617 (set_attr "length" "8")])
6619 ;; ??? This should be a define expand, so that the extra instruction have
6620 ;; a chance of being optimized away.
6622 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6623 ;; does, but no one uses that and we don't have a switch for it.
6625 ;(define_insn "ffsdi2"
6626 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6627 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6628 ; (clobber (match_scratch:DI 2 "=&r"))]
6630 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6631 ; [(set_attr "type" "multi")
6632 ; (set_attr "length" "4")])
6636 ;; Peepholes go at the end.
6638 ;; Optimize consecutive loads or stores into ldd and std when possible.
6639 ;; The conditions in which we do this are very restricted and are
6640 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6643 [(set (match_operand:SI 0 "memory_operand" "")
6645 (set (match_operand:SI 1 "memory_operand" "")
6648 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6651 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6654 [(set (match_operand:SI 0 "memory_operand" "")
6656 (set (match_operand:SI 1 "memory_operand" "")
6659 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6662 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6665 [(set (match_operand:SI 0 "register_operand" "")
6666 (match_operand:SI 1 "memory_operand" ""))
6667 (set (match_operand:SI 2 "register_operand" "")
6668 (match_operand:SI 3 "memory_operand" ""))]
6669 "registers_ok_for_ldd_peep (operands[0], operands[2])
6670 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6673 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6674 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6677 [(set (match_operand:SI 0 "memory_operand" "")
6678 (match_operand:SI 1 "register_operand" ""))
6679 (set (match_operand:SI 2 "memory_operand" "")
6680 (match_operand:SI 3 "register_operand" ""))]
6681 "registers_ok_for_ldd_peep (operands[1], operands[3])
6682 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6685 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6686 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6689 [(set (match_operand:SF 0 "register_operand" "")
6690 (match_operand:SF 1 "memory_operand" ""))
6691 (set (match_operand:SF 2 "register_operand" "")
6692 (match_operand:SF 3 "memory_operand" ""))]
6693 "registers_ok_for_ldd_peep (operands[0], operands[2])
6694 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6697 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6698 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6701 [(set (match_operand:SF 0 "memory_operand" "")
6702 (match_operand:SF 1 "register_operand" ""))
6703 (set (match_operand:SF 2 "memory_operand" "")
6704 (match_operand:SF 3 "register_operand" ""))]
6705 "registers_ok_for_ldd_peep (operands[1], operands[3])
6706 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6709 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6710 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6713 [(set (match_operand:SI 0 "register_operand" "")
6714 (match_operand:SI 1 "memory_operand" ""))
6715 (set (match_operand:SI 2 "register_operand" "")
6716 (match_operand:SI 3 "memory_operand" ""))]
6717 "registers_ok_for_ldd_peep (operands[2], operands[0])
6718 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6721 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6722 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6725 [(set (match_operand:SI 0 "memory_operand" "")
6726 (match_operand:SI 1 "register_operand" ""))
6727 (set (match_operand:SI 2 "memory_operand" "")
6728 (match_operand:SI 3 "register_operand" ""))]
6729 "registers_ok_for_ldd_peep (operands[3], operands[1])
6730 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6733 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6734 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6738 [(set (match_operand:SF 0 "register_operand" "")
6739 (match_operand:SF 1 "memory_operand" ""))
6740 (set (match_operand:SF 2 "register_operand" "")
6741 (match_operand:SF 3 "memory_operand" ""))]
6742 "registers_ok_for_ldd_peep (operands[2], operands[0])
6743 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6746 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6747 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6750 [(set (match_operand:SF 0 "memory_operand" "")
6751 (match_operand:SF 1 "register_operand" ""))
6752 (set (match_operand:SF 2 "memory_operand" "")
6753 (match_operand:SF 3 "register_operand" ""))]
6754 "registers_ok_for_ldd_peep (operands[3], operands[1])
6755 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6758 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6759 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6761 ;; Optimize the case of following a reg-reg move with a test
6762 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6763 ;; This can result from a float to fix conversion.
6766 [(set (match_operand:SI 0 "register_operand" "")
6767 (match_operand:SI 1 "register_operand" ""))
6769 (compare:CC (match_operand:SI 2 "register_operand" "")
6771 "(rtx_equal_p (operands[2], operands[0])
6772 || rtx_equal_p (operands[2], operands[1]))
6773 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6774 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6775 [(parallel [(set (match_dup 0) (match_dup 1))
6777 (compare:CC (match_dup 1) (const_int 0)))])]
6781 [(set (match_operand:DI 0 "register_operand" "")
6782 (match_operand:DI 1 "register_operand" ""))
6784 (compare:CCX (match_operand:DI 2 "register_operand" "")
6787 && (rtx_equal_p (operands[2], operands[0])
6788 || rtx_equal_p (operands[2], operands[1]))
6789 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6790 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6791 [(parallel [(set (match_dup 0) (match_dup 1))
6793 (compare:CCX (match_dup 1) (const_int 0)))])]
6797 ;; Prefetch instructions.
6799 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6800 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6801 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6803 (define_expand "prefetch"
6804 [(match_operand 0 "address_operand" "")
6805 (match_operand 1 "const_int_operand" "")
6806 (match_operand 2 "const_int_operand" "")]
6810 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6812 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6816 (define_insn "prefetch_64"
6817 [(prefetch (match_operand:DI 0 "address_operand" "p")
6818 (match_operand:DI 1 "const_int_operand" "n")
6819 (match_operand:DI 2 "const_int_operand" "n"))]
6822 static const char * const prefetch_instr[2][2] = {
6824 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6825 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6828 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6829 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6832 int read_or_write = INTVAL (operands[1]);
6833 int locality = INTVAL (operands[2]);
6835 gcc_assert (read_or_write == 0 || read_or_write == 1);
6836 gcc_assert (locality >= 0 && locality < 4);
6837 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6839 [(set_attr "type" "load")])
6841 (define_insn "prefetch_32"
6842 [(prefetch (match_operand:SI 0 "address_operand" "p")
6843 (match_operand:SI 1 "const_int_operand" "n")
6844 (match_operand:SI 2 "const_int_operand" "n"))]
6847 static const char * const prefetch_instr[2][2] = {
6849 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6850 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6853 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6854 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6857 int read_or_write = INTVAL (operands[1]);
6858 int locality = INTVAL (operands[2]);
6860 gcc_assert (read_or_write == 0 || read_or_write == 1);
6861 gcc_assert (locality >= 0 && locality < 4);
6862 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6864 [(set_attr "type" "load")])
6867 ;; Trap instructions.
6870 [(trap_if (const_int 1) (const_int 5))]
6873 [(set_attr "type" "trap")])
6875 (define_expand "ctrapsi4"
6876 [(trap_if (match_operator 0 "noov_compare_operator"
6877 [(match_operand:SI 1 "compare_operand" "")
6878 (match_operand:SI 2 "arith_operand" "")])
6879 (match_operand 3 ""))]
6881 "operands[1] = gen_compare_reg (operands[0]);
6882 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6884 operands[2] = const0_rtx;")
6886 (define_expand "ctrapdi4"
6887 [(trap_if (match_operator 0 "noov_compare_operator"
6888 [(match_operand:DI 1 "compare_operand" "")
6889 (match_operand:DI 2 "arith_operand" "")])
6890 (match_operand 3 ""))]
6892 "operands[1] = gen_compare_reg (operands[0]);
6893 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6895 operands[2] = const0_rtx;")
6899 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6900 (match_operand:SI 1 "arith_operand" "rM"))]
6904 return "t%C0\t%%icc, %1";
6908 [(set_attr "type" "trap")])
6911 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6912 (match_operand:SI 1 "arith_operand" "rM"))]
6915 [(set_attr "type" "trap")])
6918 ;; TLS support instructions.
6920 (define_insn "tgd_hi22"
6921 [(set (match_operand:SI 0 "register_operand" "=r")
6922 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6925 "sethi\\t%%tgd_hi22(%a1), %0")
6927 (define_insn "tgd_lo10"
6928 [(set (match_operand:SI 0 "register_operand" "=r")
6929 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6930 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6933 "add\\t%1, %%tgd_lo10(%a2), %0")
6935 (define_insn "tgd_add32"
6936 [(set (match_operand:SI 0 "register_operand" "=r")
6937 (plus:SI (match_operand:SI 1 "register_operand" "r")
6938 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6939 (match_operand 3 "tgd_symbolic_operand" "")]
6941 "TARGET_TLS && TARGET_ARCH32"
6942 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6944 (define_insn "tgd_add64"
6945 [(set (match_operand:DI 0 "register_operand" "=r")
6946 (plus:DI (match_operand:DI 1 "register_operand" "r")
6947 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6948 (match_operand 3 "tgd_symbolic_operand" "")]
6950 "TARGET_TLS && TARGET_ARCH64"
6951 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6953 (define_insn "tgd_call32"
6954 [(set (match_operand 0 "register_operand" "=r")
6955 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6956 (match_operand 2 "tgd_symbolic_operand" "")]
6958 (match_operand 3 "" "")))
6959 (clobber (reg:SI 15))]
6960 "TARGET_TLS && TARGET_ARCH32"
6961 "call\t%a1, %%tgd_call(%a2)%#"
6962 [(set_attr "type" "call")])
6964 (define_insn "tgd_call64"
6965 [(set (match_operand 0 "register_operand" "=r")
6966 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6967 (match_operand 2 "tgd_symbolic_operand" "")]
6969 (match_operand 3 "" "")))
6970 (clobber (reg:DI 15))]
6971 "TARGET_TLS && TARGET_ARCH64"
6972 "call\t%a1, %%tgd_call(%a2)%#"
6973 [(set_attr "type" "call")])
6975 (define_insn "tldm_hi22"
6976 [(set (match_operand:SI 0 "register_operand" "=r")
6977 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6979 "sethi\\t%%tldm_hi22(%&), %0")
6981 (define_insn "tldm_lo10"
6982 [(set (match_operand:SI 0 "register_operand" "=r")
6983 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6984 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6986 "add\\t%1, %%tldm_lo10(%&), %0")
6988 (define_insn "tldm_add32"
6989 [(set (match_operand:SI 0 "register_operand" "=r")
6990 (plus:SI (match_operand:SI 1 "register_operand" "r")
6991 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6993 "TARGET_TLS && TARGET_ARCH32"
6994 "add\\t%1, %2, %0, %%tldm_add(%&)")
6996 (define_insn "tldm_add64"
6997 [(set (match_operand:DI 0 "register_operand" "=r")
6998 (plus:DI (match_operand:DI 1 "register_operand" "r")
6999 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7001 "TARGET_TLS && TARGET_ARCH64"
7002 "add\\t%1, %2, %0, %%tldm_add(%&)")
7004 (define_insn "tldm_call32"
7005 [(set (match_operand 0 "register_operand" "=r")
7006 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7008 (match_operand 2 "" "")))
7009 (clobber (reg:SI 15))]
7010 "TARGET_TLS && TARGET_ARCH32"
7011 "call\t%a1, %%tldm_call(%&)%#"
7012 [(set_attr "type" "call")])
7014 (define_insn "tldm_call64"
7015 [(set (match_operand 0 "register_operand" "=r")
7016 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7018 (match_operand 2 "" "")))
7019 (clobber (reg:DI 15))]
7020 "TARGET_TLS && TARGET_ARCH64"
7021 "call\t%a1, %%tldm_call(%&)%#"
7022 [(set_attr "type" "call")])
7024 (define_insn "tldo_hix22"
7025 [(set (match_operand:SI 0 "register_operand" "=r")
7026 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7029 "sethi\\t%%tldo_hix22(%a1), %0")
7031 (define_insn "tldo_lox10"
7032 [(set (match_operand:SI 0 "register_operand" "=r")
7033 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7034 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7037 "xor\\t%1, %%tldo_lox10(%a2), %0")
7039 (define_insn "tldo_add32"
7040 [(set (match_operand:SI 0 "register_operand" "=r")
7041 (plus:SI (match_operand:SI 1 "register_operand" "r")
7042 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7043 (match_operand 3 "tld_symbolic_operand" "")]
7045 "TARGET_TLS && TARGET_ARCH32"
7046 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7048 (define_insn "tldo_add64"
7049 [(set (match_operand:DI 0 "register_operand" "=r")
7050 (plus:DI (match_operand:DI 1 "register_operand" "r")
7051 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7052 (match_operand 3 "tld_symbolic_operand" "")]
7054 "TARGET_TLS && TARGET_ARCH64"
7055 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7057 (define_insn "tie_hi22"
7058 [(set (match_operand:SI 0 "register_operand" "=r")
7059 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7062 "sethi\\t%%tie_hi22(%a1), %0")
7064 (define_insn "tie_lo10"
7065 [(set (match_operand:SI 0 "register_operand" "=r")
7066 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7067 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7070 "add\\t%1, %%tie_lo10(%a2), %0")
7072 (define_insn "tie_ld32"
7073 [(set (match_operand:SI 0 "register_operand" "=r")
7074 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7075 (match_operand:SI 2 "register_operand" "r")
7076 (match_operand 3 "tie_symbolic_operand" "")]
7078 "TARGET_TLS && TARGET_ARCH32"
7079 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7080 [(set_attr "type" "load")])
7082 (define_insn "tie_ld64"
7083 [(set (match_operand:DI 0 "register_operand" "=r")
7084 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7085 (match_operand:SI 2 "register_operand" "r")
7086 (match_operand 3 "tie_symbolic_operand" "")]
7088 "TARGET_TLS && TARGET_ARCH64"
7089 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7090 [(set_attr "type" "load")])
7092 (define_insn "tie_add32"
7093 [(set (match_operand:SI 0 "register_operand" "=r")
7094 (plus:SI (match_operand:SI 1 "register_operand" "r")
7095 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7096 (match_operand 3 "tie_symbolic_operand" "")]
7098 "TARGET_SUN_TLS && TARGET_ARCH32"
7099 "add\\t%1, %2, %0, %%tie_add(%a3)")
7101 (define_insn "tie_add64"
7102 [(set (match_operand:DI 0 "register_operand" "=r")
7103 (plus:DI (match_operand:DI 1 "register_operand" "r")
7104 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7105 (match_operand 3 "tie_symbolic_operand" "")]
7107 "TARGET_SUN_TLS && TARGET_ARCH64"
7108 "add\\t%1, %2, %0, %%tie_add(%a3)")
7110 (define_insn "tle_hix22_sp32"
7111 [(set (match_operand:SI 0 "register_operand" "=r")
7112 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7114 "TARGET_TLS && TARGET_ARCH32"
7115 "sethi\\t%%tle_hix22(%a1), %0")
7117 (define_insn "tle_lox10_sp32"
7118 [(set (match_operand:SI 0 "register_operand" "=r")
7119 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7120 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7122 "TARGET_TLS && TARGET_ARCH32"
7123 "xor\\t%1, %%tle_lox10(%a2), %0")
7125 (define_insn "tle_hix22_sp64"
7126 [(set (match_operand:DI 0 "register_operand" "=r")
7127 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7129 "TARGET_TLS && TARGET_ARCH64"
7130 "sethi\\t%%tle_hix22(%a1), %0")
7132 (define_insn "tle_lox10_sp64"
7133 [(set (match_operand:DI 0 "register_operand" "=r")
7134 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7135 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7137 "TARGET_TLS && TARGET_ARCH64"
7138 "xor\\t%1, %%tle_lox10(%a2), %0")
7140 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7141 (define_insn "*tldo_ldub_sp32"
7142 [(set (match_operand:QI 0 "register_operand" "=r")
7143 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7144 (match_operand 3 "tld_symbolic_operand" "")]
7146 (match_operand:SI 1 "register_operand" "r"))))]
7147 "TARGET_TLS && TARGET_ARCH32"
7148 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7149 [(set_attr "type" "load")
7150 (set_attr "us3load_type" "3cycle")])
7152 (define_insn "*tldo_ldub1_sp32"
7153 [(set (match_operand:HI 0 "register_operand" "=r")
7154 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7155 (match_operand 3 "tld_symbolic_operand" "")]
7157 (match_operand:SI 1 "register_operand" "r")))))]
7158 "TARGET_TLS && TARGET_ARCH32"
7159 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7160 [(set_attr "type" "load")
7161 (set_attr "us3load_type" "3cycle")])
7163 (define_insn "*tldo_ldub2_sp32"
7164 [(set (match_operand:SI 0 "register_operand" "=r")
7165 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7166 (match_operand 3 "tld_symbolic_operand" "")]
7168 (match_operand:SI 1 "register_operand" "r")))))]
7169 "TARGET_TLS && TARGET_ARCH32"
7170 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7171 [(set_attr "type" "load")
7172 (set_attr "us3load_type" "3cycle")])
7174 (define_insn "*tldo_ldsb1_sp32"
7175 [(set (match_operand:HI 0 "register_operand" "=r")
7176 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7177 (match_operand 3 "tld_symbolic_operand" "")]
7179 (match_operand:SI 1 "register_operand" "r")))))]
7180 "TARGET_TLS && TARGET_ARCH32"
7181 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7182 [(set_attr "type" "sload")
7183 (set_attr "us3load_type" "3cycle")])
7185 (define_insn "*tldo_ldsb2_sp32"
7186 [(set (match_operand:SI 0 "register_operand" "=r")
7187 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7188 (match_operand 3 "tld_symbolic_operand" "")]
7190 (match_operand:SI 1 "register_operand" "r")))))]
7191 "TARGET_TLS && TARGET_ARCH32"
7192 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7193 [(set_attr "type" "sload")
7194 (set_attr "us3load_type" "3cycle")])
7196 (define_insn "*tldo_ldub_sp64"
7197 [(set (match_operand:QI 0 "register_operand" "=r")
7198 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7199 (match_operand 3 "tld_symbolic_operand" "")]
7201 (match_operand:DI 1 "register_operand" "r"))))]
7202 "TARGET_TLS && TARGET_ARCH64"
7203 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7204 [(set_attr "type" "load")
7205 (set_attr "us3load_type" "3cycle")])
7207 (define_insn "*tldo_ldub1_sp64"
7208 [(set (match_operand:HI 0 "register_operand" "=r")
7209 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7210 (match_operand 3 "tld_symbolic_operand" "")]
7212 (match_operand:DI 1 "register_operand" "r")))))]
7213 "TARGET_TLS && TARGET_ARCH64"
7214 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7215 [(set_attr "type" "load")
7216 (set_attr "us3load_type" "3cycle")])
7218 (define_insn "*tldo_ldub2_sp64"
7219 [(set (match_operand:SI 0 "register_operand" "=r")
7220 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7221 (match_operand 3 "tld_symbolic_operand" "")]
7223 (match_operand:DI 1 "register_operand" "r")))))]
7224 "TARGET_TLS && TARGET_ARCH64"
7225 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7226 [(set_attr "type" "load")
7227 (set_attr "us3load_type" "3cycle")])
7229 (define_insn "*tldo_ldub3_sp64"
7230 [(set (match_operand:DI 0 "register_operand" "=r")
7231 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7232 (match_operand 3 "tld_symbolic_operand" "")]
7234 (match_operand:DI 1 "register_operand" "r")))))]
7235 "TARGET_TLS && TARGET_ARCH64"
7236 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7237 [(set_attr "type" "load")
7238 (set_attr "us3load_type" "3cycle")])
7240 (define_insn "*tldo_ldsb1_sp64"
7241 [(set (match_operand:HI 0 "register_operand" "=r")
7242 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7243 (match_operand 3 "tld_symbolic_operand" "")]
7245 (match_operand:DI 1 "register_operand" "r")))))]
7246 "TARGET_TLS && TARGET_ARCH64"
7247 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7248 [(set_attr "type" "sload")
7249 (set_attr "us3load_type" "3cycle")])
7251 (define_insn "*tldo_ldsb2_sp64"
7252 [(set (match_operand:SI 0 "register_operand" "=r")
7253 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7254 (match_operand 3 "tld_symbolic_operand" "")]
7256 (match_operand:DI 1 "register_operand" "r")))))]
7257 "TARGET_TLS && TARGET_ARCH64"
7258 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7259 [(set_attr "type" "sload")
7260 (set_attr "us3load_type" "3cycle")])
7262 (define_insn "*tldo_ldsb3_sp64"
7263 [(set (match_operand:DI 0 "register_operand" "=r")
7264 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7265 (match_operand 3 "tld_symbolic_operand" "")]
7267 (match_operand:DI 1 "register_operand" "r")))))]
7268 "TARGET_TLS && TARGET_ARCH64"
7269 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7270 [(set_attr "type" "sload")
7271 (set_attr "us3load_type" "3cycle")])
7273 (define_insn "*tldo_lduh_sp32"
7274 [(set (match_operand:HI 0 "register_operand" "=r")
7275 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7276 (match_operand 3 "tld_symbolic_operand" "")]
7278 (match_operand:SI 1 "register_operand" "r"))))]
7279 "TARGET_TLS && TARGET_ARCH32"
7280 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7281 [(set_attr "type" "load")
7282 (set_attr "us3load_type" "3cycle")])
7284 (define_insn "*tldo_lduh1_sp32"
7285 [(set (match_operand:SI 0 "register_operand" "=r")
7286 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7287 (match_operand 3 "tld_symbolic_operand" "")]
7289 (match_operand:SI 1 "register_operand" "r")))))]
7290 "TARGET_TLS && TARGET_ARCH32"
7291 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7292 [(set_attr "type" "load")
7293 (set_attr "us3load_type" "3cycle")])
7295 (define_insn "*tldo_ldsh1_sp32"
7296 [(set (match_operand:SI 0 "register_operand" "=r")
7297 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7298 (match_operand 3 "tld_symbolic_operand" "")]
7300 (match_operand:SI 1 "register_operand" "r")))))]
7301 "TARGET_TLS && TARGET_ARCH32"
7302 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7303 [(set_attr "type" "sload")
7304 (set_attr "us3load_type" "3cycle")])
7306 (define_insn "*tldo_lduh_sp64"
7307 [(set (match_operand:HI 0 "register_operand" "=r")
7308 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7309 (match_operand 3 "tld_symbolic_operand" "")]
7311 (match_operand:DI 1 "register_operand" "r"))))]
7312 "TARGET_TLS && TARGET_ARCH64"
7313 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7314 [(set_attr "type" "load")
7315 (set_attr "us3load_type" "3cycle")])
7317 (define_insn "*tldo_lduh1_sp64"
7318 [(set (match_operand:SI 0 "register_operand" "=r")
7319 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7320 (match_operand 3 "tld_symbolic_operand" "")]
7322 (match_operand:DI 1 "register_operand" "r")))))]
7323 "TARGET_TLS && TARGET_ARCH64"
7324 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7325 [(set_attr "type" "load")
7326 (set_attr "us3load_type" "3cycle")])
7328 (define_insn "*tldo_lduh2_sp64"
7329 [(set (match_operand:DI 0 "register_operand" "=r")
7330 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7331 (match_operand 3 "tld_symbolic_operand" "")]
7333 (match_operand:DI 1 "register_operand" "r")))))]
7334 "TARGET_TLS && TARGET_ARCH64"
7335 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7336 [(set_attr "type" "load")
7337 (set_attr "us3load_type" "3cycle")])
7339 (define_insn "*tldo_ldsh1_sp64"
7340 [(set (match_operand:SI 0 "register_operand" "=r")
7341 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7342 (match_operand 3 "tld_symbolic_operand" "")]
7344 (match_operand:DI 1 "register_operand" "r")))))]
7345 "TARGET_TLS && TARGET_ARCH64"
7346 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7347 [(set_attr "type" "sload")
7348 (set_attr "us3load_type" "3cycle")])
7350 (define_insn "*tldo_ldsh2_sp64"
7351 [(set (match_operand:DI 0 "register_operand" "=r")
7352 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7353 (match_operand 3 "tld_symbolic_operand" "")]
7355 (match_operand:DI 1 "register_operand" "r")))))]
7356 "TARGET_TLS && TARGET_ARCH64"
7357 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7358 [(set_attr "type" "sload")
7359 (set_attr "us3load_type" "3cycle")])
7361 (define_insn "*tldo_lduw_sp32"
7362 [(set (match_operand:SI 0 "register_operand" "=r")
7363 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7364 (match_operand 3 "tld_symbolic_operand" "")]
7366 (match_operand:SI 1 "register_operand" "r"))))]
7367 "TARGET_TLS && TARGET_ARCH32"
7368 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7369 [(set_attr "type" "load")])
7371 (define_insn "*tldo_lduw_sp64"
7372 [(set (match_operand:SI 0 "register_operand" "=r")
7373 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7374 (match_operand 3 "tld_symbolic_operand" "")]
7376 (match_operand:DI 1 "register_operand" "r"))))]
7377 "TARGET_TLS && TARGET_ARCH64"
7378 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7379 [(set_attr "type" "load")])
7381 (define_insn "*tldo_lduw1_sp64"
7382 [(set (match_operand:DI 0 "register_operand" "=r")
7383 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7384 (match_operand 3 "tld_symbolic_operand" "")]
7386 (match_operand:DI 1 "register_operand" "r")))))]
7387 "TARGET_TLS && TARGET_ARCH64"
7388 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7389 [(set_attr "type" "load")])
7391 (define_insn "*tldo_ldsw1_sp64"
7392 [(set (match_operand:DI 0 "register_operand" "=r")
7393 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7394 (match_operand 3 "tld_symbolic_operand" "")]
7396 (match_operand:DI 1 "register_operand" "r")))))]
7397 "TARGET_TLS && TARGET_ARCH64"
7398 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7399 [(set_attr "type" "sload")
7400 (set_attr "us3load_type" "3cycle")])
7402 (define_insn "*tldo_ldx_sp64"
7403 [(set (match_operand:DI 0 "register_operand" "=r")
7404 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7405 (match_operand 3 "tld_symbolic_operand" "")]
7407 (match_operand:DI 1 "register_operand" "r"))))]
7408 "TARGET_TLS && TARGET_ARCH64"
7409 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7410 [(set_attr "type" "load")])
7412 (define_insn "*tldo_stb_sp32"
7413 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7414 (match_operand 3 "tld_symbolic_operand" "")]
7416 (match_operand:SI 1 "register_operand" "r")))
7417 (match_operand:QI 0 "register_operand" "=r"))]
7418 "TARGET_TLS && TARGET_ARCH32"
7419 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7420 [(set_attr "type" "store")])
7422 (define_insn "*tldo_stb_sp64"
7423 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7424 (match_operand 3 "tld_symbolic_operand" "")]
7426 (match_operand:DI 1 "register_operand" "r")))
7427 (match_operand:QI 0 "register_operand" "=r"))]
7428 "TARGET_TLS && TARGET_ARCH64"
7429 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7430 [(set_attr "type" "store")])
7432 (define_insn "*tldo_sth_sp32"
7433 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7434 (match_operand 3 "tld_symbolic_operand" "")]
7436 (match_operand:SI 1 "register_operand" "r")))
7437 (match_operand:HI 0 "register_operand" "=r"))]
7438 "TARGET_TLS && TARGET_ARCH32"
7439 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7440 [(set_attr "type" "store")])
7442 (define_insn "*tldo_sth_sp64"
7443 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7444 (match_operand 3 "tld_symbolic_operand" "")]
7446 (match_operand:DI 1 "register_operand" "r")))
7447 (match_operand:HI 0 "register_operand" "=r"))]
7448 "TARGET_TLS && TARGET_ARCH64"
7449 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7450 [(set_attr "type" "store")])
7452 (define_insn "*tldo_stw_sp32"
7453 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7454 (match_operand 3 "tld_symbolic_operand" "")]
7456 (match_operand:SI 1 "register_operand" "r")))
7457 (match_operand:SI 0 "register_operand" "=r"))]
7458 "TARGET_TLS && TARGET_ARCH32"
7459 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7460 [(set_attr "type" "store")])
7462 (define_insn "*tldo_stw_sp64"
7463 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7464 (match_operand 3 "tld_symbolic_operand" "")]
7466 (match_operand:DI 1 "register_operand" "r")))
7467 (match_operand:SI 0 "register_operand" "=r"))]
7468 "TARGET_TLS && TARGET_ARCH64"
7469 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7470 [(set_attr "type" "store")])
7472 (define_insn "*tldo_stx_sp64"
7473 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7474 (match_operand 3 "tld_symbolic_operand" "")]
7476 (match_operand:DI 1 "register_operand" "r")))
7477 (match_operand:DI 0 "register_operand" "=r"))]
7478 "TARGET_TLS && TARGET_ARCH64"
7479 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7480 [(set_attr "type" "store")])
7483 ;; Stack protector instructions.
7485 (define_expand "stack_protect_set"
7486 [(match_operand 0 "memory_operand" "")
7487 (match_operand 1 "memory_operand" "")]
7490 #ifdef TARGET_THREAD_SSP_OFFSET
7491 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7492 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7493 operands[1] = gen_rtx_MEM (Pmode, addr);
7496 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7498 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7502 (define_insn "stack_protect_setsi"
7503 [(set (match_operand:SI 0 "memory_operand" "=m")
7504 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7505 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7507 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7508 [(set_attr "type" "multi")
7509 (set_attr "length" "3")])
7511 (define_insn "stack_protect_setdi"
7512 [(set (match_operand:DI 0 "memory_operand" "=m")
7513 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7514 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7516 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7517 [(set_attr "type" "multi")
7518 (set_attr "length" "3")])
7520 (define_expand "stack_protect_test"
7521 [(match_operand 0 "memory_operand" "")
7522 (match_operand 1 "memory_operand" "")
7523 (match_operand 2 "" "")]
7527 #ifdef TARGET_THREAD_SSP_OFFSET
7528 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7529 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7530 operands[1] = gen_rtx_MEM (Pmode, addr);
7534 result = gen_reg_rtx (Pmode);
7535 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7536 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7537 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7541 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7542 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7543 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7544 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7549 (define_insn "stack_protect_testsi"
7551 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7552 (match_operand:SI 1 "memory_operand" "m")]
7554 (set (match_scratch:SI 3 "=r") (const_int 0))
7555 (clobber (match_scratch:SI 2 "=&r"))]
7557 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7558 [(set_attr "type" "multi")
7559 (set_attr "length" "4")])
7561 (define_insn "stack_protect_testdi"
7562 [(set (match_operand:DI 0 "register_operand" "=&r")
7563 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7564 (match_operand:DI 2 "memory_operand" "m")]
7566 (set (match_scratch:DI 3 "=r") (const_int 0))]
7568 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7569 [(set_attr "type" "multi")
7570 (set_attr "length" "4")])
7573 ;; Vector instructions.
7575 (define_insn "addv2si3"
7576 [(set (match_operand:V2SI 0 "register_operand" "=e")
7577 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7578 (match_operand:V2SI 2 "register_operand" "e")))]
7580 "fpadd32\t%1, %2, %0"
7581 [(set_attr "type" "fga")
7582 (set_attr "fptype" "double")])
7584 (define_insn "addv4hi3"
7585 [(set (match_operand:V4HI 0 "register_operand" "=e")
7586 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7587 (match_operand:V4HI 2 "register_operand" "e")))]
7589 "fpadd16\t%1, %2, %0"
7590 [(set_attr "type" "fga")
7591 (set_attr "fptype" "double")])
7593 ;; fpadd32s is emitted by the addsi3 pattern.
7595 (define_insn "addv2hi3"
7596 [(set (match_operand:V2HI 0 "register_operand" "=f")
7597 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7598 (match_operand:V2HI 2 "register_operand" "f")))]
7600 "fpadd16s\t%1, %2, %0"
7601 [(set_attr "type" "fga")
7602 (set_attr "fptype" "single")])
7604 (define_insn "subv2si3"
7605 [(set (match_operand:V2SI 0 "register_operand" "=e")
7606 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7607 (match_operand:V2SI 2 "register_operand" "e")))]
7609 "fpsub32\t%1, %2, %0"
7610 [(set_attr "type" "fga")
7611 (set_attr "fptype" "double")])
7613 (define_insn "subv4hi3"
7614 [(set (match_operand:V4HI 0 "register_operand" "=e")
7615 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7616 (match_operand:V4HI 2 "register_operand" "e")))]
7618 "fpsub16\t%1, %2, %0"
7619 [(set_attr "type" "fga")
7620 (set_attr "fptype" "double")])
7622 ;; fpsub32s is emitted by the subsi3 pattern.
7624 (define_insn "subv2hi3"
7625 [(set (match_operand:V2HI 0 "register_operand" "=f")
7626 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7627 (match_operand:V2HI 2 "register_operand" "f")))]
7629 "fpsub16s\t%1, %2, %0"
7630 [(set_attr "type" "fga")
7631 (set_attr "fptype" "single")])
7633 ;; All other logical instructions have integer equivalents so they
7634 ;; are defined together.
7636 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7638 (define_insn "*nand<V64:mode>_vis"
7639 [(set (match_operand:V64 0 "register_operand" "=e")
7640 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7641 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7644 [(set_attr "type" "fga")
7645 (set_attr "fptype" "double")])
7647 (define_insn "*nand<V32:mode>_vis"
7648 [(set (match_operand:V32 0 "register_operand" "=f")
7649 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7650 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7652 "fnands\t%1, %2, %0"
7653 [(set_attr "type" "fga")
7654 (set_attr "fptype" "single")])
7656 ;; Hard to generate VIS instructions. We have builtins for these.
7658 (define_insn "fpack16_vis"
7659 [(set (match_operand:V4QI 0 "register_operand" "=f")
7660 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7664 [(set_attr "type" "fga")
7665 (set_attr "fptype" "double")])
7667 (define_insn "fpackfix_vis"
7668 [(set (match_operand:V2HI 0 "register_operand" "=f")
7669 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7673 [(set_attr "type" "fga")
7674 (set_attr "fptype" "double")])
7676 (define_insn "fpack32_vis"
7677 [(set (match_operand:V8QI 0 "register_operand" "=e")
7678 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7679 (match_operand:V8QI 2 "register_operand" "e")]
7682 "fpack32\t%1, %2, %0"
7683 [(set_attr "type" "fga")
7684 (set_attr "fptype" "double")])
7686 (define_insn "fexpand_vis"
7687 [(set (match_operand:V4HI 0 "register_operand" "=e")
7688 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7692 [(set_attr "type" "fga")
7693 (set_attr "fptype" "double")])
7695 ;; It may be possible to describe this operation as (1 indexed):
7696 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7697 ;; 1,5,10,14,19,23,28,32)
7698 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7699 ;; because vec_merge expects all the operands to be of the same type.
7700 (define_insn "fpmerge_vis"
7701 [(set (match_operand:V8QI 0 "register_operand" "=e")
7702 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7703 (match_operand:V4QI 2 "register_operand" "f")]
7706 "fpmerge\t%1, %2, %0"
7707 [(set_attr "type" "fga")
7708 (set_attr "fptype" "double")])
7710 ;; Partitioned multiply instructions
7711 (define_insn "fmul8x16_vis"
7712 [(set (match_operand:V4HI 0 "register_operand" "=e")
7713 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7714 (match_operand:V4HI 2 "register_operand" "e")))]
7716 "fmul8x16\t%1, %2, %0"
7717 [(set_attr "type" "fpmul")
7718 (set_attr "fptype" "double")])
7720 ;; Only one of the following two insns can be a multiply.
7721 (define_insn "fmul8x16au_vis"
7722 [(set (match_operand:V4HI 0 "register_operand" "=e")
7723 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7724 (match_operand:V2HI 2 "register_operand" "f")))]
7726 "fmul8x16au\t%1, %2, %0"
7727 [(set_attr "type" "fpmul")
7728 (set_attr "fptype" "double")])
7730 (define_insn "fmul8x16al_vis"
7731 [(set (match_operand:V4HI 0 "register_operand" "=e")
7732 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7733 (match_operand:V2HI 2 "register_operand" "f")]
7736 "fmul8x16al\t%1, %2, %0"
7737 [(set_attr "type" "fpmul")
7738 (set_attr "fptype" "double")])
7740 ;; Only one of the following two insns can be a multiply.
7741 (define_insn "fmul8sux16_vis"
7742 [(set (match_operand:V4HI 0 "register_operand" "=e")
7743 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7744 (match_operand:V4HI 2 "register_operand" "e")))]
7746 "fmul8sux16\t%1, %2, %0"
7747 [(set_attr "type" "fpmul")
7748 (set_attr "fptype" "double")])
7750 (define_insn "fmul8ulx16_vis"
7751 [(set (match_operand:V4HI 0 "register_operand" "=e")
7752 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7753 (match_operand:V4HI 2 "register_operand" "e")]
7756 "fmul8ulx16\t%1, %2, %0"
7757 [(set_attr "type" "fpmul")
7758 (set_attr "fptype" "double")])
7760 ;; Only one of the following two insns can be a multiply.
7761 (define_insn "fmuld8sux16_vis"
7762 [(set (match_operand:V2SI 0 "register_operand" "=e")
7763 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7764 (match_operand:V2HI 2 "register_operand" "f")))]
7766 "fmuld8sux16\t%1, %2, %0"
7767 [(set_attr "type" "fpmul")
7768 (set_attr "fptype" "double")])
7770 (define_insn "fmuld8ulx16_vis"
7771 [(set (match_operand:V2SI 0 "register_operand" "=e")
7772 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7773 (match_operand:V2HI 2 "register_operand" "f")]
7776 "fmuld8ulx16\t%1, %2, %0"
7777 [(set_attr "type" "fpmul")
7778 (set_attr "fptype" "double")])
7780 ;; Using faligndata only makes sense after an alignaddr since the choice of
7781 ;; bytes to take out of each operand is dependent on the results of the last
7783 (define_insn "faligndata<V64I:mode>_vis"
7784 [(set (match_operand:V64I 0 "register_operand" "=e")
7785 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7786 (match_operand:V64I 2 "register_operand" "e")]
7789 "faligndata\t%1, %2, %0"
7790 [(set_attr "type" "fga")
7791 (set_attr "fptype" "double")])
7793 (define_insn "alignaddr<P:mode>_vis"
7794 [(set (match_operand:P 0 "register_operand" "=r")
7795 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7796 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7799 "alignaddr\t%r1, %r2, %0")
7801 (define_insn "pdist_vis"
7802 [(set (match_operand:DI 0 "register_operand" "=e")
7803 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7804 (match_operand:V8QI 2 "register_operand" "e")
7805 (match_operand:DI 3 "register_operand" "0")]
7809 [(set_attr "type" "fga")
7810 (set_attr "fptype" "double")])
7812 ;; Edge instructions produce condition codes equivalent to a 'subcc'
7813 ;; with the same operands.
7814 (define_insn "edge8_vis"
7815 [(set (reg:CCX_NOOV 100)
7816 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
7817 (match_operand:DI 2 "register_operand" "rJ"))
7819 (set (match_operand:DI 0 "register_operand" "=r")
7820 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
7822 "edge8\t%r1, %r2, %0"
7823 [(set_attr "type" "edge")])
7825 (define_insn "edge8l_vis"
7826 [(set (reg:CCX_NOOV 100)
7827 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
7828 (match_operand:DI 2 "register_operand" "rJ"))
7830 (set (match_operand:DI 0 "register_operand" "=r")
7831 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
7833 "edge8l\t%r1, %r2, %0"
7834 [(set_attr "type" "edge")])
7836 (define_insn "edge16_vis"
7837 [(set (reg:CCX_NOOV 100)
7838 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
7839 (match_operand:DI 2 "register_operand" "rJ"))
7841 (set (match_operand:DI 0 "register_operand" "=r")
7842 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
7844 "edge16\t%r1, %r2, %0"
7845 [(set_attr "type" "edge")])
7847 (define_insn "edge16l_vis"
7848 [(set (reg:CCX_NOOV 100)
7849 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
7850 (match_operand:DI 2 "register_operand" "rJ"))
7852 (set (match_operand:DI 0 "register_operand" "=r")
7853 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
7855 "edge16l\t%r1, %r2, %0"
7856 [(set_attr "type" "edge")])
7858 (define_insn "edge32_vis"
7859 [(set (reg:CCX_NOOV 100)
7860 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
7861 (match_operand:DI 2 "register_operand" "rJ"))
7863 (set (match_operand:DI 0 "register_operand" "=r")
7864 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
7866 "edge32\t%r1, %r2, %0"
7867 [(set_attr "type" "edge")])
7869 (define_insn "edge32l_vis"
7870 [(set (reg:CCX_NOOV 100)
7871 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
7872 (match_operand:DI 2 "register_operand" "rJ"))
7874 (set (match_operand:DI 0 "register_operand" "=r")
7875 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
7877 "edge32l\t%r1, %r2, %0"
7878 [(set_attr "type" "edge")])