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)
77 (UNSPECV_PROBE_STACK_RANGE 11)
81 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
82 (define_mode_iterator I [QI HI SI DI])
83 (define_mode_iterator F [SF DF TF])
85 ;; We don't define V1SI because SI should work just fine.
86 (define_mode_iterator V32 [SF V2HI V4QI])
87 (define_mode_iterator V32I [SI V2HI V4QI])
89 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
90 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
92 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
93 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
94 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
95 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
96 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
99 ;; Attribute for cpu type.
100 ;; These must match the values for enum processor_type in sparc.h.
119 (const (symbol_ref "sparc_cpu_attr")))
121 ;; Attribute for the instruction set.
122 ;; At present we only need to distinguish v9/!v9, but for clarity we
123 ;; test TARGET_V8 too.
124 (define_attr "isa" "v7,v8,v9,sparclet"
126 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
127 (symbol_ref "TARGET_V8") (const_string "v8")
128 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
129 (const_string "v7"))))
135 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
143 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
146 multi,savew,flushw,iflush,trap"
147 (const_string "ialu"))
149 ;; True if branch/call has empty delay slot and will emit a nop in it
150 (define_attr "empty_delay_slot" "false,true"
151 (symbol_ref "(empty_delay_slot (insn)
152 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
154 (define_attr "branch_type" "none,icc,fcc,reg"
155 (const_string "none"))
157 (define_attr "pic" "false,true"
158 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
160 (define_attr "calls_alloca" "false,true"
161 (symbol_ref "(cfun->calls_alloca != 0
162 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
164 (define_attr "calls_eh_return" "false,true"
165 (symbol_ref "(crtl->calls_eh_return != 0
166 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
168 (define_attr "leaf_function" "false,true"
169 (symbol_ref "(current_function_uses_only_leaf_regs != 0
170 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
172 (define_attr "delayed_branch" "false,true"
173 (symbol_ref "(flag_delayed_branch != 0
174 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
176 (define_attr "flat" "false,true"
177 (symbol_ref "(TARGET_FLAT != 0
178 ? FLAT_TRUE : FLAT_FALSE)"))
180 ;; Length (in # of insns).
181 ;; Beware that setting a length greater or equal to 3 for conditional branches
182 ;; has a side-effect (see output_cbranch and output_v9branch).
183 (define_attr "length" ""
184 (cond [(eq_attr "type" "uncond_branch,call")
185 (if_then_else (eq_attr "empty_delay_slot" "true")
188 (eq_attr "type" "sibcall")
189 (if_then_else (eq_attr "leaf_function" "true")
190 (if_then_else (eq_attr "empty_delay_slot" "true")
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (eq_attr "branch_type" "icc")
197 (if_then_else (match_operand 0 "noov_compare64_operator" "")
198 (if_then_else (lt (pc) (match_dup 1))
199 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (eq_attr "empty_delay_slot" "true")
206 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
207 (if_then_else (eq_attr "empty_delay_slot" "true")
210 (if_then_else (eq_attr "empty_delay_slot" "true")
213 (if_then_else (eq_attr "empty_delay_slot" "true")
216 (eq_attr "branch_type" "fcc")
217 (if_then_else (match_operand 0 "fcc0_register_operand" "")
218 (if_then_else (eq_attr "empty_delay_slot" "true")
219 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
222 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
225 (if_then_else (lt (pc) (match_dup 2))
226 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
227 (if_then_else (eq_attr "empty_delay_slot" "true")
230 (if_then_else (eq_attr "empty_delay_slot" "true")
233 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
234 (if_then_else (eq_attr "empty_delay_slot" "true")
237 (if_then_else (eq_attr "empty_delay_slot" "true")
240 (eq_attr "branch_type" "reg")
241 (if_then_else (lt (pc) (match_dup 2))
242 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
243 (if_then_else (eq_attr "empty_delay_slot" "true")
246 (if_then_else (eq_attr "empty_delay_slot" "true")
249 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
250 (if_then_else (eq_attr "empty_delay_slot" "true")
253 (if_then_else (eq_attr "empty_delay_slot" "true")
259 (define_attr "fptype" "single,double"
260 (const_string "single"))
262 ;; UltraSPARC-III integer load type.
263 (define_attr "us3load_type" "2cycle,3cycle"
264 (const_string "2cycle"))
266 (define_asm_attributes
267 [(set_attr "length" "2")
268 (set_attr "type" "multi")])
270 ;; Attributes for instruction and branch scheduling
271 (define_attr "tls_call_delay" "false,true"
272 (symbol_ref "(tls_call_delay (insn)
273 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
275 (define_attr "in_call_delay" "false,true"
276 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
277 (const_string "false")
278 (eq_attr "type" "load,fpload,store,fpstore")
279 (if_then_else (eq_attr "length" "1")
280 (const_string "true")
281 (const_string "false"))]
282 (if_then_else (and (eq_attr "length" "1")
283 (eq_attr "tls_call_delay" "true"))
284 (const_string "true")
285 (const_string "false"))))
287 (define_attr "eligible_for_sibcall_delay" "false,true"
288 (symbol_ref "(eligible_for_sibcall_delay (insn)
289 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
290 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
292 (define_attr "eligible_for_return_delay" "false,true"
293 (symbol_ref "(eligible_for_return_delay (insn)
294 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
295 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
297 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
298 ;; branches. This would allow us to remove the nop always inserted before
299 ;; a floating point branch.
301 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
302 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
303 ;; This is because doing so will add several pipeline stalls to the path
304 ;; that the load/store did not come from. Unfortunately, there is no way
305 ;; to prevent fill_eager_delay_slots from using load/store without completely
306 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
307 ;; because it prevents us from moving back the final store of inner loops.
309 (define_attr "in_branch_delay" "false,true"
310 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
311 (eq_attr "length" "1"))
312 (const_string "true")
313 (const_string "false")))
315 (define_attr "in_uncond_branch_delay" "false,true"
316 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
317 (eq_attr "length" "1"))
318 (const_string "true")
319 (const_string "false")))
321 (define_attr "in_annul_branch_delay" "false,true"
322 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
323 (eq_attr "length" "1"))
324 (const_string "true")
325 (const_string "false")))
327 (define_delay (eq_attr "type" "call")
328 [(eq_attr "in_call_delay" "true") (nil) (nil)])
330 (define_delay (eq_attr "type" "sibcall")
331 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
333 (define_delay (eq_attr "type" "branch")
334 [(eq_attr "in_branch_delay" "true")
335 (nil) (eq_attr "in_annul_branch_delay" "true")])
337 (define_delay (eq_attr "type" "uncond_branch")
338 [(eq_attr "in_uncond_branch_delay" "true")
341 (define_delay (eq_attr "type" "return")
342 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
345 ;; Include SPARC DFA schedulers
347 (include "cypress.md")
348 (include "supersparc.md")
349 (include "hypersparc.md")
351 (include "sparclet.md")
352 (include "ultra1_2.md")
353 (include "ultra3.md")
354 (include "niagara.md")
355 (include "niagara2.md")
358 ;; Operand and operator predicates and constraints
360 (include "predicates.md")
361 (include "constraints.md")
364 ;; Compare instructions.
366 ;; These are just the DEFINE_INSNs to match the patterns and the
367 ;; DEFINE_SPLITs for some of the scc insns that actually require
368 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
370 ;; The compare DEFINE_INSNs.
372 (define_insn "*cmpsi_insn"
374 (compare:CC (match_operand:SI 0 "register_operand" "r")
375 (match_operand:SI 1 "arith_operand" "rI")))]
378 [(set_attr "type" "compare")])
380 (define_insn "*cmpdi_sp64"
382 (compare:CCX (match_operand:DI 0 "register_operand" "r")
383 (match_operand:DI 1 "arith_operand" "rI")))]
386 [(set_attr "type" "compare")])
388 (define_insn "*cmpsf_fpe"
389 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
390 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
391 (match_operand:SF 2 "register_operand" "f")))]
395 return "fcmpes\t%0, %1, %2";
396 return "fcmpes\t%1, %2";
398 [(set_attr "type" "fpcmp")])
400 (define_insn "*cmpdf_fpe"
401 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
402 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
403 (match_operand:DF 2 "register_operand" "e")))]
407 return "fcmped\t%0, %1, %2";
408 return "fcmped\t%1, %2";
410 [(set_attr "type" "fpcmp")
411 (set_attr "fptype" "double")])
413 (define_insn "*cmptf_fpe"
414 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
415 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
416 (match_operand:TF 2 "register_operand" "e")))]
417 "TARGET_FPU && TARGET_HARD_QUAD"
420 return "fcmpeq\t%0, %1, %2";
421 return "fcmpeq\t%1, %2";
423 [(set_attr "type" "fpcmp")])
425 (define_insn "*cmpsf_fp"
426 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
427 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
428 (match_operand:SF 2 "register_operand" "f")))]
432 return "fcmps\t%0, %1, %2";
433 return "fcmps\t%1, %2";
435 [(set_attr "type" "fpcmp")])
437 (define_insn "*cmpdf_fp"
438 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
439 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
440 (match_operand:DF 2 "register_operand" "e")))]
444 return "fcmpd\t%0, %1, %2";
445 return "fcmpd\t%1, %2";
447 [(set_attr "type" "fpcmp")
448 (set_attr "fptype" "double")])
450 (define_insn "*cmptf_fp"
451 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
452 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
453 (match_operand:TF 2 "register_operand" "e")))]
454 "TARGET_FPU && TARGET_HARD_QUAD"
457 return "fcmpq\t%0, %1, %2";
458 return "fcmpq\t%1, %2";
460 [(set_attr "type" "fpcmp")])
462 ;; Next come the scc insns.
464 (define_expand "cstoresi4"
465 [(use (match_operator 1 "comparison_operator"
466 [(match_operand:SI 2 "compare_operand" "")
467 (match_operand:SI 3 "arith_operand" "")]))
468 (clobber (match_operand:SI 0 "register_operand"))]
471 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
472 operands[2] = force_reg (SImode, operands[2]);
473 if (emit_scc_insn (operands)) DONE; else FAIL;
476 (define_expand "cstoredi4"
477 [(use (match_operator 1 "comparison_operator"
478 [(match_operand:DI 2 "compare_operand" "")
479 (match_operand:DI 3 "arith_operand" "")]))
480 (clobber (match_operand:SI 0 "register_operand"))]
483 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
484 operands[2] = force_reg (DImode, operands[2]);
485 if (emit_scc_insn (operands)) DONE; else FAIL;
488 (define_expand "cstore<F:mode>4"
489 [(use (match_operator 1 "comparison_operator"
490 [(match_operand:F 2 "register_operand" "")
491 (match_operand:F 3 "register_operand" "")]))
492 (clobber (match_operand:SI 0 "register_operand"))]
494 { if (emit_scc_insn (operands)) DONE; else FAIL; })
498 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
499 ;; generate addcc/subcc instructions.
501 (define_expand "seqsi_special"
503 (xor:SI (match_operand:SI 1 "register_operand" "")
504 (match_operand:SI 2 "register_operand" "")))
505 (parallel [(set (match_operand:SI 0 "register_operand" "")
506 (eq:SI (match_dup 3) (const_int 0)))
507 (clobber (reg:CC 100))])]
509 { operands[3] = gen_reg_rtx (SImode); })
511 (define_expand "seqdi_special"
513 (xor:DI (match_operand:DI 1 "register_operand" "")
514 (match_operand:DI 2 "register_operand" "")))
515 (set (match_operand:SI 0 "register_operand" "")
516 (eq:SI (match_dup 3) (const_int 0)))]
518 { operands[3] = gen_reg_rtx (DImode); })
520 (define_expand "snesi_special"
522 (xor:SI (match_operand:SI 1 "register_operand" "")
523 (match_operand:SI 2 "register_operand" "")))
524 (parallel [(set (match_operand:SI 0 "register_operand" "")
525 (ne:SI (match_dup 3) (const_int 0)))
526 (clobber (reg:CC 100))])]
528 { operands[3] = gen_reg_rtx (SImode); })
530 (define_expand "snedi_special"
532 (xor:DI (match_operand:DI 1 "register_operand" "")
533 (match_operand:DI 2 "register_operand" "")))
534 (set (match_operand:SI 0 "register_operand" "")
535 (ne:SI (match_dup 3) (const_int 0)))]
537 { operands[3] = gen_reg_rtx (DImode); })
540 ;; Now the DEFINE_INSNs for the scc cases.
542 ;; The SEQ and SNE patterns are special because they can be done
543 ;; without any branching and do not involve a COMPARE. We want
544 ;; them to always use the splits below so the results can be
547 (define_insn_and_split "*snesi_zero"
548 [(set (match_operand:SI 0 "register_operand" "=r")
549 (ne:SI (match_operand:SI 1 "register_operand" "r")
551 (clobber (reg:CC 100))]
555 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
557 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
559 [(set_attr "length" "2")])
561 (define_insn_and_split "*neg_snesi_zero"
562 [(set (match_operand:SI 0 "register_operand" "=r")
563 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
565 (clobber (reg:CC 100))]
569 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
571 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
573 [(set_attr "length" "2")])
575 (define_insn_and_split "*snesi_zero_extend"
576 [(set (match_operand:DI 0 "register_operand" "=r")
577 (ne:DI (match_operand:SI 1 "register_operand" "r")
579 (clobber (reg:CC 100))]
583 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
586 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
588 (ltu:SI (reg:CC_NOOV 100)
591 [(set_attr "length" "2")])
593 (define_insn_and_split "*snedi_zero"
594 [(set (match_operand:DI 0 "register_operand" "=&r")
595 (ne:DI (match_operand:DI 1 "register_operand" "r")
599 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
600 [(set (match_dup 0) (const_int 0))
601 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
606 [(set_attr "length" "2")])
608 (define_insn_and_split "*neg_snedi_zero"
609 [(set (match_operand:DI 0 "register_operand" "=&r")
610 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
614 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
615 [(set (match_dup 0) (const_int 0))
616 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
621 [(set_attr "length" "2")])
623 (define_insn_and_split "*snedi_zero_trunc"
624 [(set (match_operand:SI 0 "register_operand" "=&r")
625 (ne:SI (match_operand:DI 1 "register_operand" "r")
629 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
630 [(set (match_dup 0) (const_int 0))
631 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
636 [(set_attr "length" "2")])
638 (define_insn_and_split "*seqsi_zero"
639 [(set (match_operand:SI 0 "register_operand" "=r")
640 (eq:SI (match_operand:SI 1 "register_operand" "r")
642 (clobber (reg:CC 100))]
646 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
648 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
650 [(set_attr "length" "2")])
652 (define_insn_and_split "*neg_seqsi_zero"
653 [(set (match_operand:SI 0 "register_operand" "=r")
654 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
656 (clobber (reg:CC 100))]
660 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
662 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
664 [(set_attr "length" "2")])
666 (define_insn_and_split "*seqsi_zero_extend"
667 [(set (match_operand:DI 0 "register_operand" "=r")
668 (eq:DI (match_operand:SI 1 "register_operand" "r")
670 (clobber (reg:CC 100))]
674 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
677 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
679 (ltu:SI (reg:CC_NOOV 100)
682 [(set_attr "length" "2")])
684 (define_insn_and_split "*seqdi_zero"
685 [(set (match_operand:DI 0 "register_operand" "=&r")
686 (eq:DI (match_operand:DI 1 "register_operand" "r")
690 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
691 [(set (match_dup 0) (const_int 0))
692 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
697 [(set_attr "length" "2")])
699 (define_insn_and_split "*neg_seqdi_zero"
700 [(set (match_operand:DI 0 "register_operand" "=&r")
701 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
705 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
706 [(set (match_dup 0) (const_int 0))
707 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
712 [(set_attr "length" "2")])
714 (define_insn_and_split "*seqdi_zero_trunc"
715 [(set (match_operand:SI 0 "register_operand" "=&r")
716 (eq:SI (match_operand:DI 1 "register_operand" "r")
720 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
721 [(set (match_dup 0) (const_int 0))
722 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
727 [(set_attr "length" "2")])
729 ;; We can also do (x + (i == 0)) and related, so put them in.
730 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
733 (define_insn_and_split "*x_plus_i_ne_0"
734 [(set (match_operand:SI 0 "register_operand" "=r")
735 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
737 (match_operand:SI 2 "register_operand" "r")))
738 (clobber (reg:CC 100))]
742 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
744 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
747 [(set_attr "length" "2")])
749 (define_insn_and_split "*x_minus_i_ne_0"
750 [(set (match_operand:SI 0 "register_operand" "=r")
751 (minus:SI (match_operand:SI 2 "register_operand" "r")
752 (ne:SI (match_operand:SI 1 "register_operand" "r")
754 (clobber (reg:CC 100))]
758 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
760 (set (match_dup 0) (minus:SI (match_dup 2)
761 (ltu:SI (reg:CC 100) (const_int 0))))]
763 [(set_attr "length" "2")])
765 (define_insn_and_split "*x_plus_i_eq_0"
766 [(set (match_operand:SI 0 "register_operand" "=r")
767 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
769 (match_operand:SI 2 "register_operand" "r")))
770 (clobber (reg:CC 100))]
774 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
776 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
779 [(set_attr "length" "2")])
781 (define_insn_and_split "*x_minus_i_eq_0"
782 [(set (match_operand:SI 0 "register_operand" "=r")
783 (minus:SI (match_operand:SI 2 "register_operand" "r")
784 (eq:SI (match_operand:SI 1 "register_operand" "r")
786 (clobber (reg:CC 100))]
790 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
792 (set (match_dup 0) (minus:SI (match_dup 2)
793 (geu:SI (reg:CC 100) (const_int 0))))]
795 [(set_attr "length" "2")])
797 ;; We can also do GEU and LTU directly, but these operate after a compare.
798 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
801 (define_insn "*sltu_insn"
802 [(set (match_operand:SI 0 "register_operand" "=r")
803 (ltu:SI (reg:CC 100) (const_int 0)))]
806 [(set_attr "type" "ialuX")])
808 (define_insn "*neg_sltu_insn"
809 [(set (match_operand:SI 0 "register_operand" "=r")
810 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
813 [(set_attr "type" "ialuX")])
815 ;; ??? Combine should canonicalize these next two to the same pattern.
816 (define_insn "*neg_sltu_minus_x"
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
819 (match_operand:SI 1 "arith_operand" "rI")))]
822 [(set_attr "type" "ialuX")])
824 (define_insn "*neg_sltu_plus_x"
825 [(set (match_operand:SI 0 "register_operand" "=r")
826 (neg:SI (plus: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 "*sgeu_insn"
833 [(set (match_operand:SI 0 "register_operand" "=r")
834 (geu:SI (reg:CC 100) (const_int 0)))]
837 [(set_attr "type" "ialuX")])
839 (define_insn "*neg_sgeu_insn"
840 [(set (match_operand:SI 0 "register_operand" "=r")
841 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
844 [(set_attr "type" "ialuX")])
846 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
847 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
850 (define_insn "*sltu_plus_x"
851 [(set (match_operand:SI 0 "register_operand" "=r")
852 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
853 (match_operand:SI 1 "arith_operand" "rI")))]
856 [(set_attr "type" "ialuX")])
858 (define_insn "*sltu_plus_x_plus_y"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
861 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
862 (match_operand:SI 2 "arith_operand" "rI"))))]
865 [(set_attr "type" "ialuX")])
867 (define_insn "*x_minus_sltu"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (minus:SI (match_operand:SI 1 "register_operand" "r")
870 (ltu:SI (reg:CC 100) (const_int 0))))]
873 [(set_attr "type" "ialuX")])
875 ;; ??? Combine should canonicalize these next two to the same pattern.
876 (define_insn "*x_minus_y_minus_sltu"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
879 (match_operand:SI 2 "arith_operand" "rI"))
880 (ltu:SI (reg:CC 100) (const_int 0))))]
883 [(set_attr "type" "ialuX")])
885 (define_insn "*x_minus_sltu_plus_y"
886 [(set (match_operand:SI 0 "register_operand" "=r")
887 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
888 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
889 (match_operand:SI 2 "arith_operand" "rI"))))]
892 [(set_attr "type" "ialuX")])
894 (define_insn "*sgeu_plus_x"
895 [(set (match_operand:SI 0 "register_operand" "=r")
896 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
897 (match_operand:SI 1 "register_operand" "r")))]
900 [(set_attr "type" "ialuX")])
902 (define_insn "*x_minus_sgeu"
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (minus:SI (match_operand:SI 1 "register_operand" "r")
905 (geu:SI (reg:CC 100) (const_int 0))))]
908 [(set_attr "type" "ialuX")])
911 [(set (match_operand:SI 0 "register_operand" "")
912 (match_operator:SI 2 "noov_compare_operator"
913 [(match_operand 1 "icc_or_fcc_register_operand" "")
916 && REGNO (operands[1]) == SPARC_ICC_REG
917 && (GET_MODE (operands[1]) == CCXmode
918 /* 32-bit LTU/GEU are better implemented using addx/subx. */
919 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
920 [(set (match_dup 0) (const_int 0))
922 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
928 ;; These control RTL generation for conditional jump insns
930 (define_expand "cbranchcc4"
932 (if_then_else (match_operator 0 "comparison_operator"
933 [(match_operand 1 "compare_operand" "")
934 (match_operand 2 "const_zero_operand" "")])
935 (label_ref (match_operand 3 "" ""))
940 (define_expand "cbranchsi4"
941 [(use (match_operator 0 "comparison_operator"
942 [(match_operand:SI 1 "compare_operand" "")
943 (match_operand:SI 2 "arith_operand" "")]))
944 (use (match_operand 3 ""))]
947 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
948 operands[1] = force_reg (SImode, operands[1]);
949 emit_conditional_branch_insn (operands);
953 (define_expand "cbranchdi4"
954 [(use (match_operator 0 "comparison_operator"
955 [(match_operand:DI 1 "compare_operand" "")
956 (match_operand:DI 2 "arith_operand" "")]))
957 (use (match_operand 3 ""))]
960 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
961 operands[1] = force_reg (DImode, operands[1]);
962 emit_conditional_branch_insn (operands);
966 (define_expand "cbranch<F:mode>4"
967 [(use (match_operator 0 "comparison_operator"
968 [(match_operand:F 1 "register_operand" "")
969 (match_operand:F 2 "register_operand" "")]))
970 (use (match_operand 3 ""))]
972 { emit_conditional_branch_insn (operands); DONE; })
975 ;; Now match both normal and inverted jump.
977 ;; XXX fpcmp nop braindamage
978 (define_insn "*normal_branch"
980 (if_then_else (match_operator 0 "noov_compare_operator"
981 [(reg 100) (const_int 0)])
982 (label_ref (match_operand 1 "" ""))
986 return output_cbranch (operands[0], operands[1], 1, 0,
987 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
990 [(set_attr "type" "branch")
991 (set_attr "branch_type" "icc")])
993 ;; XXX fpcmp nop braindamage
994 (define_insn "*inverted_branch"
996 (if_then_else (match_operator 0 "noov_compare_operator"
997 [(reg 100) (const_int 0)])
999 (label_ref (match_operand 1 "" ""))))]
1002 return output_cbranch (operands[0], operands[1], 1, 1,
1003 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1006 [(set_attr "type" "branch")
1007 (set_attr "branch_type" "icc")])
1009 ;; XXX fpcmp nop braindamage
1010 (define_insn "*normal_fp_branch"
1012 (if_then_else (match_operator 1 "comparison_operator"
1013 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1015 (label_ref (match_operand 2 "" ""))
1019 return output_cbranch (operands[1], operands[2], 2, 0,
1020 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1023 [(set_attr "type" "branch")
1024 (set_attr "branch_type" "fcc")])
1026 ;; XXX fpcmp nop braindamage
1027 (define_insn "*inverted_fp_branch"
1029 (if_then_else (match_operator 1 "comparison_operator"
1030 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1033 (label_ref (match_operand 2 "" ""))))]
1036 return output_cbranch (operands[1], operands[2], 2, 1,
1037 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1040 [(set_attr "type" "branch")
1041 (set_attr "branch_type" "fcc")])
1043 ;; XXX fpcmp nop braindamage
1044 (define_insn "*normal_fpe_branch"
1046 (if_then_else (match_operator 1 "comparison_operator"
1047 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1049 (label_ref (match_operand 2 "" ""))
1053 return output_cbranch (operands[1], operands[2], 2, 0,
1054 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1057 [(set_attr "type" "branch")
1058 (set_attr "branch_type" "fcc")])
1060 ;; XXX fpcmp nop braindamage
1061 (define_insn "*inverted_fpe_branch"
1063 (if_then_else (match_operator 1 "comparison_operator"
1064 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1067 (label_ref (match_operand 2 "" ""))))]
1070 return output_cbranch (operands[1], operands[2], 2, 1,
1071 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1074 [(set_attr "type" "branch")
1075 (set_attr "branch_type" "fcc")])
1077 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1078 ;; in the architecture.
1080 ;; There are no 32 bit brreg insns.
1083 (define_insn "*normal_int_branch_sp64"
1085 (if_then_else (match_operator 0 "v9_register_compare_operator"
1086 [(match_operand:DI 1 "register_operand" "r")
1088 (label_ref (match_operand 2 "" ""))
1092 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1093 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1096 [(set_attr "type" "branch")
1097 (set_attr "branch_type" "reg")])
1100 (define_insn "*inverted_int_branch_sp64"
1102 (if_then_else (match_operator 0 "v9_register_compare_operator"
1103 [(match_operand:DI 1 "register_operand" "r")
1106 (label_ref (match_operand 2 "" ""))))]
1109 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1110 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1113 [(set_attr "type" "branch")
1114 (set_attr "branch_type" "reg")])
1117 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1118 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1119 ;; that adds the PC value at the call point to register #(operand 3).
1121 (define_insn "load_pcrel_sym<P:mode>"
1122 [(set (match_operand:P 0 "register_operand" "=r")
1123 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1124 (match_operand:P 2 "call_address_operand" "")
1125 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1126 (clobber (reg:P 15))]
1127 "REGNO (operands[0]) == INTVAL (operands[3])"
1129 if (flag_delayed_branch)
1130 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1132 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1134 [(set (attr "type") (const_string "multi"))
1135 (set (attr "length")
1136 (if_then_else (eq_attr "delayed_branch" "true")
1141 ;; Integer move instructions
1143 (define_expand "movqi"
1144 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1145 (match_operand:QI 1 "general_operand" ""))]
1148 if (sparc_expand_move (QImode, operands))
1152 (define_insn "*movqi_insn"
1153 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1154 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1155 "(register_operand (operands[0], QImode)
1156 || register_or_zero_operand (operands[1], QImode))"
1161 [(set_attr "type" "*,load,store")
1162 (set_attr "us3load_type" "*,3cycle,*")])
1164 (define_expand "movhi"
1165 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1166 (match_operand:HI 1 "general_operand" ""))]
1169 if (sparc_expand_move (HImode, operands))
1173 (define_insn "*movhi_insn"
1174 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1175 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1176 "(register_operand (operands[0], HImode)
1177 || register_or_zero_operand (operands[1], HImode))"
1180 sethi\t%%hi(%a1), %0
1183 [(set_attr "type" "*,*,load,store")
1184 (set_attr "us3load_type" "*,*,3cycle,*")])
1186 ;; We always work with constants here.
1187 (define_insn "*movhi_lo_sum"
1188 [(set (match_operand:HI 0 "register_operand" "=r")
1189 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1190 (match_operand:HI 2 "small_int_operand" "I")))]
1194 (define_expand "movsi"
1195 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1196 (match_operand:SI 1 "general_operand" ""))]
1199 if (sparc_expand_move (SImode, operands))
1203 (define_insn "*movsi_insn"
1204 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1205 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1206 "(register_operand (operands[0], SImode)
1207 || register_or_zero_operand (operands[1], SImode))"
1210 sethi\t%%hi(%a1), %0
1217 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1219 (define_insn "*movsi_lo_sum"
1220 [(set (match_operand:SI 0 "register_operand" "=r")
1221 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1222 (match_operand:SI 2 "immediate_operand" "in")))]
1224 "or\t%1, %%lo(%a2), %0")
1226 (define_insn "*movsi_high"
1227 [(set (match_operand:SI 0 "register_operand" "=r")
1228 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1230 "sethi\t%%hi(%a1), %0")
1232 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1233 ;; so that CSE won't optimize the address computation away.
1234 (define_insn "movsi_lo_sum_pic"
1235 [(set (match_operand:SI 0 "register_operand" "=r")
1236 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1237 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1240 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1241 return "xor\t%1, %%gdop_lox10(%a2), %0";
1243 return "or\t%1, %%lo(%a2), %0";
1247 (define_insn "movsi_high_pic"
1248 [(set (match_operand:SI 0 "register_operand" "=r")
1249 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1250 "flag_pic && check_pic (1)"
1252 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1253 return "sethi\t%%gdop_hix22(%a1), %0";
1255 return "sethi\t%%hi(%a1), %0";
1259 (define_insn "movsi_pic_gotdata_op"
1260 [(set (match_operand:SI 0 "register_operand" "=r")
1261 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1262 (match_operand:SI 2 "register_operand" "r")
1263 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1264 "flag_pic && check_pic (1)"
1266 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1267 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1269 return "ld\t[%1 + %2], %0";
1272 [(set_attr "type" "load")])
1274 (define_expand "movsi_pic_label_ref"
1275 [(set (match_dup 3) (high:SI
1276 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1277 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1278 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1279 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1280 (set (match_operand:SI 0 "register_operand" "=r")
1281 (minus:SI (match_dup 5) (match_dup 4)))]
1284 crtl->uses_pic_offset_table = 1;
1285 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1286 if (!can_create_pseudo_p ())
1288 operands[3] = operands[0];
1289 operands[4] = operands[0];
1293 operands[3] = gen_reg_rtx (SImode);
1294 operands[4] = gen_reg_rtx (SImode);
1296 operands[5] = pic_offset_table_rtx;
1299 (define_insn "*movsi_high_pic_label_ref"
1300 [(set (match_operand:SI 0 "register_operand" "=r")
1302 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1303 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1305 "sethi\t%%hi(%a2-(%a1-.)), %0")
1307 (define_insn "*movsi_lo_sum_pic_label_ref"
1308 [(set (match_operand:SI 0 "register_operand" "=r")
1309 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1310 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1311 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1313 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1315 ;; Set up the PIC register for VxWorks.
1317 (define_expand "vxworks_load_got"
1319 (high:SI (match_dup 1)))
1321 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1323 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1324 "TARGET_VXWORKS_RTP"
1326 operands[0] = pic_offset_table_rtx;
1327 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1328 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1331 (define_expand "movdi"
1332 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1333 (match_operand:DI 1 "general_operand" ""))]
1336 if (sparc_expand_move (DImode, operands))
1340 ;; Be careful, fmovd does not exist when !v9.
1341 ;; We match MEM moves directly when we have correct even
1342 ;; numbered registers, but fall into splits otherwise.
1343 ;; The constraint ordering here is really important to
1344 ;; avoid insane problems in reload, especially for patterns
1347 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1348 ;; (const_int -5016)))
1352 (define_insn "*movdi_insn_sp32"
1353 [(set (match_operand:DI 0 "nonimmediate_operand"
1354 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1355 (match_operand:DI 1 "input_operand"
1356 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1358 && (register_operand (operands[0], DImode)
1359 || register_or_zero_operand (operands[1], DImode))"
1373 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1374 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1376 (define_insn "*movdi_insn_sp32_v9"
1377 [(set (match_operand:DI 0 "nonimmediate_operand"
1378 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1379 (match_operand:DI 1 "input_operand"
1380 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1383 && (register_operand (operands[0], DImode)
1384 || register_or_zero_operand (operands[1], DImode))"
1401 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1402 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1403 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1405 (define_insn "*movdi_insn_sp64"
1406 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1407 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1409 && (register_operand (operands[0], DImode)
1410 || register_or_zero_operand (operands[1], DImode))"
1413 sethi\t%%hi(%a1), %0
1420 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1421 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1423 (define_expand "movdi_pic_label_ref"
1424 [(set (match_dup 3) (high:DI
1425 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1426 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1427 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1428 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1429 (set (match_operand:DI 0 "register_operand" "=r")
1430 (minus:DI (match_dup 5) (match_dup 4)))]
1431 "TARGET_ARCH64 && flag_pic"
1433 crtl->uses_pic_offset_table = 1;
1434 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1435 if (!can_create_pseudo_p ())
1437 operands[3] = operands[0];
1438 operands[4] = operands[0];
1442 operands[3] = gen_reg_rtx (DImode);
1443 operands[4] = gen_reg_rtx (DImode);
1445 operands[5] = pic_offset_table_rtx;
1448 (define_insn "*movdi_high_pic_label_ref"
1449 [(set (match_operand:DI 0 "register_operand" "=r")
1451 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1452 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1453 "TARGET_ARCH64 && flag_pic"
1454 "sethi\t%%hi(%a2-(%a1-.)), %0")
1456 (define_insn "*movdi_lo_sum_pic_label_ref"
1457 [(set (match_operand:DI 0 "register_operand" "=r")
1458 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1459 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1460 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1461 "TARGET_ARCH64 && flag_pic"
1462 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1464 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1465 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1467 (define_insn "movdi_lo_sum_pic"
1468 [(set (match_operand:DI 0 "register_operand" "=r")
1469 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1470 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1471 "TARGET_ARCH64 && flag_pic"
1473 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1474 return "xor\t%1, %%gdop_lox10(%a2), %0";
1476 return "or\t%1, %%lo(%a2), %0";
1480 (define_insn "movdi_high_pic"
1481 [(set (match_operand:DI 0 "register_operand" "=r")
1482 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1483 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1485 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1486 return "sethi\t%%gdop_hix22(%a1), %0";
1488 return "sethi\t%%hi(%a1), %0";
1492 (define_insn "movdi_pic_gotdata_op"
1493 [(set (match_operand:DI 0 "register_operand" "=r")
1494 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1495 (match_operand:DI 2 "register_operand" "r")
1496 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1497 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1499 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1500 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1502 return "ldx\t[%1 + %2], %0";
1505 [(set_attr "type" "load")])
1507 (define_insn "*sethi_di_medlow_embmedany_pic"
1508 [(set (match_operand:DI 0 "register_operand" "=r")
1509 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1510 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1511 "sethi\t%%hi(%a1), %0")
1513 (define_insn "*sethi_di_medlow"
1514 [(set (match_operand:DI 0 "register_operand" "=r")
1515 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1516 "TARGET_CM_MEDLOW && check_pic (1)"
1517 "sethi\t%%hi(%a1), %0")
1519 (define_insn "*losum_di_medlow"
1520 [(set (match_operand:DI 0 "register_operand" "=r")
1521 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1522 (match_operand:DI 2 "symbolic_operand" "")))]
1524 "or\t%1, %%lo(%a2), %0")
1526 (define_insn "seth44"
1527 [(set (match_operand:DI 0 "register_operand" "=r")
1528 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1530 "sethi\t%%h44(%a1), %0")
1532 (define_insn "setm44"
1533 [(set (match_operand:DI 0 "register_operand" "=r")
1534 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1535 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1537 "or\t%1, %%m44(%a2), %0")
1539 (define_insn "setl44"
1540 [(set (match_operand:DI 0 "register_operand" "=r")
1541 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1542 (match_operand:DI 2 "symbolic_operand" "")))]
1544 "or\t%1, %%l44(%a2), %0")
1546 (define_insn "sethh"
1547 [(set (match_operand:DI 0 "register_operand" "=r")
1548 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1550 "sethi\t%%hh(%a1), %0")
1552 (define_insn "setlm"
1553 [(set (match_operand:DI 0 "register_operand" "=r")
1554 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1556 "sethi\t%%lm(%a1), %0")
1558 (define_insn "sethm"
1559 [(set (match_operand:DI 0 "register_operand" "=r")
1560 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1561 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1563 "or\t%1, %%hm(%a2), %0")
1565 (define_insn "setlo"
1566 [(set (match_operand:DI 0 "register_operand" "=r")
1567 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1568 (match_operand:DI 2 "symbolic_operand" "")))]
1570 "or\t%1, %%lo(%a2), %0")
1572 (define_insn "embmedany_sethi"
1573 [(set (match_operand:DI 0 "register_operand" "=r")
1574 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1575 "TARGET_CM_EMBMEDANY && check_pic (1)"
1576 "sethi\t%%hi(%a1), %0")
1578 (define_insn "embmedany_losum"
1579 [(set (match_operand:DI 0 "register_operand" "=r")
1580 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1581 (match_operand:DI 2 "data_segment_operand" "")))]
1582 "TARGET_CM_EMBMEDANY"
1583 "add\t%1, %%lo(%a2), %0")
1585 (define_insn "embmedany_brsum"
1586 [(set (match_operand:DI 0 "register_operand" "=r")
1587 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1588 "TARGET_CM_EMBMEDANY"
1591 (define_insn "embmedany_textuhi"
1592 [(set (match_operand:DI 0 "register_operand" "=r")
1593 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1594 "TARGET_CM_EMBMEDANY && check_pic (1)"
1595 "sethi\t%%uhi(%a1), %0")
1597 (define_insn "embmedany_texthi"
1598 [(set (match_operand:DI 0 "register_operand" "=r")
1599 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1600 "TARGET_CM_EMBMEDANY && check_pic (1)"
1601 "sethi\t%%hi(%a1), %0")
1603 (define_insn "embmedany_textulo"
1604 [(set (match_operand:DI 0 "register_operand" "=r")
1605 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1606 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1607 "TARGET_CM_EMBMEDANY"
1608 "or\t%1, %%ulo(%a2), %0")
1610 (define_insn "embmedany_textlo"
1611 [(set (match_operand:DI 0 "register_operand" "=r")
1612 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1613 (match_operand:DI 2 "text_segment_operand" "")))]
1614 "TARGET_CM_EMBMEDANY"
1615 "or\t%1, %%lo(%a2), %0")
1617 ;; Now some patterns to help reload out a bit.
1618 (define_expand "reload_indi"
1619 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1620 (match_operand:DI 1 "immediate_operand" "")
1621 (match_operand:TI 2 "register_operand" "=&r")])]
1623 || TARGET_CM_EMBMEDANY)
1626 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1630 (define_expand "reload_outdi"
1631 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1632 (match_operand:DI 1 "immediate_operand" "")
1633 (match_operand:TI 2 "register_operand" "=&r")])]
1635 || TARGET_CM_EMBMEDANY)
1638 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1642 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1644 [(set (match_operand:DI 0 "register_operand" "")
1645 (match_operand:DI 1 "const_int_operand" ""))]
1646 "! TARGET_ARCH64 && reload_completed"
1647 [(clobber (const_int 0))]
1649 #if HOST_BITS_PER_WIDE_INT == 32
1650 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1651 (INTVAL (operands[1]) < 0) ?
1654 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1657 unsigned int low, high;
1659 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1660 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1661 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1663 /* Slick... but this trick loses if this subreg constant part
1664 can be done in one insn. */
1666 && ! SPARC_SETHI32_P (high)
1667 && ! SPARC_SIMM13_P (high))
1668 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1669 gen_highpart (SImode, operands[0])));
1671 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1677 [(set (match_operand:DI 0 "register_operand" "")
1678 (match_operand:DI 1 "const_double_operand" ""))]
1682 && ((GET_CODE (operands[0]) == REG
1683 && REGNO (operands[0]) < 32)
1684 || (GET_CODE (operands[0]) == SUBREG
1685 && GET_CODE (SUBREG_REG (operands[0])) == REG
1686 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1687 [(clobber (const_int 0))]
1689 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1690 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1692 /* Slick... but this trick loses if this subreg constant part
1693 can be done in one insn. */
1694 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1695 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1696 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1698 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1699 gen_highpart (SImode, operands[0])));
1703 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1704 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1710 [(set (match_operand:DI 0 "register_operand" "")
1711 (match_operand:DI 1 "register_operand" ""))]
1715 && ((GET_CODE (operands[0]) == REG
1716 && REGNO (operands[0]) < 32)
1717 || (GET_CODE (operands[0]) == SUBREG
1718 && GET_CODE (SUBREG_REG (operands[0])) == REG
1719 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1720 [(clobber (const_int 0))]
1722 rtx set_dest = operands[0];
1723 rtx set_src = operands[1];
1727 dest1 = gen_highpart (SImode, set_dest);
1728 dest2 = gen_lowpart (SImode, set_dest);
1729 src1 = gen_highpart (SImode, set_src);
1730 src2 = gen_lowpart (SImode, set_src);
1732 /* Now emit using the real source and destination we found, swapping
1733 the order if we detect overlap. */
1734 if (reg_overlap_mentioned_p (dest1, src2))
1736 emit_insn (gen_movsi (dest2, src2));
1737 emit_insn (gen_movsi (dest1, src1));
1741 emit_insn (gen_movsi (dest1, src1));
1742 emit_insn (gen_movsi (dest2, src2));
1747 ;; Now handle the cases of memory moves from/to non-even
1748 ;; DI mode register pairs.
1750 [(set (match_operand:DI 0 "register_operand" "")
1751 (match_operand:DI 1 "memory_operand" ""))]
1754 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1755 [(clobber (const_int 0))]
1757 rtx word0 = adjust_address (operands[1], SImode, 0);
1758 rtx word1 = adjust_address (operands[1], SImode, 4);
1759 rtx high_part = gen_highpart (SImode, operands[0]);
1760 rtx low_part = gen_lowpart (SImode, operands[0]);
1762 if (reg_overlap_mentioned_p (high_part, word1))
1764 emit_insn (gen_movsi (low_part, word1));
1765 emit_insn (gen_movsi (high_part, word0));
1769 emit_insn (gen_movsi (high_part, word0));
1770 emit_insn (gen_movsi (low_part, word1));
1776 [(set (match_operand:DI 0 "memory_operand" "")
1777 (match_operand:DI 1 "register_operand" ""))]
1780 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1781 [(clobber (const_int 0))]
1783 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1784 gen_highpart (SImode, operands[1])));
1785 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1786 gen_lowpart (SImode, operands[1])));
1791 [(set (match_operand:DI 0 "memory_operand" "")
1792 (match_operand:DI 1 "const_zero_operand" ""))]
1796 && ! mem_min_alignment (operands[0], 8)))
1797 && offsettable_memref_p (operands[0])"
1798 [(clobber (const_int 0))]
1800 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1801 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1806 ;; Floating point and vector move instructions
1808 ;; Yes, you guessed it right, the former movsf expander.
1809 (define_expand "mov<V32:mode>"
1810 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1811 (match_operand:V32 1 "general_operand" ""))]
1812 "<V32:MODE>mode == SFmode || TARGET_VIS"
1814 if (sparc_expand_move (<V32:MODE>mode, operands))
1818 (define_insn "*movsf_insn"
1819 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1820 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1822 && (register_operand (operands[0], <V32:MODE>mode)
1823 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1825 if (GET_CODE (operands[1]) == CONST_DOUBLE
1826 && (which_alternative == 2
1827 || which_alternative == 3
1828 || which_alternative == 4))
1833 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1834 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1835 operands[1] = GEN_INT (i);
1838 switch (which_alternative)
1841 return "fzeros\t%0";
1843 return "fmovs\t%1, %0";
1845 return "mov\t%1, %0";
1847 return "sethi\t%%hi(%a1), %0";
1852 return "ld\t%1, %0";
1855 return "st\t%r1, %0";
1860 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1862 ;; Exactly the same as above, except that all `f' cases are deleted.
1863 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1866 (define_insn "*movsf_insn_no_fpu"
1867 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1868 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1870 && (register_operand (operands[0], SFmode)
1871 || register_or_zero_operand (operands[1], SFmode))"
1873 if (GET_CODE (operands[1]) == CONST_DOUBLE
1874 && (which_alternative == 0
1875 || which_alternative == 1
1876 || which_alternative == 2))
1881 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1882 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1883 operands[1] = GEN_INT (i);
1886 switch (which_alternative)
1889 return "mov\t%1, %0";
1891 return "sethi\t%%hi(%a1), %0";
1895 return "ld\t%1, %0";
1897 return "st\t%r1, %0";
1902 [(set_attr "type" "*,*,*,load,store")])
1904 ;; The following 3 patterns build SFmode constants in integer registers.
1906 (define_insn "*movsf_lo_sum"
1907 [(set (match_operand:SF 0 "register_operand" "=r")
1908 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1909 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1915 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1916 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1917 operands[2] = GEN_INT (i);
1918 return "or\t%1, %%lo(%a2), %0";
1921 (define_insn "*movsf_high"
1922 [(set (match_operand:SF 0 "register_operand" "=r")
1923 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1929 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1930 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1931 operands[1] = GEN_INT (i);
1932 return "sethi\t%%hi(%1), %0";
1936 [(set (match_operand:SF 0 "register_operand" "")
1937 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1938 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1939 [(set (match_dup 0) (high:SF (match_dup 1)))
1940 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1942 ;; Yes, you again guessed it right, the former movdf expander.
1943 (define_expand "mov<V64:mode>"
1944 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1945 (match_operand:V64 1 "general_operand" ""))]
1946 "<V64:MODE>mode == DFmode || TARGET_VIS"
1948 if (sparc_expand_move (<V64:MODE>mode, operands))
1952 ;; Be careful, fmovd does not exist when !v9.
1953 (define_insn "*movdf_insn_sp32"
1954 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1955 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1958 && (register_operand (operands[0], DFmode)
1959 || register_or_zero_operand (operands[1], DFmode))"
1971 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1972 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1974 (define_insn "*movdf_insn_sp32_no_fpu"
1975 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1976 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1979 && (register_operand (operands[0], DFmode)
1980 || register_or_zero_operand (operands[1], DFmode))"
1987 [(set_attr "type" "load,store,*,*,*")
1988 (set_attr "length" "*,*,2,2,2")])
1990 ;; We have available v9 double floats but not 64-bit integer registers.
1991 (define_insn "*movdf_insn_sp32_v9"
1992 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1993 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1997 && (register_operand (operands[0], <V64:MODE>mode)
1998 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2010 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2011 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2012 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2014 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2015 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2016 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2020 && (register_operand (operands[0], DFmode)
2021 || register_or_zero_operand (operands[1], DFmode))"
2028 [(set_attr "type" "load,store,store,*,*")
2029 (set_attr "length" "*,*,*,2,2")])
2031 ;; We have available both v9 double floats and 64-bit integer registers.
2032 (define_insn "*movdf_insn_sp64"
2033 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2034 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2037 && (register_operand (operands[0], <V64:MODE>mode)
2038 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2048 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2049 (set_attr "length" "*,*,*,*,*,*,*,2")
2050 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2052 (define_insn "*movdf_insn_sp64_no_fpu"
2053 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2054 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2057 && (register_operand (operands[0], DFmode)
2058 || register_or_zero_operand (operands[1], DFmode))"
2063 [(set_attr "type" "*,load,store")])
2065 ;; This pattern builds V64mode constants in integer registers.
2067 [(set (match_operand:V64 0 "register_operand" "")
2068 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2070 && (GET_CODE (operands[0]) == REG
2071 && REGNO (operands[0]) < 32)
2072 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2073 && reload_completed"
2074 [(clobber (const_int 0))]
2076 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2080 #if HOST_BITS_PER_WIDE_INT == 32
2083 enum machine_mode mode = GET_MODE (operands[1]);
2084 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2085 emit_insn (gen_movdi (operands[0], tem));
2090 enum machine_mode mode = GET_MODE (operands[1]);
2091 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2092 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2094 gcc_assert (GET_CODE (hi) == CONST_INT);
2095 gcc_assert (GET_CODE (lo) == CONST_INT);
2097 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2099 /* Slick... but this trick loses if this subreg constant part
2100 can be done in one insn. */
2102 && ! SPARC_SETHI32_P (INTVAL (hi))
2103 && ! SPARC_SIMM13_P (INTVAL (hi)))
2105 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2106 gen_highpart (SImode, operands[0])));
2110 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2116 ;; Ok, now the splits to handle all the multi insn and
2117 ;; mis-aligned memory address cases.
2118 ;; In these splits please take note that we must be
2119 ;; careful when V9 but not ARCH64 because the integer
2120 ;; register DFmode cases must be handled.
2122 [(set (match_operand:V64 0 "register_operand" "")
2123 (match_operand:V64 1 "register_operand" ""))]
2126 && ((GET_CODE (operands[0]) == REG
2127 && REGNO (operands[0]) < 32)
2128 || (GET_CODE (operands[0]) == SUBREG
2129 && GET_CODE (SUBREG_REG (operands[0])) == REG
2130 && REGNO (SUBREG_REG (operands[0])) < 32))))
2131 && reload_completed"
2132 [(clobber (const_int 0))]
2134 rtx set_dest = operands[0];
2135 rtx set_src = operands[1];
2138 enum machine_mode half_mode;
2140 /* We can be expanded for DFmode or integral vector modes. */
2141 if (<V64:MODE>mode == DFmode)
2146 dest1 = gen_highpart (half_mode, set_dest);
2147 dest2 = gen_lowpart (half_mode, set_dest);
2148 src1 = gen_highpart (half_mode, set_src);
2149 src2 = gen_lowpart (half_mode, set_src);
2151 /* Now emit using the real source and destination we found, swapping
2152 the order if we detect overlap. */
2153 if (reg_overlap_mentioned_p (dest1, src2))
2155 emit_move_insn_1 (dest2, src2);
2156 emit_move_insn_1 (dest1, src1);
2160 emit_move_insn_1 (dest1, src1);
2161 emit_move_insn_1 (dest2, src2);
2167 [(set (match_operand:V64 0 "register_operand" "")
2168 (match_operand:V64 1 "memory_operand" ""))]
2171 && (((REGNO (operands[0]) % 2) != 0)
2172 || ! mem_min_alignment (operands[1], 8))
2173 && offsettable_memref_p (operands[1])"
2174 [(clobber (const_int 0))]
2176 enum machine_mode half_mode;
2179 /* We can be expanded for DFmode or integral vector modes. */
2180 if (<V64:MODE>mode == DFmode)
2185 word0 = adjust_address (operands[1], half_mode, 0);
2186 word1 = adjust_address (operands[1], half_mode, 4);
2188 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2190 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2191 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2195 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2196 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2202 [(set (match_operand:V64 0 "memory_operand" "")
2203 (match_operand:V64 1 "register_operand" ""))]
2206 && (((REGNO (operands[1]) % 2) != 0)
2207 || ! mem_min_alignment (operands[0], 8))
2208 && offsettable_memref_p (operands[0])"
2209 [(clobber (const_int 0))]
2211 enum machine_mode half_mode;
2214 /* We can be expanded for DFmode or integral vector modes. */
2215 if (<V64:MODE>mode == DFmode)
2220 word0 = adjust_address (operands[0], half_mode, 0);
2221 word1 = adjust_address (operands[0], half_mode, 4);
2223 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2224 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2229 [(set (match_operand:V64 0 "memory_operand" "")
2230 (match_operand:V64 1 "const_zero_operand" ""))]
2234 && ! mem_min_alignment (operands[0], 8)))
2235 && offsettable_memref_p (operands[0])"
2236 [(clobber (const_int 0))]
2238 enum machine_mode half_mode;
2241 /* We can be expanded for DFmode or integral vector modes. */
2242 if (<V64:MODE>mode == DFmode)
2247 dest1 = adjust_address (operands[0], half_mode, 0);
2248 dest2 = adjust_address (operands[0], half_mode, 4);
2250 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2251 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2256 [(set (match_operand:V64 0 "register_operand" "")
2257 (match_operand:V64 1 "const_zero_operand" ""))]
2260 && ((GET_CODE (operands[0]) == REG
2261 && REGNO (operands[0]) < 32)
2262 || (GET_CODE (operands[0]) == SUBREG
2263 && GET_CODE (SUBREG_REG (operands[0])) == REG
2264 && REGNO (SUBREG_REG (operands[0])) < 32))"
2265 [(clobber (const_int 0))]
2267 enum machine_mode half_mode;
2268 rtx set_dest = operands[0];
2271 /* We can be expanded for DFmode or integral vector modes. */
2272 if (<V64:MODE>mode == DFmode)
2277 dest1 = gen_highpart (half_mode, set_dest);
2278 dest2 = gen_lowpart (half_mode, set_dest);
2279 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2280 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2284 (define_expand "movtf"
2285 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2286 (match_operand:TF 1 "general_operand" ""))]
2289 if (sparc_expand_move (TFmode, operands))
2293 (define_insn "*movtf_insn_sp32"
2294 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2295 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2298 && (register_operand (operands[0], TFmode)
2299 || register_or_zero_operand (operands[1], TFmode))"
2301 [(set_attr "length" "4")])
2303 ;; Exactly the same as above, except that all `e' cases are deleted.
2304 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2307 (define_insn "*movtf_insn_sp32_no_fpu"
2308 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2309 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2312 && (register_operand (operands[0], TFmode)
2313 || register_or_zero_operand (operands[1], TFmode))"
2315 [(set_attr "length" "4")])
2317 (define_insn "*movtf_insn_sp64"
2318 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2319 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2322 && ! TARGET_HARD_QUAD
2323 && (register_operand (operands[0], TFmode)
2324 || register_or_zero_operand (operands[1], TFmode))"
2326 [(set_attr "length" "2")])
2328 (define_insn "*movtf_insn_sp64_hq"
2329 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2330 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2334 && (register_operand (operands[0], TFmode)
2335 || register_or_zero_operand (operands[1], TFmode))"
2343 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2344 (set_attr "length" "2,*,*,*,2,2")])
2346 (define_insn "*movtf_insn_sp64_no_fpu"
2347 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2348 (match_operand:TF 1 "input_operand" "orG,rG"))]
2351 && (register_operand (operands[0], TFmode)
2352 || register_or_zero_operand (operands[1], TFmode))"
2354 [(set_attr "length" "2")])
2356 ;; Now all the splits to handle multi-insn TF mode moves.
2358 [(set (match_operand:TF 0 "register_operand" "")
2359 (match_operand:TF 1 "register_operand" ""))]
2363 && ! TARGET_HARD_QUAD)
2364 || ! fp_register_operand (operands[0], TFmode))"
2365 [(clobber (const_int 0))]
2367 rtx set_dest = operands[0];
2368 rtx set_src = operands[1];
2372 dest1 = gen_df_reg (set_dest, 0);
2373 dest2 = gen_df_reg (set_dest, 1);
2374 src1 = gen_df_reg (set_src, 0);
2375 src2 = gen_df_reg (set_src, 1);
2377 /* Now emit using the real source and destination we found, swapping
2378 the order if we detect overlap. */
2379 if (reg_overlap_mentioned_p (dest1, src2))
2381 emit_insn (gen_movdf (dest2, src2));
2382 emit_insn (gen_movdf (dest1, src1));
2386 emit_insn (gen_movdf (dest1, src1));
2387 emit_insn (gen_movdf (dest2, src2));
2393 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2394 (match_operand:TF 1 "const_zero_operand" ""))]
2396 [(clobber (const_int 0))]
2398 rtx set_dest = operands[0];
2401 switch (GET_CODE (set_dest))
2404 dest1 = gen_df_reg (set_dest, 0);
2405 dest2 = gen_df_reg (set_dest, 1);
2408 dest1 = adjust_address (set_dest, DFmode, 0);
2409 dest2 = adjust_address (set_dest, DFmode, 8);
2415 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2416 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2421 [(set (match_operand:TF 0 "register_operand" "")
2422 (match_operand:TF 1 "memory_operand" ""))]
2424 && offsettable_memref_p (operands[1])
2426 || ! TARGET_HARD_QUAD
2427 || ! fp_register_operand (operands[0], TFmode)))"
2428 [(clobber (const_int 0))]
2430 rtx word0 = adjust_address (operands[1], DFmode, 0);
2431 rtx word1 = adjust_address (operands[1], DFmode, 8);
2432 rtx set_dest, dest1, dest2;
2434 set_dest = operands[0];
2436 dest1 = gen_df_reg (set_dest, 0);
2437 dest2 = gen_df_reg (set_dest, 1);
2439 /* Now output, ordering such that we don't clobber any registers
2440 mentioned in the address. */
2441 if (reg_overlap_mentioned_p (dest1, word1))
2444 emit_insn (gen_movdf (dest2, word1));
2445 emit_insn (gen_movdf (dest1, word0));
2449 emit_insn (gen_movdf (dest1, word0));
2450 emit_insn (gen_movdf (dest2, word1));
2456 [(set (match_operand:TF 0 "memory_operand" "")
2457 (match_operand:TF 1 "register_operand" ""))]
2459 && offsettable_memref_p (operands[0])
2461 || ! TARGET_HARD_QUAD
2462 || ! fp_register_operand (operands[1], TFmode)))"
2463 [(clobber (const_int 0))]
2465 rtx set_src = operands[1];
2467 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2468 gen_df_reg (set_src, 0)));
2469 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2470 gen_df_reg (set_src, 1)));
2475 ;; SPARC-V9 conditional move instructions
2477 ;; We can handle larger constants here for some flavors, but for now we keep
2478 ;; it simple and only allow those constants supported by all flavors.
2479 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2480 ;; 3 contains the constant if one is present, but we handle either for
2481 ;; generality (sparc.c puts a constant in operand 2).
2483 (define_expand "mov<I:mode>cc"
2484 [(set (match_operand:I 0 "register_operand" "")
2485 (if_then_else:I (match_operand 1 "comparison_operator" "")
2486 (match_operand:I 2 "arith10_operand" "")
2487 (match_operand:I 3 "arith10_operand" "")))]
2488 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2490 enum rtx_code code = GET_CODE (operands[1]);
2493 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2497 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2499 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2500 GET_CODE (operands[1]));
2502 if (XEXP (operands[1], 1) == const0_rtx
2503 && GET_CODE (XEXP (operands[1], 0)) == REG
2504 && GET_MODE (XEXP (operands[1], 0)) == DImode
2505 && v9_regcmp_p (code))
2506 cc_reg = XEXP (operands[1], 0);
2508 cc_reg = gen_compare_reg (operands[1]);
2510 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2513 (define_expand "mov<F:mode>cc"
2514 [(set (match_operand:F 0 "register_operand" "")
2515 (if_then_else:F (match_operand 1 "comparison_operator" "")
2516 (match_operand:F 2 "register_operand" "")
2517 (match_operand:F 3 "register_operand" "")))]
2518 "TARGET_V9 && TARGET_FPU"
2520 enum rtx_code code = GET_CODE (operands[1]);
2523 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2527 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2529 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2530 GET_CODE (operands[1]));
2532 if (XEXP (operands[1], 1) == const0_rtx
2533 && GET_CODE (XEXP (operands[1], 0)) == REG
2534 && GET_MODE (XEXP (operands[1], 0)) == DImode
2535 && v9_regcmp_p (code))
2536 cc_reg = XEXP (operands[1], 0);
2538 cc_reg = gen_compare_reg (operands[1]);
2540 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2543 ;; Conditional move define_insns
2545 (define_insn "*mov<I:mode>_cc_v9"
2546 [(set (match_operand:I 0 "register_operand" "=r,r")
2547 (if_then_else:I (match_operator 1 "comparison_operator"
2548 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2550 (match_operand:I 3 "arith11_operand" "rL,0")
2551 (match_operand:I 4 "arith11_operand" "0,rL")))]
2552 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2555 mov%c1\t%x2, %4, %0"
2556 [(set_attr "type" "cmove")])
2558 (define_insn "*mov<I:mode>_cc_reg_sp64"
2559 [(set (match_operand:I 0 "register_operand" "=r,r")
2560 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2561 [(match_operand:DI 2 "register_operand" "r,r")
2563 (match_operand:I 3 "arith10_operand" "rM,0")
2564 (match_operand:I 4 "arith10_operand" "0,rM")))]
2567 movr%D1\t%2, %r3, %0
2568 movr%d1\t%2, %r4, %0"
2569 [(set_attr "type" "cmove")])
2571 (define_insn "*movsf_cc_v9"
2572 [(set (match_operand:SF 0 "register_operand" "=f,f")
2573 (if_then_else:SF (match_operator 1 "comparison_operator"
2574 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2576 (match_operand:SF 3 "register_operand" "f,0")
2577 (match_operand:SF 4 "register_operand" "0,f")))]
2578 "TARGET_V9 && TARGET_FPU"
2580 fmovs%C1\t%x2, %3, %0
2581 fmovs%c1\t%x2, %4, %0"
2582 [(set_attr "type" "fpcmove")])
2584 (define_insn "*movsf_cc_reg_sp64"
2585 [(set (match_operand:SF 0 "register_operand" "=f,f")
2586 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2587 [(match_operand:DI 2 "register_operand" "r,r")
2589 (match_operand:SF 3 "register_operand" "f,0")
2590 (match_operand:SF 4 "register_operand" "0,f")))]
2591 "TARGET_ARCH64 && TARGET_FPU"
2593 fmovrs%D1\t%2, %3, %0
2594 fmovrs%d1\t%2, %4, %0"
2595 [(set_attr "type" "fpcrmove")])
2597 ;; Named because invoked by movtf_cc_v9
2598 (define_insn "movdf_cc_v9"
2599 [(set (match_operand:DF 0 "register_operand" "=e,e")
2600 (if_then_else:DF (match_operator 1 "comparison_operator"
2601 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2603 (match_operand:DF 3 "register_operand" "e,0")
2604 (match_operand:DF 4 "register_operand" "0,e")))]
2605 "TARGET_V9 && TARGET_FPU"
2607 fmovd%C1\t%x2, %3, %0
2608 fmovd%c1\t%x2, %4, %0"
2609 [(set_attr "type" "fpcmove")
2610 (set_attr "fptype" "double")])
2612 ;; Named because invoked by movtf_cc_reg_sp64
2613 (define_insn "movdf_cc_reg_sp64"
2614 [(set (match_operand:DF 0 "register_operand" "=e,e")
2615 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2616 [(match_operand:DI 2 "register_operand" "r,r")
2618 (match_operand:DF 3 "register_operand" "e,0")
2619 (match_operand:DF 4 "register_operand" "0,e")))]
2620 "TARGET_ARCH64 && TARGET_FPU"
2622 fmovrd%D1\t%2, %3, %0
2623 fmovrd%d1\t%2, %4, %0"
2624 [(set_attr "type" "fpcrmove")
2625 (set_attr "fptype" "double")])
2627 (define_insn "*movtf_cc_hq_v9"
2628 [(set (match_operand:TF 0 "register_operand" "=e,e")
2629 (if_then_else:TF (match_operator 1 "comparison_operator"
2630 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2632 (match_operand:TF 3 "register_operand" "e,0")
2633 (match_operand:TF 4 "register_operand" "0,e")))]
2634 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2636 fmovq%C1\t%x2, %3, %0
2637 fmovq%c1\t%x2, %4, %0"
2638 [(set_attr "type" "fpcmove")])
2640 (define_insn "*movtf_cc_reg_hq_sp64"
2641 [(set (match_operand:TF 0 "register_operand" "=e,e")
2642 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2643 [(match_operand:DI 2 "register_operand" "r,r")
2645 (match_operand:TF 3 "register_operand" "e,0")
2646 (match_operand:TF 4 "register_operand" "0,e")))]
2647 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2649 fmovrq%D1\t%2, %3, %0
2650 fmovrq%d1\t%2, %4, %0"
2651 [(set_attr "type" "fpcrmove")])
2653 (define_insn_and_split "*movtf_cc_v9"
2654 [(set (match_operand:TF 0 "register_operand" "=e,e")
2655 (if_then_else:TF (match_operator 1 "comparison_operator"
2656 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2658 (match_operand:TF 3 "register_operand" "e,0")
2659 (match_operand:TF 4 "register_operand" "0,e")))]
2660 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2662 "&& reload_completed"
2663 [(clobber (const_int 0))]
2665 rtx set_dest = operands[0];
2666 rtx set_srca = operands[3];
2667 rtx set_srcb = operands[4];
2668 int third = rtx_equal_p (set_dest, set_srca);
2670 rtx srca1, srca2, srcb1, srcb2;
2672 dest1 = gen_df_reg (set_dest, 0);
2673 dest2 = gen_df_reg (set_dest, 1);
2674 srca1 = gen_df_reg (set_srca, 0);
2675 srca2 = gen_df_reg (set_srca, 1);
2676 srcb1 = gen_df_reg (set_srcb, 0);
2677 srcb2 = gen_df_reg (set_srcb, 1);
2679 /* Now emit using the real source and destination we found, swapping
2680 the order if we detect overlap. */
2681 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2682 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2684 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2685 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2689 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2690 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2694 [(set_attr "length" "2")])
2696 (define_insn_and_split "*movtf_cc_reg_sp64"
2697 [(set (match_operand:TF 0 "register_operand" "=e,e")
2698 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2699 [(match_operand:DI 2 "register_operand" "r,r")
2701 (match_operand:TF 3 "register_operand" "e,0")
2702 (match_operand:TF 4 "register_operand" "0,e")))]
2703 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2705 "&& reload_completed"
2706 [(clobber (const_int 0))]
2708 rtx set_dest = operands[0];
2709 rtx set_srca = operands[3];
2710 rtx set_srcb = operands[4];
2711 int third = rtx_equal_p (set_dest, set_srca);
2713 rtx srca1, srca2, srcb1, srcb2;
2715 dest1 = gen_df_reg (set_dest, 0);
2716 dest2 = gen_df_reg (set_dest, 1);
2717 srca1 = gen_df_reg (set_srca, 0);
2718 srca2 = gen_df_reg (set_srca, 1);
2719 srcb1 = gen_df_reg (set_srcb, 0);
2720 srcb2 = gen_df_reg (set_srcb, 1);
2722 /* Now emit using the real source and destination we found, swapping
2723 the order if we detect overlap. */
2724 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2725 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2727 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2728 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2732 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2733 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2737 [(set_attr "length" "2")])
2740 ;; Zero-extension instructions
2742 ;; These patterns originally accepted general_operands, however, slightly
2743 ;; better code is generated by only accepting register_operands, and then
2744 ;; letting combine generate the ldu[hb] insns.
2746 (define_expand "zero_extendhisi2"
2747 [(set (match_operand:SI 0 "register_operand" "")
2748 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2751 rtx temp = gen_reg_rtx (SImode);
2752 rtx shift_16 = GEN_INT (16);
2753 int op1_subbyte = 0;
2755 if (GET_CODE (operand1) == SUBREG)
2757 op1_subbyte = SUBREG_BYTE (operand1);
2758 op1_subbyte /= GET_MODE_SIZE (SImode);
2759 op1_subbyte *= GET_MODE_SIZE (SImode);
2760 operand1 = XEXP (operand1, 0);
2763 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2765 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2769 (define_insn "*zero_extendhisi2_insn"
2770 [(set (match_operand:SI 0 "register_operand" "=r")
2771 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2774 [(set_attr "type" "load")
2775 (set_attr "us3load_type" "3cycle")])
2777 (define_expand "zero_extendqihi2"
2778 [(set (match_operand:HI 0 "register_operand" "")
2779 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2783 (define_insn "*zero_extendqihi2_insn"
2784 [(set (match_operand:HI 0 "register_operand" "=r,r")
2785 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2786 "GET_CODE (operands[1]) != CONST_INT"
2790 [(set_attr "type" "*,load")
2791 (set_attr "us3load_type" "*,3cycle")])
2793 (define_expand "zero_extendqisi2"
2794 [(set (match_operand:SI 0 "register_operand" "")
2795 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2799 (define_insn "*zero_extendqisi2_insn"
2800 [(set (match_operand:SI 0 "register_operand" "=r,r")
2801 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2802 "GET_CODE (operands[1]) != CONST_INT"
2806 [(set_attr "type" "*,load")
2807 (set_attr "us3load_type" "*,3cycle")])
2809 (define_expand "zero_extendqidi2"
2810 [(set (match_operand:DI 0 "register_operand" "")
2811 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2815 (define_insn "*zero_extendqidi2_insn"
2816 [(set (match_operand:DI 0 "register_operand" "=r,r")
2817 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2818 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2822 [(set_attr "type" "*,load")
2823 (set_attr "us3load_type" "*,3cycle")])
2825 (define_expand "zero_extendhidi2"
2826 [(set (match_operand:DI 0 "register_operand" "")
2827 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2830 rtx temp = gen_reg_rtx (DImode);
2831 rtx shift_48 = GEN_INT (48);
2832 int op1_subbyte = 0;
2834 if (GET_CODE (operand1) == SUBREG)
2836 op1_subbyte = SUBREG_BYTE (operand1);
2837 op1_subbyte /= GET_MODE_SIZE (DImode);
2838 op1_subbyte *= GET_MODE_SIZE (DImode);
2839 operand1 = XEXP (operand1, 0);
2842 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2844 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2848 (define_insn "*zero_extendhidi2_insn"
2849 [(set (match_operand:DI 0 "register_operand" "=r")
2850 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2853 [(set_attr "type" "load")
2854 (set_attr "us3load_type" "3cycle")])
2856 ;; ??? Write truncdisi pattern using sra?
2858 (define_expand "zero_extendsidi2"
2859 [(set (match_operand:DI 0 "register_operand" "")
2860 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2864 (define_insn "*zero_extendsidi2_insn_sp64"
2865 [(set (match_operand:DI 0 "register_operand" "=r,r")
2866 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2867 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2871 [(set_attr "type" "shift,load")])
2873 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2874 [(set (match_operand:DI 0 "register_operand" "=r")
2875 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2878 "&& reload_completed"
2879 [(set (match_dup 2) (match_dup 3))
2880 (set (match_dup 4) (match_dup 5))]
2884 dest1 = gen_highpart (SImode, operands[0]);
2885 dest2 = gen_lowpart (SImode, operands[0]);
2887 /* Swap the order in case of overlap. */
2888 if (REGNO (dest1) == REGNO (operands[1]))
2890 operands[2] = dest2;
2891 operands[3] = operands[1];
2892 operands[4] = dest1;
2893 operands[5] = const0_rtx;
2897 operands[2] = dest1;
2898 operands[3] = const0_rtx;
2899 operands[4] = dest2;
2900 operands[5] = operands[1];
2903 [(set_attr "length" "2")])
2905 ;; Simplify comparisons of extended values.
2907 (define_insn "*cmp_zero_extendqisi2"
2909 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2912 "andcc\t%0, 0xff, %%g0"
2913 [(set_attr "type" "compare")])
2915 (define_insn "*cmp_zero_qi"
2917 (compare:CC (match_operand:QI 0 "register_operand" "r")
2920 "andcc\t%0, 0xff, %%g0"
2921 [(set_attr "type" "compare")])
2923 (define_insn "*cmp_zero_extendqisi2_set"
2925 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2927 (set (match_operand:SI 0 "register_operand" "=r")
2928 (zero_extend:SI (match_dup 1)))]
2930 "andcc\t%1, 0xff, %0"
2931 [(set_attr "type" "compare")])
2933 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2935 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2938 (set (match_operand:SI 0 "register_operand" "=r")
2939 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2941 "andcc\t%1, 0xff, %0"
2942 [(set_attr "type" "compare")])
2944 (define_insn "*cmp_zero_extendqidi2"
2946 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2949 "andcc\t%0, 0xff, %%g0"
2950 [(set_attr "type" "compare")])
2952 (define_insn "*cmp_zero_qi_sp64"
2954 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2957 "andcc\t%0, 0xff, %%g0"
2958 [(set_attr "type" "compare")])
2960 (define_insn "*cmp_zero_extendqidi2_set"
2962 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2964 (set (match_operand:DI 0 "register_operand" "=r")
2965 (zero_extend:DI (match_dup 1)))]
2967 "andcc\t%1, 0xff, %0"
2968 [(set_attr "type" "compare")])
2970 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2972 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2975 (set (match_operand:DI 0 "register_operand" "=r")
2976 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2978 "andcc\t%1, 0xff, %0"
2979 [(set_attr "type" "compare")])
2981 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2983 (define_insn "*cmp_siqi_trunc"
2985 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2988 "andcc\t%0, 0xff, %%g0"
2989 [(set_attr "type" "compare")])
2991 (define_insn "*cmp_siqi_trunc_set"
2993 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2995 (set (match_operand:QI 0 "register_operand" "=r")
2996 (subreg:QI (match_dup 1) 3))]
2998 "andcc\t%1, 0xff, %0"
2999 [(set_attr "type" "compare")])
3001 (define_insn "*cmp_diqi_trunc"
3003 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3006 "andcc\t%0, 0xff, %%g0"
3007 [(set_attr "type" "compare")])
3009 (define_insn "*cmp_diqi_trunc_set"
3011 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3013 (set (match_operand:QI 0 "register_operand" "=r")
3014 (subreg:QI (match_dup 1) 7))]
3016 "andcc\t%1, 0xff, %0"
3017 [(set_attr "type" "compare")])
3020 ;; Sign-extension instructions
3022 ;; These patterns originally accepted general_operands, however, slightly
3023 ;; better code is generated by only accepting register_operands, and then
3024 ;; letting combine generate the lds[hb] insns.
3026 (define_expand "extendhisi2"
3027 [(set (match_operand:SI 0 "register_operand" "")
3028 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3031 rtx temp = gen_reg_rtx (SImode);
3032 rtx shift_16 = GEN_INT (16);
3033 int op1_subbyte = 0;
3035 if (GET_CODE (operand1) == SUBREG)
3037 op1_subbyte = SUBREG_BYTE (operand1);
3038 op1_subbyte /= GET_MODE_SIZE (SImode);
3039 op1_subbyte *= GET_MODE_SIZE (SImode);
3040 operand1 = XEXP (operand1, 0);
3043 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3045 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3049 (define_insn "*sign_extendhisi2_insn"
3050 [(set (match_operand:SI 0 "register_operand" "=r")
3051 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3054 [(set_attr "type" "sload")
3055 (set_attr "us3load_type" "3cycle")])
3057 (define_expand "extendqihi2"
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3062 rtx temp = gen_reg_rtx (SImode);
3063 rtx shift_24 = GEN_INT (24);
3064 int op1_subbyte = 0;
3065 int op0_subbyte = 0;
3067 if (GET_CODE (operand1) == SUBREG)
3069 op1_subbyte = SUBREG_BYTE (operand1);
3070 op1_subbyte /= GET_MODE_SIZE (SImode);
3071 op1_subbyte *= GET_MODE_SIZE (SImode);
3072 operand1 = XEXP (operand1, 0);
3074 if (GET_CODE (operand0) == SUBREG)
3076 op0_subbyte = SUBREG_BYTE (operand0);
3077 op0_subbyte /= GET_MODE_SIZE (SImode);
3078 op0_subbyte *= GET_MODE_SIZE (SImode);
3079 operand0 = XEXP (operand0, 0);
3081 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3083 if (GET_MODE (operand0) != SImode)
3084 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3085 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3089 (define_insn "*sign_extendqihi2_insn"
3090 [(set (match_operand:HI 0 "register_operand" "=r")
3091 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3094 [(set_attr "type" "sload")
3095 (set_attr "us3load_type" "3cycle")])
3097 (define_expand "extendqisi2"
3098 [(set (match_operand:SI 0 "register_operand" "")
3099 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3102 rtx temp = gen_reg_rtx (SImode);
3103 rtx shift_24 = GEN_INT (24);
3104 int op1_subbyte = 0;
3106 if (GET_CODE (operand1) == SUBREG)
3108 op1_subbyte = SUBREG_BYTE (operand1);
3109 op1_subbyte /= GET_MODE_SIZE (SImode);
3110 op1_subbyte *= GET_MODE_SIZE (SImode);
3111 operand1 = XEXP (operand1, 0);
3114 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3116 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3120 (define_insn "*sign_extendqisi2_insn"
3121 [(set (match_operand:SI 0 "register_operand" "=r")
3122 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3125 [(set_attr "type" "sload")
3126 (set_attr "us3load_type" "3cycle")])
3128 (define_expand "extendqidi2"
3129 [(set (match_operand:DI 0 "register_operand" "")
3130 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3133 rtx temp = gen_reg_rtx (DImode);
3134 rtx shift_56 = GEN_INT (56);
3135 int op1_subbyte = 0;
3137 if (GET_CODE (operand1) == SUBREG)
3139 op1_subbyte = SUBREG_BYTE (operand1);
3140 op1_subbyte /= GET_MODE_SIZE (DImode);
3141 op1_subbyte *= GET_MODE_SIZE (DImode);
3142 operand1 = XEXP (operand1, 0);
3145 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3147 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3151 (define_insn "*sign_extendqidi2_insn"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3156 [(set_attr "type" "sload")
3157 (set_attr "us3load_type" "3cycle")])
3159 (define_expand "extendhidi2"
3160 [(set (match_operand:DI 0 "register_operand" "")
3161 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3164 rtx temp = gen_reg_rtx (DImode);
3165 rtx shift_48 = GEN_INT (48);
3166 int op1_subbyte = 0;
3168 if (GET_CODE (operand1) == SUBREG)
3170 op1_subbyte = SUBREG_BYTE (operand1);
3171 op1_subbyte /= GET_MODE_SIZE (DImode);
3172 op1_subbyte *= GET_MODE_SIZE (DImode);
3173 operand1 = XEXP (operand1, 0);
3176 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3178 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3182 (define_insn "*sign_extendhidi2_insn"
3183 [(set (match_operand:DI 0 "register_operand" "=r")
3184 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3187 [(set_attr "type" "sload")
3188 (set_attr "us3load_type" "3cycle")])
3190 (define_expand "extendsidi2"
3191 [(set (match_operand:DI 0 "register_operand" "")
3192 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3196 (define_insn "*sign_extendsidi2_insn"
3197 [(set (match_operand:DI 0 "register_operand" "=r,r")
3198 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3203 [(set_attr "type" "shift,sload")
3204 (set_attr "us3load_type" "*,3cycle")])
3207 ;; Special pattern for optimizing bit-field compares. This is needed
3208 ;; because combine uses this as a canonical form.
3210 (define_insn "*cmp_zero_extract"
3213 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3214 (match_operand:SI 1 "small_int_operand" "I")
3215 (match_operand:SI 2 "small_int_operand" "I"))
3217 "INTVAL (operands[2]) > 19"
3219 int len = INTVAL (operands[1]);
3220 int pos = 32 - INTVAL (operands[2]) - len;
3221 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3222 operands[1] = GEN_INT (mask);
3223 return "andcc\t%0, %1, %%g0";
3225 [(set_attr "type" "compare")])
3227 (define_insn "*cmp_zero_extract_sp64"
3230 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3231 (match_operand:SI 1 "small_int_operand" "I")
3232 (match_operand:SI 2 "small_int_operand" "I"))
3234 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3236 int len = INTVAL (operands[1]);
3237 int pos = 64 - INTVAL (operands[2]) - len;
3238 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3239 operands[1] = GEN_INT (mask);
3240 return "andcc\t%0, %1, %%g0";
3242 [(set_attr "type" "compare")])
3245 ;; Conversions between float, double and long double.
3247 (define_insn "extendsfdf2"
3248 [(set (match_operand:DF 0 "register_operand" "=e")
3250 (match_operand:SF 1 "register_operand" "f")))]
3253 [(set_attr "type" "fp")
3254 (set_attr "fptype" "double")])
3256 (define_expand "extendsftf2"
3257 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3259 (match_operand:SF 1 "register_operand" "")))]
3260 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3261 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3263 (define_insn "*extendsftf2_hq"
3264 [(set (match_operand:TF 0 "register_operand" "=e")
3266 (match_operand:SF 1 "register_operand" "f")))]
3267 "TARGET_FPU && TARGET_HARD_QUAD"
3269 [(set_attr "type" "fp")])
3271 (define_expand "extenddftf2"
3272 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3274 (match_operand:DF 1 "register_operand" "")))]
3275 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3276 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3278 (define_insn "*extenddftf2_hq"
3279 [(set (match_operand:TF 0 "register_operand" "=e")
3281 (match_operand:DF 1 "register_operand" "e")))]
3282 "TARGET_FPU && TARGET_HARD_QUAD"
3284 [(set_attr "type" "fp")])
3286 (define_insn "truncdfsf2"
3287 [(set (match_operand:SF 0 "register_operand" "=f")
3289 (match_operand:DF 1 "register_operand" "e")))]
3292 [(set_attr "type" "fp")
3293 (set_attr "fptype" "double")])
3295 (define_expand "trunctfsf2"
3296 [(set (match_operand:SF 0 "register_operand" "")
3298 (match_operand:TF 1 "general_operand" "")))]
3299 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3300 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3302 (define_insn "*trunctfsf2_hq"
3303 [(set (match_operand:SF 0 "register_operand" "=f")
3305 (match_operand:TF 1 "register_operand" "e")))]
3306 "TARGET_FPU && TARGET_HARD_QUAD"
3308 [(set_attr "type" "fp")])
3310 (define_expand "trunctfdf2"
3311 [(set (match_operand:DF 0 "register_operand" "")
3313 (match_operand:TF 1 "general_operand" "")))]
3314 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3315 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3317 (define_insn "*trunctfdf2_hq"
3318 [(set (match_operand:DF 0 "register_operand" "=e")
3320 (match_operand:TF 1 "register_operand" "e")))]
3321 "TARGET_FPU && TARGET_HARD_QUAD"
3323 [(set_attr "type" "fp")])
3326 ;; Conversion between fixed point and floating point.
3328 (define_insn "floatsisf2"
3329 [(set (match_operand:SF 0 "register_operand" "=f")
3330 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3333 [(set_attr "type" "fp")
3334 (set_attr "fptype" "double")])
3336 (define_insn "floatsidf2"
3337 [(set (match_operand:DF 0 "register_operand" "=e")
3338 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3341 [(set_attr "type" "fp")
3342 (set_attr "fptype" "double")])
3344 (define_expand "floatsitf2"
3345 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3346 (float:TF (match_operand:SI 1 "register_operand" "")))]
3347 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3348 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3350 (define_insn "*floatsitf2_hq"
3351 [(set (match_operand:TF 0 "register_operand" "=e")
3352 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3353 "TARGET_FPU && TARGET_HARD_QUAD"
3355 [(set_attr "type" "fp")])
3357 (define_expand "floatunssitf2"
3358 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3359 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3360 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3361 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3363 ;; Now the same for 64 bit sources.
3365 (define_insn "floatdisf2"
3366 [(set (match_operand:SF 0 "register_operand" "=f")
3367 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3368 "TARGET_V9 && TARGET_FPU"
3370 [(set_attr "type" "fp")
3371 (set_attr "fptype" "double")])
3373 (define_expand "floatunsdisf2"
3374 [(use (match_operand:SF 0 "register_operand" ""))
3375 (use (match_operand:DI 1 "general_operand" ""))]
3376 "TARGET_ARCH64 && TARGET_FPU"
3377 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3379 (define_insn "floatdidf2"
3380 [(set (match_operand:DF 0 "register_operand" "=e")
3381 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3382 "TARGET_V9 && TARGET_FPU"
3384 [(set_attr "type" "fp")
3385 (set_attr "fptype" "double")])
3387 (define_expand "floatunsdidf2"
3388 [(use (match_operand:DF 0 "register_operand" ""))
3389 (use (match_operand:DI 1 "general_operand" ""))]
3390 "TARGET_ARCH64 && TARGET_FPU"
3391 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3393 (define_expand "floatditf2"
3394 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3395 (float:TF (match_operand:DI 1 "register_operand" "")))]
3396 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3397 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3399 (define_insn "*floatditf2_hq"
3400 [(set (match_operand:TF 0 "register_operand" "=e")
3401 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3402 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3404 [(set_attr "type" "fp")])
3406 (define_expand "floatunsditf2"
3407 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3408 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3409 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3410 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3412 ;; Convert a float to an actual integer.
3413 ;; Truncation is performed as part of the conversion.
3415 (define_insn "fix_truncsfsi2"
3416 [(set (match_operand:SI 0 "register_operand" "=f")
3417 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3420 [(set_attr "type" "fp")
3421 (set_attr "fptype" "double")])
3423 (define_insn "fix_truncdfsi2"
3424 [(set (match_operand:SI 0 "register_operand" "=f")
3425 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3428 [(set_attr "type" "fp")
3429 (set_attr "fptype" "double")])
3431 (define_expand "fix_trunctfsi2"
3432 [(set (match_operand:SI 0 "register_operand" "")
3433 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3434 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3435 "emit_tfmode_cvt (FIX, operands); DONE;")
3437 (define_insn "*fix_trunctfsi2_hq"
3438 [(set (match_operand:SI 0 "register_operand" "=f")
3439 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3440 "TARGET_FPU && TARGET_HARD_QUAD"
3442 [(set_attr "type" "fp")])
3444 (define_expand "fixuns_trunctfsi2"
3445 [(set (match_operand:SI 0 "register_operand" "")
3446 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3447 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3448 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3450 ;; Now the same, for V9 targets
3452 (define_insn "fix_truncsfdi2"
3453 [(set (match_operand:DI 0 "register_operand" "=e")
3454 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3455 "TARGET_V9 && TARGET_FPU"
3457 [(set_attr "type" "fp")
3458 (set_attr "fptype" "double")])
3460 (define_expand "fixuns_truncsfdi2"
3461 [(use (match_operand:DI 0 "register_operand" ""))
3462 (use (match_operand:SF 1 "general_operand" ""))]
3463 "TARGET_ARCH64 && TARGET_FPU"
3464 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3466 (define_insn "fix_truncdfdi2"
3467 [(set (match_operand:DI 0 "register_operand" "=e")
3468 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3469 "TARGET_V9 && TARGET_FPU"
3471 [(set_attr "type" "fp")
3472 (set_attr "fptype" "double")])
3474 (define_expand "fixuns_truncdfdi2"
3475 [(use (match_operand:DI 0 "register_operand" ""))
3476 (use (match_operand:DF 1 "general_operand" ""))]
3477 "TARGET_ARCH64 && TARGET_FPU"
3478 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3480 (define_expand "fix_trunctfdi2"
3481 [(set (match_operand:DI 0 "register_operand" "")
3482 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3483 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3484 "emit_tfmode_cvt (FIX, operands); DONE;")
3486 (define_insn "*fix_trunctfdi2_hq"
3487 [(set (match_operand:DI 0 "register_operand" "=e")
3488 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3489 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3491 [(set_attr "type" "fp")])
3493 (define_expand "fixuns_trunctfdi2"
3494 [(set (match_operand:DI 0 "register_operand" "")
3495 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3496 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3497 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3500 ;; Integer addition/subtraction instructions.
3502 (define_expand "adddi3"
3503 [(set (match_operand:DI 0 "register_operand" "")
3504 (plus:DI (match_operand:DI 1 "register_operand" "")
3505 (match_operand:DI 2 "arith_double_add_operand" "")))]
3508 if (! TARGET_ARCH64)
3510 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3511 gen_rtx_SET (VOIDmode, operands[0],
3512 gen_rtx_PLUS (DImode, operands[1],
3514 gen_rtx_CLOBBER (VOIDmode,
3515 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3520 (define_insn_and_split "*adddi3_insn_sp32"
3521 [(set (match_operand:DI 0 "register_operand" "=r")
3522 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3523 (match_operand:DI 2 "arith_double_operand" "rHI")))
3524 (clobber (reg:CC 100))]
3527 "&& reload_completed"
3528 [(parallel [(set (reg:CC_NOOV 100)
3529 (compare:CC_NOOV (plus:SI (match_dup 4)
3533 (plus:SI (match_dup 4) (match_dup 5)))])
3535 (plus:SI (plus:SI (match_dup 7)
3537 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3539 operands[3] = gen_lowpart (SImode, operands[0]);
3540 operands[4] = gen_lowpart (SImode, operands[1]);
3541 operands[5] = gen_lowpart (SImode, operands[2]);
3542 operands[6] = gen_highpart (SImode, operands[0]);
3543 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3544 #if HOST_BITS_PER_WIDE_INT == 32
3545 if (GET_CODE (operands[2]) == CONST_INT)
3547 if (INTVAL (operands[2]) < 0)
3548 operands[8] = constm1_rtx;
3550 operands[8] = const0_rtx;
3554 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3556 [(set_attr "length" "2")])
3558 ;; LTU here means "carry set"
3560 [(set (match_operand:SI 0 "register_operand" "=r")
3561 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3562 (match_operand:SI 2 "arith_operand" "rI"))
3563 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3566 [(set_attr "type" "ialuX")])
3568 (define_insn_and_split "*addx_extend_sp32"
3569 [(set (match_operand:DI 0 "register_operand" "=r")
3570 (zero_extend:DI (plus:SI (plus:SI
3571 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3572 (match_operand:SI 2 "arith_operand" "rI"))
3573 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3576 "&& reload_completed"
3577 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3578 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3579 (set (match_dup 4) (const_int 0))]
3580 "operands[3] = gen_lowpart (SImode, operands[0]);
3581 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3582 [(set_attr "length" "2")])
3584 (define_insn "*addx_extend_sp64"
3585 [(set (match_operand:DI 0 "register_operand" "=r")
3586 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3587 (match_operand:SI 2 "arith_operand" "rI"))
3588 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3591 [(set_attr "type" "ialuX")])
3593 (define_insn_and_split "*adddi3_extend_sp32"
3594 [(set (match_operand:DI 0 "register_operand" "=r")
3595 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3596 (match_operand:DI 2 "register_operand" "r")))
3597 (clobber (reg:CC 100))]
3600 "&& reload_completed"
3601 [(parallel [(set (reg:CC_NOOV 100)
3602 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3604 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3606 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3607 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3608 "operands[3] = gen_lowpart (SImode, operands[2]);
3609 operands[4] = gen_highpart (SImode, operands[2]);
3610 operands[5] = gen_lowpart (SImode, operands[0]);
3611 operands[6] = gen_highpart (SImode, operands[0]);"
3612 [(set_attr "length" "2")])
3614 (define_insn "*adddi3_sp64"
3615 [(set (match_operand:DI 0 "register_operand" "=r,r")
3616 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3617 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3623 (define_insn "addsi3"
3624 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3625 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3626 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3631 fpadd32s\t%1, %2, %0"
3632 [(set_attr "type" "*,*,fga")
3633 (set_attr "fptype" "*,*,single")])
3635 (define_insn "*cmp_cc_plus"
3636 [(set (reg:CC_NOOV 100)
3637 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3638 (match_operand:SI 1 "arith_operand" "rI"))
3641 "addcc\t%0, %1, %%g0"
3642 [(set_attr "type" "compare")])
3644 (define_insn "*cmp_ccx_plus"
3645 [(set (reg:CCX_NOOV 100)
3646 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3647 (match_operand:DI 1 "arith_operand" "rI"))
3650 "addcc\t%0, %1, %%g0"
3651 [(set_attr "type" "compare")])
3653 (define_insn "*cmp_cc_plus_set"
3654 [(set (reg:CC_NOOV 100)
3655 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3656 (match_operand:SI 2 "arith_operand" "rI"))
3658 (set (match_operand:SI 0 "register_operand" "=r")
3659 (plus:SI (match_dup 1) (match_dup 2)))]
3662 [(set_attr "type" "compare")])
3664 (define_insn "*cmp_ccx_plus_set"
3665 [(set (reg:CCX_NOOV 100)
3666 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3667 (match_operand:DI 2 "arith_operand" "rI"))
3669 (set (match_operand:DI 0 "register_operand" "=r")
3670 (plus:DI (match_dup 1) (match_dup 2)))]
3673 [(set_attr "type" "compare")])
3675 (define_expand "subdi3"
3676 [(set (match_operand:DI 0 "register_operand" "")
3677 (minus:DI (match_operand:DI 1 "register_operand" "")
3678 (match_operand:DI 2 "arith_double_add_operand" "")))]
3681 if (! TARGET_ARCH64)
3683 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3684 gen_rtx_SET (VOIDmode, operands[0],
3685 gen_rtx_MINUS (DImode, operands[1],
3687 gen_rtx_CLOBBER (VOIDmode,
3688 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3693 (define_insn_and_split "*subdi3_insn_sp32"
3694 [(set (match_operand:DI 0 "register_operand" "=r")
3695 (minus:DI (match_operand:DI 1 "register_operand" "r")
3696 (match_operand:DI 2 "arith_double_operand" "rHI")))
3697 (clobber (reg:CC 100))]
3700 "&& reload_completed"
3701 [(parallel [(set (reg:CC_NOOV 100)
3702 (compare:CC_NOOV (minus:SI (match_dup 4)
3706 (minus:SI (match_dup 4) (match_dup 5)))])
3708 (minus:SI (minus:SI (match_dup 7)
3710 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3712 operands[3] = gen_lowpart (SImode, operands[0]);
3713 operands[4] = gen_lowpart (SImode, operands[1]);
3714 operands[5] = gen_lowpart (SImode, operands[2]);
3715 operands[6] = gen_highpart (SImode, operands[0]);
3716 operands[7] = gen_highpart (SImode, operands[1]);
3717 #if HOST_BITS_PER_WIDE_INT == 32
3718 if (GET_CODE (operands[2]) == CONST_INT)
3720 if (INTVAL (operands[2]) < 0)
3721 operands[8] = constm1_rtx;
3723 operands[8] = const0_rtx;
3727 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3729 [(set_attr "length" "2")])
3731 ;; LTU here means "carry set"
3733 [(set (match_operand:SI 0 "register_operand" "=r")
3734 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3735 (match_operand:SI 2 "arith_operand" "rI"))
3736 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3739 [(set_attr "type" "ialuX")])
3741 (define_insn "*subx_extend_sp64"
3742 [(set (match_operand:DI 0 "register_operand" "=r")
3743 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3744 (match_operand:SI 2 "arith_operand" "rI"))
3745 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3748 [(set_attr "type" "ialuX")])
3750 (define_insn_and_split "*subx_extend"
3751 [(set (match_operand:DI 0 "register_operand" "=r")
3752 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3753 (match_operand:SI 2 "arith_operand" "rI"))
3754 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3757 "&& reload_completed"
3758 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3759 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3760 (set (match_dup 4) (const_int 0))]
3761 "operands[3] = gen_lowpart (SImode, operands[0]);
3762 operands[4] = gen_highpart (SImode, operands[0]);"
3763 [(set_attr "length" "2")])
3765 (define_insn_and_split "*subdi3_extend_sp32"
3766 [(set (match_operand:DI 0 "register_operand" "=r")
3767 (minus:DI (match_operand:DI 1 "register_operand" "r")
3768 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3769 (clobber (reg:CC 100))]
3772 "&& reload_completed"
3773 [(parallel [(set (reg:CC_NOOV 100)
3774 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3776 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3778 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3779 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3780 "operands[3] = gen_lowpart (SImode, operands[1]);
3781 operands[4] = gen_highpart (SImode, operands[1]);
3782 operands[5] = gen_lowpart (SImode, operands[0]);
3783 operands[6] = gen_highpart (SImode, operands[0]);"
3784 [(set_attr "length" "2")])
3786 (define_insn "*subdi3_sp64"
3787 [(set (match_operand:DI 0 "register_operand" "=r,r")
3788 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3789 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3795 (define_insn "subsi3"
3796 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3797 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3798 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3803 fpsub32s\t%1, %2, %0"
3804 [(set_attr "type" "*,*,fga")
3805 (set_attr "fptype" "*,*,single")])
3807 (define_insn "*cmp_minus_cc"
3808 [(set (reg:CC_NOOV 100)
3809 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3810 (match_operand:SI 1 "arith_operand" "rI"))
3813 "subcc\t%r0, %1, %%g0"
3814 [(set_attr "type" "compare")])
3816 (define_insn "*cmp_minus_ccx"
3817 [(set (reg:CCX_NOOV 100)
3818 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3819 (match_operand:DI 1 "arith_operand" "rI"))
3822 "subcc\t%0, %1, %%g0"
3823 [(set_attr "type" "compare")])
3825 (define_insn "cmp_minus_cc_set"
3826 [(set (reg:CC_NOOV 100)
3827 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3828 (match_operand:SI 2 "arith_operand" "rI"))
3830 (set (match_operand:SI 0 "register_operand" "=r")
3831 (minus:SI (match_dup 1) (match_dup 2)))]
3833 "subcc\t%r1, %2, %0"
3834 [(set_attr "type" "compare")])
3836 (define_insn "*cmp_minus_ccx_set"
3837 [(set (reg:CCX_NOOV 100)
3838 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3839 (match_operand:DI 2 "arith_operand" "rI"))
3841 (set (match_operand:DI 0 "register_operand" "=r")
3842 (minus:DI (match_dup 1) (match_dup 2)))]
3845 [(set_attr "type" "compare")])
3848 ;; Integer multiply/divide instructions.
3850 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3851 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3853 (define_insn "mulsi3"
3854 [(set (match_operand:SI 0 "register_operand" "=r")
3855 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3856 (match_operand:SI 2 "arith_operand" "rI")))]
3859 [(set_attr "type" "imul")])
3861 (define_expand "muldi3"
3862 [(set (match_operand:DI 0 "register_operand" "")
3863 (mult:DI (match_operand:DI 1 "arith_operand" "")
3864 (match_operand:DI 2 "arith_operand" "")))]
3865 "TARGET_ARCH64 || TARGET_V8PLUS"
3869 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3874 (define_insn "*muldi3_sp64"
3875 [(set (match_operand:DI 0 "register_operand" "=r")
3876 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3877 (match_operand:DI 2 "arith_operand" "rI")))]
3880 [(set_attr "type" "imul")])
3882 ;; V8plus wide multiply.
3884 (define_insn "muldi3_v8plus"
3885 [(set (match_operand:DI 0 "register_operand" "=r,h")
3886 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3887 (match_operand:DI 2 "arith_operand" "rI,rI")))
3888 (clobber (match_scratch:SI 3 "=&h,X"))
3889 (clobber (match_scratch:SI 4 "=&h,X"))]
3892 if (sparc_check_64 (operands[1], insn) <= 0)
3893 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3894 if (which_alternative == 1)
3895 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3896 if (GET_CODE (operands[2]) == CONST_INT)
3898 if (which_alternative == 1)
3899 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3901 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";
3903 else if (rtx_equal_p (operands[1], operands[2]))
3905 if (which_alternative == 1)
3906 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3908 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";
3910 if (sparc_check_64 (operands[2], insn) <= 0)
3911 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3912 if (which_alternative == 1)
3913 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";
3915 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";
3917 [(set_attr "type" "multi")
3918 (set_attr "length" "9,8")])
3920 (define_insn "*cmp_mul_set"
3922 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3923 (match_operand:SI 2 "arith_operand" "rI"))
3925 (set (match_operand:SI 0 "register_operand" "=r")
3926 (mult:SI (match_dup 1) (match_dup 2)))]
3927 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3928 "smulcc\t%1, %2, %0"
3929 [(set_attr "type" "imul")])
3931 (define_expand "mulsidi3"
3932 [(set (match_operand:DI 0 "register_operand" "")
3933 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3934 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3937 if (CONSTANT_P (operands[2]))
3940 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3942 else if (TARGET_ARCH32)
3943 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3946 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3952 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3957 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3958 ;; registers can hold 64-bit values in the V8plus environment.
3960 (define_insn "mulsidi3_v8plus"
3961 [(set (match_operand:DI 0 "register_operand" "=h,r")
3962 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3963 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3964 (clobber (match_scratch:SI 3 "=X,&h"))]
3967 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3968 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3969 [(set_attr "type" "multi")
3970 (set_attr "length" "2,3")])
3973 (define_insn "const_mulsidi3_v8plus"
3974 [(set (match_operand:DI 0 "register_operand" "=h,r")
3975 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3976 (match_operand:DI 2 "small_int_operand" "I,I")))
3977 (clobber (match_scratch:SI 3 "=X,&h"))]
3980 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3981 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3982 [(set_attr "type" "multi")
3983 (set_attr "length" "2,3")])
3986 (define_insn "*mulsidi3_sp32"
3987 [(set (match_operand:DI 0 "register_operand" "=r")
3988 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3989 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3992 return TARGET_SPARCLET
3993 ? "smuld\t%1, %2, %L0"
3994 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3997 (if_then_else (eq_attr "isa" "sparclet")
3998 (const_string "imul") (const_string "multi")))
3999 (set (attr "length")
4000 (if_then_else (eq_attr "isa" "sparclet")
4001 (const_int 1) (const_int 2)))])
4003 (define_insn "*mulsidi3_sp64"
4004 [(set (match_operand:DI 0 "register_operand" "=r")
4005 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4006 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4007 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4009 [(set_attr "type" "imul")])
4011 ;; Extra pattern, because sign_extend of a constant isn't valid.
4014 (define_insn "const_mulsidi3_sp32"
4015 [(set (match_operand:DI 0 "register_operand" "=r")
4016 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4017 (match_operand:DI 2 "small_int_operand" "I")))]
4020 return TARGET_SPARCLET
4021 ? "smuld\t%1, %2, %L0"
4022 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4025 (if_then_else (eq_attr "isa" "sparclet")
4026 (const_string "imul") (const_string "multi")))
4027 (set (attr "length")
4028 (if_then_else (eq_attr "isa" "sparclet")
4029 (const_int 1) (const_int 2)))])
4031 (define_insn "const_mulsidi3_sp64"
4032 [(set (match_operand:DI 0 "register_operand" "=r")
4033 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4034 (match_operand:DI 2 "small_int_operand" "I")))]
4035 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4037 [(set_attr "type" "imul")])
4039 (define_expand "smulsi3_highpart"
4040 [(set (match_operand:SI 0 "register_operand" "")
4042 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4043 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4045 "TARGET_HARD_MUL && TARGET_ARCH32"
4047 if (CONSTANT_P (operands[2]))
4051 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4057 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4062 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4063 operands[2], GEN_INT (32)));
4069 (define_insn "smulsi3_highpart_v8plus"
4070 [(set (match_operand:SI 0 "register_operand" "=h,r")
4072 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4073 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4074 (match_operand:SI 3 "small_int_operand" "I,I"))))
4075 (clobber (match_scratch:SI 4 "=X,&h"))]
4078 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4079 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4080 [(set_attr "type" "multi")
4081 (set_attr "length" "2")])
4083 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4086 [(set (match_operand:SI 0 "register_operand" "=h,r")
4089 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4090 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4091 (match_operand:SI 3 "small_int_operand" "I,I"))
4093 (clobber (match_scratch:SI 4 "=X,&h"))]
4096 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4097 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4098 [(set_attr "type" "multi")
4099 (set_attr "length" "2")])
4102 (define_insn "const_smulsi3_highpart_v8plus"
4103 [(set (match_operand:SI 0 "register_operand" "=h,r")
4105 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4106 (match_operand:DI 2 "small_int_operand" "I,I"))
4107 (match_operand:SI 3 "small_int_operand" "I,I"))))
4108 (clobber (match_scratch:SI 4 "=X,&h"))]
4111 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4112 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4113 [(set_attr "type" "multi")
4114 (set_attr "length" "2")])
4117 (define_insn "*smulsi3_highpart_sp32"
4118 [(set (match_operand:SI 0 "register_operand" "=r")
4120 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4121 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4124 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4125 [(set_attr "type" "multi")
4126 (set_attr "length" "2")])
4129 (define_insn "const_smulsi3_highpart"
4130 [(set (match_operand:SI 0 "register_operand" "=r")
4132 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4133 (match_operand:DI 2 "small_int_operand" "i"))
4136 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4137 [(set_attr "type" "multi")
4138 (set_attr "length" "2")])
4140 (define_expand "umulsidi3"
4141 [(set (match_operand:DI 0 "register_operand" "")
4142 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4143 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4146 if (CONSTANT_P (operands[2]))
4149 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4151 else if (TARGET_ARCH32)
4152 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4155 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4161 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4167 (define_insn "umulsidi3_v8plus"
4168 [(set (match_operand:DI 0 "register_operand" "=h,r")
4169 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4170 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4171 (clobber (match_scratch:SI 3 "=X,&h"))]
4174 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4175 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4176 [(set_attr "type" "multi")
4177 (set_attr "length" "2,3")])
4180 (define_insn "*umulsidi3_sp32"
4181 [(set (match_operand:DI 0 "register_operand" "=r")
4182 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4183 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4186 return TARGET_SPARCLET
4187 ? "umuld\t%1, %2, %L0"
4188 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4191 (if_then_else (eq_attr "isa" "sparclet")
4192 (const_string "imul") (const_string "multi")))
4193 (set (attr "length")
4194 (if_then_else (eq_attr "isa" "sparclet")
4195 (const_int 1) (const_int 2)))])
4197 (define_insn "*umulsidi3_sp64"
4198 [(set (match_operand:DI 0 "register_operand" "=r")
4199 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4200 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4201 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4203 [(set_attr "type" "imul")])
4205 ;; Extra pattern, because sign_extend of a constant isn't valid.
4208 (define_insn "const_umulsidi3_sp32"
4209 [(set (match_operand:DI 0 "register_operand" "=r")
4210 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4211 (match_operand:DI 2 "uns_small_int_operand" "")))]
4214 return TARGET_SPARCLET
4215 ? "umuld\t%1, %s2, %L0"
4216 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4219 (if_then_else (eq_attr "isa" "sparclet")
4220 (const_string "imul") (const_string "multi")))
4221 (set (attr "length")
4222 (if_then_else (eq_attr "isa" "sparclet")
4223 (const_int 1) (const_int 2)))])
4225 (define_insn "const_umulsidi3_sp64"
4226 [(set (match_operand:DI 0 "register_operand" "=r")
4227 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4228 (match_operand:DI 2 "uns_small_int_operand" "")))]
4229 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4231 [(set_attr "type" "imul")])
4234 (define_insn "const_umulsidi3_v8plus"
4235 [(set (match_operand:DI 0 "register_operand" "=h,r")
4236 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4237 (match_operand:DI 2 "uns_small_int_operand" "")))
4238 (clobber (match_scratch:SI 3 "=X,h"))]
4241 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4242 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4243 [(set_attr "type" "multi")
4244 (set_attr "length" "2,3")])
4246 (define_expand "umulsi3_highpart"
4247 [(set (match_operand:SI 0 "register_operand" "")
4249 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4250 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4252 "TARGET_HARD_MUL && TARGET_ARCH32"
4254 if (CONSTANT_P (operands[2]))
4258 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4264 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4269 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4270 operands[2], GEN_INT (32)));
4276 (define_insn "umulsi3_highpart_v8plus"
4277 [(set (match_operand:SI 0 "register_operand" "=h,r")
4279 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4280 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4281 (match_operand:SI 3 "small_int_operand" "I,I"))))
4282 (clobber (match_scratch:SI 4 "=X,h"))]
4285 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4286 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4287 [(set_attr "type" "multi")
4288 (set_attr "length" "2")])
4291 (define_insn "const_umulsi3_highpart_v8plus"
4292 [(set (match_operand:SI 0 "register_operand" "=h,r")
4294 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4295 (match_operand:DI 2 "uns_small_int_operand" ""))
4296 (match_operand:SI 3 "small_int_operand" "I,I"))))
4297 (clobber (match_scratch:SI 4 "=X,h"))]
4300 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4301 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4302 [(set_attr "type" "multi")
4303 (set_attr "length" "2")])
4306 (define_insn "*umulsi3_highpart_sp32"
4307 [(set (match_operand:SI 0 "register_operand" "=r")
4309 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4310 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4313 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4314 [(set_attr "type" "multi")
4315 (set_attr "length" "2")])
4318 (define_insn "const_umulsi3_highpart"
4319 [(set (match_operand:SI 0 "register_operand" "=r")
4321 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4322 (match_operand:DI 2 "uns_small_int_operand" ""))
4325 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4326 [(set_attr "type" "multi")
4327 (set_attr "length" "2")])
4329 (define_expand "divsi3"
4330 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4331 (div:SI (match_operand:SI 1 "register_operand" "")
4332 (match_operand:SI 2 "input_operand" "")))
4333 (clobber (match_scratch:SI 3 ""))])]
4334 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4338 operands[3] = gen_reg_rtx(SImode);
4339 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4340 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4346 ;; The V8 architecture specifies that there must be at least 3 instructions
4347 ;; between a write to the Y register and a use of it for correct results.
4348 ;; We try to fill one of them with a simple constant or a memory load.
4350 (define_insn "divsi3_sp32"
4351 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4352 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4353 (match_operand:SI 2 "input_operand" "rI,K,m")))
4354 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4355 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4357 output_asm_insn ("sra\t%1, 31, %3", operands);
4358 output_asm_insn ("wr\t%3, 0, %%y", operands);
4360 switch (which_alternative)
4364 return "sdiv\t%1, %2, %0";
4366 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4369 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4371 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4374 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4376 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4381 [(set_attr "type" "multi")
4382 (set (attr "length")
4383 (if_then_else (eq_attr "isa" "v9")
4384 (const_int 4) (const_int 6)))])
4386 (define_insn "divsi3_sp64"
4387 [(set (match_operand:SI 0 "register_operand" "=r")
4388 (div:SI (match_operand:SI 1 "register_operand" "r")
4389 (match_operand:SI 2 "input_operand" "rI")))
4390 (use (match_operand:SI 3 "register_operand" "r"))]
4391 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4392 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4393 [(set_attr "type" "multi")
4394 (set_attr "length" "2")])
4396 (define_insn "divdi3"
4397 [(set (match_operand:DI 0 "register_operand" "=r")
4398 (div:DI (match_operand:DI 1 "register_operand" "r")
4399 (match_operand:DI 2 "arith_operand" "rI")))]
4402 [(set_attr "type" "idiv")])
4404 (define_insn "*cmp_sdiv_cc_set"
4406 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4407 (match_operand:SI 2 "arith_operand" "rI"))
4409 (set (match_operand:SI 0 "register_operand" "=r")
4410 (div:SI (match_dup 1) (match_dup 2)))
4411 (clobber (match_scratch:SI 3 "=&r"))]
4412 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4414 output_asm_insn ("sra\t%1, 31, %3", operands);
4415 output_asm_insn ("wr\t%3, 0, %%y", operands);
4418 return "sdivcc\t%1, %2, %0";
4420 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4422 [(set_attr "type" "multi")
4423 (set (attr "length")
4424 (if_then_else (eq_attr "isa" "v9")
4425 (const_int 3) (const_int 6)))])
4428 (define_expand "udivsi3"
4429 [(set (match_operand:SI 0 "register_operand" "")
4430 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4431 (match_operand:SI 2 "input_operand" "")))]
4432 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4435 ;; The V8 architecture specifies that there must be at least 3 instructions
4436 ;; between a write to the Y register and a use of it for correct results.
4437 ;; We try to fill one of them with a simple constant or a memory load.
4439 (define_insn "udivsi3_sp32"
4440 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4441 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4442 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4443 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4445 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4447 switch (which_alternative)
4451 return "udiv\t%1, %2, %0";
4453 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4456 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4458 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4461 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4463 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4466 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4468 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4473 [(set_attr "type" "multi")
4474 (set (attr "length")
4475 (if_then_else (eq_attr "isa" "v9")
4476 (const_int 3) (const_int 5)))])
4478 (define_insn "udivsi3_sp64"
4479 [(set (match_operand:SI 0 "register_operand" "=r")
4480 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4481 (match_operand:SI 2 "input_operand" "rI")))]
4482 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4483 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4484 [(set_attr "type" "multi")
4485 (set_attr "length" "2")])
4487 (define_insn "udivdi3"
4488 [(set (match_operand:DI 0 "register_operand" "=r")
4489 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4490 (match_operand:DI 2 "arith_operand" "rI")))]
4493 [(set_attr "type" "idiv")])
4495 (define_insn "*cmp_udiv_cc_set"
4497 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4498 (match_operand:SI 2 "arith_operand" "rI"))
4500 (set (match_operand:SI 0 "register_operand" "=r")
4501 (udiv:SI (match_dup 1) (match_dup 2)))]
4502 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4504 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4507 return "udivcc\t%1, %2, %0";
4509 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4511 [(set_attr "type" "multi")
4512 (set (attr "length")
4513 (if_then_else (eq_attr "isa" "v9")
4514 (const_int 2) (const_int 5)))])
4516 ; sparclet multiply/accumulate insns
4518 (define_insn "*smacsi"
4519 [(set (match_operand:SI 0 "register_operand" "=r")
4520 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4521 (match_operand:SI 2 "arith_operand" "rI"))
4522 (match_operand:SI 3 "register_operand" "0")))]
4525 [(set_attr "type" "imul")])
4527 (define_insn "*smacdi"
4528 [(set (match_operand:DI 0 "register_operand" "=r")
4529 (plus:DI (mult:DI (sign_extend:DI
4530 (match_operand:SI 1 "register_operand" "%r"))
4532 (match_operand:SI 2 "register_operand" "r")))
4533 (match_operand:DI 3 "register_operand" "0")))]
4535 "smacd\t%1, %2, %L0"
4536 [(set_attr "type" "imul")])
4538 (define_insn "*umacdi"
4539 [(set (match_operand:DI 0 "register_operand" "=r")
4540 (plus:DI (mult:DI (zero_extend:DI
4541 (match_operand:SI 1 "register_operand" "%r"))
4543 (match_operand:SI 2 "register_operand" "r")))
4544 (match_operand:DI 3 "register_operand" "0")))]
4546 "umacd\t%1, %2, %L0"
4547 [(set_attr "type" "imul")])
4550 ;; Boolean instructions.
4552 ;; We define DImode `and' so with DImode `not' we can get
4553 ;; DImode `andn'. Other combinations are possible.
4555 (define_expand "and<V64I:mode>3"
4556 [(set (match_operand:V64I 0 "register_operand" "")
4557 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4558 (match_operand:V64I 2 "arith_double_operand" "")))]
4562 (define_insn "*and<V64I:mode>3_sp32"
4563 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4564 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4565 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4570 [(set_attr "type" "*,fga")
4571 (set_attr "length" "2,*")
4572 (set_attr "fptype" "*,double")])
4574 (define_insn "*and<V64I:mode>3_sp64"
4575 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4576 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4577 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4582 [(set_attr "type" "*,fga")
4583 (set_attr "fptype" "*,double")])
4585 (define_insn "and<V32I:mode>3"
4586 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4587 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4588 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4593 [(set_attr "type" "*,fga")
4594 (set_attr "fptype" "*,single")])
4597 [(set (match_operand:SI 0 "register_operand" "")
4598 (and:SI (match_operand:SI 1 "register_operand" "")
4599 (match_operand:SI 2 "const_compl_high_operand" "")))
4600 (clobber (match_operand:SI 3 "register_operand" ""))]
4602 [(set (match_dup 3) (match_dup 4))
4603 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4605 operands[4] = GEN_INT (~INTVAL (operands[2]));
4608 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4609 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4610 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4611 (match_operand:V64I 2 "register_operand" "r,b")))]
4615 fandnot1\t%1, %2, %0"
4616 "&& reload_completed
4617 && ((GET_CODE (operands[0]) == REG
4618 && REGNO (operands[0]) < 32)
4619 || (GET_CODE (operands[0]) == SUBREG
4620 && GET_CODE (SUBREG_REG (operands[0])) == REG
4621 && REGNO (SUBREG_REG (operands[0])) < 32))"
4622 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4623 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4624 "operands[3] = gen_highpart (SImode, operands[0]);
4625 operands[4] = gen_highpart (SImode, operands[1]);
4626 operands[5] = gen_highpart (SImode, operands[2]);
4627 operands[6] = gen_lowpart (SImode, operands[0]);
4628 operands[7] = gen_lowpart (SImode, operands[1]);
4629 operands[8] = gen_lowpart (SImode, operands[2]);"
4630 [(set_attr "type" "*,fga")
4631 (set_attr "length" "2,*")
4632 (set_attr "fptype" "*,double")])
4634 (define_insn "*and_not_<V64I:mode>_sp64"
4635 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4636 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4637 (match_operand:V64I 2 "register_operand" "r,b")))]
4641 fandnot1\t%1, %2, %0"
4642 [(set_attr "type" "*,fga")
4643 (set_attr "fptype" "*,double")])
4645 (define_insn "*and_not_<V32I:mode>"
4646 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4647 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4648 (match_operand:V32I 2 "register_operand" "r,d")))]
4652 fandnot1s\t%1, %2, %0"
4653 [(set_attr "type" "*,fga")
4654 (set_attr "fptype" "*,single")])
4656 (define_expand "ior<V64I:mode>3"
4657 [(set (match_operand:V64I 0 "register_operand" "")
4658 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4659 (match_operand:V64I 2 "arith_double_operand" "")))]
4663 (define_insn "*ior<V64I:mode>3_sp32"
4664 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4665 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4666 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4671 [(set_attr "type" "*,fga")
4672 (set_attr "length" "2,*")
4673 (set_attr "fptype" "*,double")])
4675 (define_insn "*ior<V64I:mode>3_sp64"
4676 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4677 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4678 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4683 [(set_attr "type" "*,fga")
4684 (set_attr "fptype" "*,double")])
4686 (define_insn "ior<V32I:mode>3"
4687 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4688 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4689 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4694 [(set_attr "type" "*,fga")
4695 (set_attr "fptype" "*,single")])
4698 [(set (match_operand:SI 0 "register_operand" "")
4699 (ior:SI (match_operand:SI 1 "register_operand" "")
4700 (match_operand:SI 2 "const_compl_high_operand" "")))
4701 (clobber (match_operand:SI 3 "register_operand" ""))]
4703 [(set (match_dup 3) (match_dup 4))
4704 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4706 operands[4] = GEN_INT (~INTVAL (operands[2]));
4709 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4710 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4711 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4712 (match_operand:V64I 2 "register_operand" "r,b")))]
4716 fornot1\t%1, %2, %0"
4717 "&& reload_completed
4718 && ((GET_CODE (operands[0]) == REG
4719 && REGNO (operands[0]) < 32)
4720 || (GET_CODE (operands[0]) == SUBREG
4721 && GET_CODE (SUBREG_REG (operands[0])) == REG
4722 && REGNO (SUBREG_REG (operands[0])) < 32))"
4723 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4724 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4725 "operands[3] = gen_highpart (SImode, operands[0]);
4726 operands[4] = gen_highpart (SImode, operands[1]);
4727 operands[5] = gen_highpart (SImode, operands[2]);
4728 operands[6] = gen_lowpart (SImode, operands[0]);
4729 operands[7] = gen_lowpart (SImode, operands[1]);
4730 operands[8] = gen_lowpart (SImode, operands[2]);"
4731 [(set_attr "type" "*,fga")
4732 (set_attr "length" "2,*")
4733 (set_attr "fptype" "*,double")])
4735 (define_insn "*or_not_<V64I:mode>_sp64"
4736 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4737 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4738 (match_operand:V64I 2 "register_operand" "r,b")))]
4742 fornot1\t%1, %2, %0"
4743 [(set_attr "type" "*,fga")
4744 (set_attr "fptype" "*,double")])
4746 (define_insn "*or_not_<V32I:mode>"
4747 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4748 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4749 (match_operand:V32I 2 "register_operand" "r,d")))]
4753 fornot1s\t%1, %2, %0"
4754 [(set_attr "type" "*,fga")
4755 (set_attr "fptype" "*,single")])
4757 (define_expand "xor<V64I:mode>3"
4758 [(set (match_operand:V64I 0 "register_operand" "")
4759 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4760 (match_operand:V64I 2 "arith_double_operand" "")))]
4764 (define_insn "*xor<V64I:mode>3_sp32"
4765 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4766 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4767 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4772 [(set_attr "type" "*,fga")
4773 (set_attr "length" "2,*")
4774 (set_attr "fptype" "*,double")])
4776 (define_insn "*xor<V64I:mode>3_sp64"
4777 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4778 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4779 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4784 [(set_attr "type" "*,fga")
4785 (set_attr "fptype" "*,double")])
4787 (define_insn "xor<V32I:mode>3"
4788 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4789 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4790 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4795 [(set_attr "type" "*,fga")
4796 (set_attr "fptype" "*,single")])
4799 [(set (match_operand:SI 0 "register_operand" "")
4800 (xor:SI (match_operand:SI 1 "register_operand" "")
4801 (match_operand:SI 2 "const_compl_high_operand" "")))
4802 (clobber (match_operand:SI 3 "register_operand" ""))]
4804 [(set (match_dup 3) (match_dup 4))
4805 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4807 operands[4] = GEN_INT (~INTVAL (operands[2]));
4811 [(set (match_operand:SI 0 "register_operand" "")
4812 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4813 (match_operand:SI 2 "const_compl_high_operand" ""))))
4814 (clobber (match_operand:SI 3 "register_operand" ""))]
4816 [(set (match_dup 3) (match_dup 4))
4817 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4819 operands[4] = GEN_INT (~INTVAL (operands[2]));
4822 ;; Split DImode logical operations requiring two instructions.
4824 [(set (match_operand:V64I 0 "register_operand" "")
4825 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4826 [(match_operand:V64I 2 "register_operand" "")
4827 (match_operand:V64I 3 "arith_double_operand" "")]))]
4830 && ((GET_CODE (operands[0]) == REG
4831 && REGNO (operands[0]) < 32)
4832 || (GET_CODE (operands[0]) == SUBREG
4833 && GET_CODE (SUBREG_REG (operands[0])) == REG
4834 && REGNO (SUBREG_REG (operands[0])) < 32))"
4835 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4836 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4838 operands[4] = gen_highpart (SImode, operands[0]);
4839 operands[5] = gen_lowpart (SImode, operands[0]);
4840 operands[6] = gen_highpart (SImode, operands[2]);
4841 operands[7] = gen_lowpart (SImode, operands[2]);
4842 #if HOST_BITS_PER_WIDE_INT == 32
4843 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4845 if (INTVAL (operands[3]) < 0)
4846 operands[8] = constm1_rtx;
4848 operands[8] = const0_rtx;
4852 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4853 operands[9] = gen_lowpart (SImode, operands[3]);
4856 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4857 ;; Combine now canonicalizes to the rightmost expression.
4858 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4859 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4860 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4861 (match_operand:V64I 2 "register_operand" "r,b"))))]
4866 "&& reload_completed
4867 && ((GET_CODE (operands[0]) == REG
4868 && REGNO (operands[0]) < 32)
4869 || (GET_CODE (operands[0]) == SUBREG
4870 && GET_CODE (SUBREG_REG (operands[0])) == REG
4871 && REGNO (SUBREG_REG (operands[0])) < 32))"
4872 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4873 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4874 "operands[3] = gen_highpart (SImode, operands[0]);
4875 operands[4] = gen_highpart (SImode, operands[1]);
4876 operands[5] = gen_highpart (SImode, operands[2]);
4877 operands[6] = gen_lowpart (SImode, operands[0]);
4878 operands[7] = gen_lowpart (SImode, operands[1]);
4879 operands[8] = gen_lowpart (SImode, operands[2]);"
4880 [(set_attr "type" "*,fga")
4881 (set_attr "length" "2,*")
4882 (set_attr "fptype" "*,double")])
4884 (define_insn "*xor_not_<V64I:mode>_sp64"
4885 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4886 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4887 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4892 [(set_attr "type" "*,fga")
4893 (set_attr "fptype" "*,double")])
4895 (define_insn "*xor_not_<V32I:mode>"
4896 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4897 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4898 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4903 [(set_attr "type" "*,fga")
4904 (set_attr "fptype" "*,single")])
4906 ;; These correspond to the above in the case where we also (or only)
4907 ;; want to set the condition code.
4909 (define_insn "*cmp_cc_arith_op"
4912 (match_operator:SI 2 "cc_arith_operator"
4913 [(match_operand:SI 0 "arith_operand" "%r")
4914 (match_operand:SI 1 "arith_operand" "rI")])
4917 "%A2cc\t%0, %1, %%g0"
4918 [(set_attr "type" "compare")])
4920 (define_insn "*cmp_ccx_arith_op"
4923 (match_operator:DI 2 "cc_arith_operator"
4924 [(match_operand:DI 0 "arith_operand" "%r")
4925 (match_operand:DI 1 "arith_operand" "rI")])
4928 "%A2cc\t%0, %1, %%g0"
4929 [(set_attr "type" "compare")])
4931 (define_insn "*cmp_cc_arith_op_set"
4934 (match_operator:SI 3 "cc_arith_operator"
4935 [(match_operand:SI 1 "arith_operand" "%r")
4936 (match_operand:SI 2 "arith_operand" "rI")])
4938 (set (match_operand:SI 0 "register_operand" "=r")
4939 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4940 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4942 [(set_attr "type" "compare")])
4944 (define_insn "*cmp_ccx_arith_op_set"
4947 (match_operator:DI 3 "cc_arith_operator"
4948 [(match_operand:DI 1 "arith_operand" "%r")
4949 (match_operand:DI 2 "arith_operand" "rI")])
4951 (set (match_operand:DI 0 "register_operand" "=r")
4952 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4953 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4955 [(set_attr "type" "compare")])
4957 (define_insn "*cmp_cc_xor_not"
4960 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4961 (match_operand:SI 1 "arith_operand" "rI")))
4964 "xnorcc\t%r0, %1, %%g0"
4965 [(set_attr "type" "compare")])
4967 (define_insn "*cmp_ccx_xor_not"
4970 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4971 (match_operand:DI 1 "arith_operand" "rI")))
4974 "xnorcc\t%r0, %1, %%g0"
4975 [(set_attr "type" "compare")])
4977 (define_insn "*cmp_cc_xor_not_set"
4980 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4981 (match_operand:SI 2 "arith_operand" "rI")))
4983 (set (match_operand:SI 0 "register_operand" "=r")
4984 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4986 "xnorcc\t%r1, %2, %0"
4987 [(set_attr "type" "compare")])
4989 (define_insn "*cmp_ccx_xor_not_set"
4992 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4993 (match_operand:DI 2 "arith_operand" "rI")))
4995 (set (match_operand:DI 0 "register_operand" "=r")
4996 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4998 "xnorcc\t%r1, %2, %0"
4999 [(set_attr "type" "compare")])
5001 (define_insn "*cmp_cc_arith_op_not"
5004 (match_operator:SI 2 "cc_arith_not_operator"
5005 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5006 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5009 "%B2cc\t%r1, %0, %%g0"
5010 [(set_attr "type" "compare")])
5012 (define_insn "*cmp_ccx_arith_op_not"
5015 (match_operator:DI 2 "cc_arith_not_operator"
5016 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5017 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5020 "%B2cc\t%r1, %0, %%g0"
5021 [(set_attr "type" "compare")])
5023 (define_insn "*cmp_cc_arith_op_not_set"
5026 (match_operator:SI 3 "cc_arith_not_operator"
5027 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5028 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5030 (set (match_operand:SI 0 "register_operand" "=r")
5031 (match_operator:SI 4 "cc_arith_not_operator"
5032 [(not:SI (match_dup 1)) (match_dup 2)]))]
5033 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5034 "%B3cc\t%r2, %1, %0"
5035 [(set_attr "type" "compare")])
5037 (define_insn "*cmp_ccx_arith_op_not_set"
5040 (match_operator:DI 3 "cc_arith_not_operator"
5041 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5042 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5044 (set (match_operand:DI 0 "register_operand" "=r")
5045 (match_operator:DI 4 "cc_arith_not_operator"
5046 [(not:DI (match_dup 1)) (match_dup 2)]))]
5047 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5048 "%B3cc\t%r2, %1, %0"
5049 [(set_attr "type" "compare")])
5051 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5052 ;; does not know how to make it work for constants.
5054 (define_expand "negdi2"
5055 [(set (match_operand:DI 0 "register_operand" "=r")
5056 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5059 if (! TARGET_ARCH64)
5061 emit_insn (gen_rtx_PARALLEL
5064 gen_rtx_SET (VOIDmode, operand0,
5065 gen_rtx_NEG (DImode, operand1)),
5066 gen_rtx_CLOBBER (VOIDmode,
5067 gen_rtx_REG (CCmode,
5073 (define_insn_and_split "*negdi2_sp32"
5074 [(set (match_operand:DI 0 "register_operand" "=r")
5075 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5076 (clobber (reg:CC 100))]
5079 "&& reload_completed"
5080 [(parallel [(set (reg:CC_NOOV 100)
5081 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5083 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5084 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5085 (ltu:SI (reg:CC 100) (const_int 0))))]
5086 "operands[2] = gen_highpart (SImode, operands[0]);
5087 operands[3] = gen_highpart (SImode, operands[1]);
5088 operands[4] = gen_lowpart (SImode, operands[0]);
5089 operands[5] = gen_lowpart (SImode, operands[1]);"
5090 [(set_attr "length" "2")])
5092 (define_insn "*negdi2_sp64"
5093 [(set (match_operand:DI 0 "register_operand" "=r")
5094 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5096 "sub\t%%g0, %1, %0")
5098 (define_insn "negsi2"
5099 [(set (match_operand:SI 0 "register_operand" "=r")
5100 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5102 "sub\t%%g0, %1, %0")
5104 (define_insn "*cmp_cc_neg"
5105 [(set (reg:CC_NOOV 100)
5106 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5109 "subcc\t%%g0, %0, %%g0"
5110 [(set_attr "type" "compare")])
5112 (define_insn "*cmp_ccx_neg"
5113 [(set (reg:CCX_NOOV 100)
5114 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5117 "subcc\t%%g0, %0, %%g0"
5118 [(set_attr "type" "compare")])
5120 (define_insn "*cmp_cc_set_neg"
5121 [(set (reg:CC_NOOV 100)
5122 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5124 (set (match_operand:SI 0 "register_operand" "=r")
5125 (neg:SI (match_dup 1)))]
5127 "subcc\t%%g0, %1, %0"
5128 [(set_attr "type" "compare")])
5130 (define_insn "*cmp_ccx_set_neg"
5131 [(set (reg:CCX_NOOV 100)
5132 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5134 (set (match_operand:DI 0 "register_operand" "=r")
5135 (neg:DI (match_dup 1)))]
5137 "subcc\t%%g0, %1, %0"
5138 [(set_attr "type" "compare")])
5140 ;; We cannot use the "not" pseudo insn because the Sun assembler
5141 ;; does not know how to make it work for constants.
5142 (define_expand "one_cmpl<V64I:mode>2"
5143 [(set (match_operand:V64I 0 "register_operand" "")
5144 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5148 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5149 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5150 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5155 "&& reload_completed
5156 && ((GET_CODE (operands[0]) == REG
5157 && REGNO (operands[0]) < 32)
5158 || (GET_CODE (operands[0]) == SUBREG
5159 && GET_CODE (SUBREG_REG (operands[0])) == REG
5160 && REGNO (SUBREG_REG (operands[0])) < 32))"
5161 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5162 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5163 "operands[2] = gen_highpart (SImode, operands[0]);
5164 operands[3] = gen_highpart (SImode, operands[1]);
5165 operands[4] = gen_lowpart (SImode, operands[0]);
5166 operands[5] = gen_lowpart (SImode, operands[1]);"
5167 [(set_attr "type" "*,fga")
5168 (set_attr "length" "2,*")
5169 (set_attr "fptype" "*,double")])
5171 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5172 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5173 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5178 [(set_attr "type" "*,fga")
5179 (set_attr "fptype" "*,double")])
5181 (define_insn "one_cmpl<V32I:mode>2"
5182 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5183 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5188 [(set_attr "type" "*,fga")
5189 (set_attr "fptype" "*,single")])
5191 (define_insn "*cmp_cc_not"
5193 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5196 "xnorcc\t%%g0, %0, %%g0"
5197 [(set_attr "type" "compare")])
5199 (define_insn "*cmp_ccx_not"
5201 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5204 "xnorcc\t%%g0, %0, %%g0"
5205 [(set_attr "type" "compare")])
5207 (define_insn "*cmp_cc_set_not"
5209 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5211 (set (match_operand:SI 0 "register_operand" "=r")
5212 (not:SI (match_dup 1)))]
5214 "xnorcc\t%%g0, %1, %0"
5215 [(set_attr "type" "compare")])
5217 (define_insn "*cmp_ccx_set_not"
5219 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5221 (set (match_operand:DI 0 "register_operand" "=r")
5222 (not:DI (match_dup 1)))]
5224 "xnorcc\t%%g0, %1, %0"
5225 [(set_attr "type" "compare")])
5227 (define_insn "*cmp_cc_set"
5228 [(set (match_operand:SI 0 "register_operand" "=r")
5229 (match_operand:SI 1 "register_operand" "r"))
5231 (compare:CC (match_dup 1)
5235 [(set_attr "type" "compare")])
5237 (define_insn "*cmp_ccx_set64"
5238 [(set (match_operand:DI 0 "register_operand" "=r")
5239 (match_operand:DI 1 "register_operand" "r"))
5241 (compare:CCX (match_dup 1)
5245 [(set_attr "type" "compare")])
5248 ;; Floating point arithmetic instructions.
5250 (define_expand "addtf3"
5251 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5252 (plus:TF (match_operand:TF 1 "general_operand" "")
5253 (match_operand:TF 2 "general_operand" "")))]
5254 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5255 "emit_tfmode_binop (PLUS, operands); DONE;")
5257 (define_insn "*addtf3_hq"
5258 [(set (match_operand:TF 0 "register_operand" "=e")
5259 (plus:TF (match_operand:TF 1 "register_operand" "e")
5260 (match_operand:TF 2 "register_operand" "e")))]
5261 "TARGET_FPU && TARGET_HARD_QUAD"
5263 [(set_attr "type" "fp")])
5265 (define_insn "adddf3"
5266 [(set (match_operand:DF 0 "register_operand" "=e")
5267 (plus:DF (match_operand:DF 1 "register_operand" "e")
5268 (match_operand:DF 2 "register_operand" "e")))]
5271 [(set_attr "type" "fp")
5272 (set_attr "fptype" "double")])
5274 (define_insn "addsf3"
5275 [(set (match_operand:SF 0 "register_operand" "=f")
5276 (plus:SF (match_operand:SF 1 "register_operand" "f")
5277 (match_operand:SF 2 "register_operand" "f")))]
5280 [(set_attr "type" "fp")])
5282 (define_expand "subtf3"
5283 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5284 (minus:TF (match_operand:TF 1 "general_operand" "")
5285 (match_operand:TF 2 "general_operand" "")))]
5286 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5287 "emit_tfmode_binop (MINUS, operands); DONE;")
5289 (define_insn "*subtf3_hq"
5290 [(set (match_operand:TF 0 "register_operand" "=e")
5291 (minus:TF (match_operand:TF 1 "register_operand" "e")
5292 (match_operand:TF 2 "register_operand" "e")))]
5293 "TARGET_FPU && TARGET_HARD_QUAD"
5295 [(set_attr "type" "fp")])
5297 (define_insn "subdf3"
5298 [(set (match_operand:DF 0 "register_operand" "=e")
5299 (minus:DF (match_operand:DF 1 "register_operand" "e")
5300 (match_operand:DF 2 "register_operand" "e")))]
5303 [(set_attr "type" "fp")
5304 (set_attr "fptype" "double")])
5306 (define_insn "subsf3"
5307 [(set (match_operand:SF 0 "register_operand" "=f")
5308 (minus:SF (match_operand:SF 1 "register_operand" "f")
5309 (match_operand:SF 2 "register_operand" "f")))]
5312 [(set_attr "type" "fp")])
5314 (define_expand "multf3"
5315 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5316 (mult:TF (match_operand:TF 1 "general_operand" "")
5317 (match_operand:TF 2 "general_operand" "")))]
5318 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5319 "emit_tfmode_binop (MULT, operands); DONE;")
5321 (define_insn "*multf3_hq"
5322 [(set (match_operand:TF 0 "register_operand" "=e")
5323 (mult:TF (match_operand:TF 1 "register_operand" "e")
5324 (match_operand:TF 2 "register_operand" "e")))]
5325 "TARGET_FPU && TARGET_HARD_QUAD"
5327 [(set_attr "type" "fpmul")])
5329 (define_insn "muldf3"
5330 [(set (match_operand:DF 0 "register_operand" "=e")
5331 (mult:DF (match_operand:DF 1 "register_operand" "e")
5332 (match_operand:DF 2 "register_operand" "e")))]
5335 [(set_attr "type" "fpmul")
5336 (set_attr "fptype" "double")])
5338 (define_insn "mulsf3"
5339 [(set (match_operand:SF 0 "register_operand" "=f")
5340 (mult:SF (match_operand:SF 1 "register_operand" "f")
5341 (match_operand:SF 2 "register_operand" "f")))]
5344 [(set_attr "type" "fpmul")])
5346 (define_insn "*muldf3_extend"
5347 [(set (match_operand:DF 0 "register_operand" "=e")
5348 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5349 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5350 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5351 "fsmuld\t%1, %2, %0"
5352 [(set_attr "type" "fpmul")
5353 (set_attr "fptype" "double")])
5355 (define_insn "*multf3_extend"
5356 [(set (match_operand:TF 0 "register_operand" "=e")
5357 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5358 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5359 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5360 "fdmulq\t%1, %2, %0"
5361 [(set_attr "type" "fpmul")])
5363 (define_expand "divtf3"
5364 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5365 (div:TF (match_operand:TF 1 "general_operand" "")
5366 (match_operand:TF 2 "general_operand" "")))]
5367 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5368 "emit_tfmode_binop (DIV, operands); DONE;")
5370 ;; don't have timing for quad-prec. divide.
5371 (define_insn "*divtf3_hq"
5372 [(set (match_operand:TF 0 "register_operand" "=e")
5373 (div:TF (match_operand:TF 1 "register_operand" "e")
5374 (match_operand:TF 2 "register_operand" "e")))]
5375 "TARGET_FPU && TARGET_HARD_QUAD"
5377 [(set_attr "type" "fpdivd")])
5379 (define_insn "divdf3"
5380 [(set (match_operand:DF 0 "register_operand" "=e")
5381 (div:DF (match_operand:DF 1 "register_operand" "e")
5382 (match_operand:DF 2 "register_operand" "e")))]
5385 [(set_attr "type" "fpdivd")
5386 (set_attr "fptype" "double")])
5388 (define_insn "divsf3"
5389 [(set (match_operand:SF 0 "register_operand" "=f")
5390 (div:SF (match_operand:SF 1 "register_operand" "f")
5391 (match_operand:SF 2 "register_operand" "f")))]
5394 [(set_attr "type" "fpdivs")])
5396 (define_expand "negtf2"
5397 [(set (match_operand:TF 0 "register_operand" "=e,e")
5398 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5402 (define_insn_and_split "*negtf2_notv9"
5403 [(set (match_operand:TF 0 "register_operand" "=e,e")
5404 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5405 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5411 "&& reload_completed
5412 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5413 [(set (match_dup 2) (neg:SF (match_dup 3)))
5414 (set (match_dup 4) (match_dup 5))
5415 (set (match_dup 6) (match_dup 7))]
5416 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5417 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5418 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5419 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5420 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5421 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5422 [(set_attr "type" "fpmove,*")
5423 (set_attr "length" "*,2")])
5425 (define_insn_and_split "*negtf2_v9"
5426 [(set (match_operand:TF 0 "register_operand" "=e,e")
5427 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5428 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5429 "TARGET_FPU && TARGET_V9"
5433 "&& reload_completed
5434 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5435 [(set (match_dup 2) (neg:DF (match_dup 3)))
5436 (set (match_dup 4) (match_dup 5))]
5437 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5438 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5439 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5440 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5441 [(set_attr "type" "fpmove,*")
5442 (set_attr "length" "*,2")
5443 (set_attr "fptype" "double")])
5445 (define_expand "negdf2"
5446 [(set (match_operand:DF 0 "register_operand" "")
5447 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5451 (define_insn_and_split "*negdf2_notv9"
5452 [(set (match_operand:DF 0 "register_operand" "=e,e")
5453 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5454 "TARGET_FPU && ! TARGET_V9"
5458 "&& reload_completed
5459 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5460 [(set (match_dup 2) (neg:SF (match_dup 3)))
5461 (set (match_dup 4) (match_dup 5))]
5462 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5463 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5464 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5465 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5466 [(set_attr "type" "fpmove,*")
5467 (set_attr "length" "*,2")])
5469 (define_insn "*negdf2_v9"
5470 [(set (match_operand:DF 0 "register_operand" "=e")
5471 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5472 "TARGET_FPU && TARGET_V9"
5474 [(set_attr "type" "fpmove")
5475 (set_attr "fptype" "double")])
5477 (define_insn "negsf2"
5478 [(set (match_operand:SF 0 "register_operand" "=f")
5479 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5482 [(set_attr "type" "fpmove")])
5484 (define_expand "abstf2"
5485 [(set (match_operand:TF 0 "register_operand" "")
5486 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5490 (define_insn_and_split "*abstf2_notv9"
5491 [(set (match_operand:TF 0 "register_operand" "=e,e")
5492 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5493 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5494 "TARGET_FPU && ! TARGET_V9"
5498 "&& reload_completed
5499 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5500 [(set (match_dup 2) (abs:SF (match_dup 3)))
5501 (set (match_dup 4) (match_dup 5))
5502 (set (match_dup 6) (match_dup 7))]
5503 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5504 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5505 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5506 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5507 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5508 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5509 [(set_attr "type" "fpmove,*")
5510 (set_attr "length" "*,2")])
5512 (define_insn "*abstf2_hq_v9"
5513 [(set (match_operand:TF 0 "register_operand" "=e,e")
5514 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5515 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5519 [(set_attr "type" "fpmove")
5520 (set_attr "fptype" "double,*")])
5522 (define_insn_and_split "*abstf2_v9"
5523 [(set (match_operand:TF 0 "register_operand" "=e,e")
5524 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5525 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5529 "&& reload_completed
5530 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5531 [(set (match_dup 2) (abs:DF (match_dup 3)))
5532 (set (match_dup 4) (match_dup 5))]
5533 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5534 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5535 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5536 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5537 [(set_attr "type" "fpmove,*")
5538 (set_attr "length" "*,2")
5539 (set_attr "fptype" "double,*")])
5541 (define_expand "absdf2"
5542 [(set (match_operand:DF 0 "register_operand" "")
5543 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5547 (define_insn_and_split "*absdf2_notv9"
5548 [(set (match_operand:DF 0 "register_operand" "=e,e")
5549 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5550 "TARGET_FPU && ! TARGET_V9"
5554 "&& reload_completed
5555 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5556 [(set (match_dup 2) (abs:SF (match_dup 3)))
5557 (set (match_dup 4) (match_dup 5))]
5558 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5559 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5560 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5561 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5562 [(set_attr "type" "fpmove,*")
5563 (set_attr "length" "*,2")])
5565 (define_insn "*absdf2_v9"
5566 [(set (match_operand:DF 0 "register_operand" "=e")
5567 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5568 "TARGET_FPU && TARGET_V9"
5570 [(set_attr "type" "fpmove")
5571 (set_attr "fptype" "double")])
5573 (define_insn "abssf2"
5574 [(set (match_operand:SF 0 "register_operand" "=f")
5575 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5578 [(set_attr "type" "fpmove")])
5580 (define_expand "sqrttf2"
5581 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5582 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5583 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5584 "emit_tfmode_unop (SQRT, operands); DONE;")
5586 (define_insn "*sqrttf2_hq"
5587 [(set (match_operand:TF 0 "register_operand" "=e")
5588 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5589 "TARGET_FPU && TARGET_HARD_QUAD"
5591 [(set_attr "type" "fpsqrtd")])
5593 (define_insn "sqrtdf2"
5594 [(set (match_operand:DF 0 "register_operand" "=e")
5595 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5598 [(set_attr "type" "fpsqrtd")
5599 (set_attr "fptype" "double")])
5601 (define_insn "sqrtsf2"
5602 [(set (match_operand:SF 0 "register_operand" "=f")
5603 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5606 [(set_attr "type" "fpsqrts")])
5609 ;; Arithmetic shift instructions.
5611 (define_insn "ashlsi3"
5612 [(set (match_operand:SI 0 "register_operand" "=r")
5613 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5614 (match_operand:SI 2 "arith_operand" "rI")))]
5617 if (GET_CODE (operands[2]) == CONST_INT)
5618 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5619 return "sll\t%1, %2, %0";
5622 (if_then_else (match_operand 2 "const_one_operand" "")
5623 (const_string "ialu") (const_string "shift")))])
5625 (define_expand "ashldi3"
5626 [(set (match_operand:DI 0 "register_operand" "=r")
5627 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5628 (match_operand:SI 2 "arith_operand" "rI")))]
5629 "TARGET_ARCH64 || TARGET_V8PLUS"
5631 if (! TARGET_ARCH64)
5633 if (GET_CODE (operands[2]) == CONST_INT)
5635 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5640 (define_insn "*ashldi3_sp64"
5641 [(set (match_operand:DI 0 "register_operand" "=r")
5642 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5643 (match_operand:SI 2 "arith_operand" "rI")))]
5646 if (GET_CODE (operands[2]) == CONST_INT)
5647 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5648 return "sllx\t%1, %2, %0";
5651 (if_then_else (match_operand 2 "const_one_operand" "")
5652 (const_string "ialu") (const_string "shift")))])
5655 (define_insn "ashldi3_v8plus"
5656 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5657 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5658 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5659 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5661 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5662 [(set_attr "type" "multi")
5663 (set_attr "length" "5,5,6")])
5665 ;; Optimize (1LL<<x)-1
5666 ;; XXX this also needs to be fixed to handle equal subregs
5667 ;; XXX first before we could re-enable it.
5669 ; [(set (match_operand:DI 0 "register_operand" "=h")
5670 ; (plus:DI (ashift:DI (const_int 1)
5671 ; (match_operand:SI 1 "arith_operand" "rI"))
5673 ; "0 && TARGET_V8PLUS"
5675 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5676 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5677 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5679 ; [(set_attr "type" "multi")
5680 ; (set_attr "length" "4")])
5682 (define_insn "*cmp_cc_ashift_1"
5683 [(set (reg:CC_NOOV 100)
5684 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5688 "addcc\t%0, %0, %%g0"
5689 [(set_attr "type" "compare")])
5691 (define_insn "*cmp_cc_set_ashift_1"
5692 [(set (reg:CC_NOOV 100)
5693 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5696 (set (match_operand:SI 0 "register_operand" "=r")
5697 (ashift:SI (match_dup 1) (const_int 1)))]
5700 [(set_attr "type" "compare")])
5702 (define_insn "ashrsi3"
5703 [(set (match_operand:SI 0 "register_operand" "=r")
5704 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5705 (match_operand:SI 2 "arith_operand" "rI")))]
5708 if (GET_CODE (operands[2]) == CONST_INT)
5709 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5710 return "sra\t%1, %2, %0";
5712 [(set_attr "type" "shift")])
5714 (define_insn "*ashrsi3_extend"
5715 [(set (match_operand:DI 0 "register_operand" "=r")
5716 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5717 (match_operand:SI 2 "arith_operand" "r"))))]
5720 [(set_attr "type" "shift")])
5722 ;; This handles the case as above, but with constant shift instead of
5723 ;; register. Combiner "simplifies" it for us a little bit though.
5724 (define_insn "*ashrsi3_extend2"
5725 [(set (match_operand:DI 0 "register_operand" "=r")
5726 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5728 (match_operand:SI 2 "small_int_operand" "I")))]
5729 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5731 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5732 return "sra\t%1, %2, %0";
5734 [(set_attr "type" "shift")])
5736 (define_expand "ashrdi3"
5737 [(set (match_operand:DI 0 "register_operand" "=r")
5738 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5739 (match_operand:SI 2 "arith_operand" "rI")))]
5740 "TARGET_ARCH64 || TARGET_V8PLUS"
5742 if (! TARGET_ARCH64)
5744 if (GET_CODE (operands[2]) == CONST_INT)
5745 FAIL; /* prefer generic code in this case */
5746 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5751 (define_insn "*ashrdi3_sp64"
5752 [(set (match_operand:DI 0 "register_operand" "=r")
5753 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5754 (match_operand:SI 2 "arith_operand" "rI")))]
5758 if (GET_CODE (operands[2]) == CONST_INT)
5759 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5760 return "srax\t%1, %2, %0";
5762 [(set_attr "type" "shift")])
5765 (define_insn "ashrdi3_v8plus"
5766 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5767 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5768 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5769 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5771 "* return output_v8plus_shift (operands, insn, \"srax\");"
5772 [(set_attr "type" "multi")
5773 (set_attr "length" "5,5,6")])
5775 (define_insn "lshrsi3"
5776 [(set (match_operand:SI 0 "register_operand" "=r")
5777 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5778 (match_operand:SI 2 "arith_operand" "rI")))]
5781 if (GET_CODE (operands[2]) == CONST_INT)
5782 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5783 return "srl\t%1, %2, %0";
5785 [(set_attr "type" "shift")])
5787 ;; This handles the case where
5788 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5789 ;; but combiner "simplifies" it for us.
5790 (define_insn "*lshrsi3_extend"
5791 [(set (match_operand:DI 0 "register_operand" "=r")
5792 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5793 (match_operand:SI 2 "arith_operand" "r")) 0)
5794 (match_operand 3 "const_int_operand" "")))]
5795 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5797 [(set_attr "type" "shift")])
5799 ;; This handles the case where
5800 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5801 ;; but combiner "simplifies" it for us.
5802 (define_insn "*lshrsi3_extend2"
5803 [(set (match_operand:DI 0 "register_operand" "=r")
5804 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5805 (match_operand 2 "small_int_operand" "I")
5807 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5809 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5810 return "srl\t%1, %2, %0";
5812 [(set_attr "type" "shift")])
5814 (define_expand "lshrdi3"
5815 [(set (match_operand:DI 0 "register_operand" "=r")
5816 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5817 (match_operand:SI 2 "arith_operand" "rI")))]
5818 "TARGET_ARCH64 || TARGET_V8PLUS"
5820 if (! TARGET_ARCH64)
5822 if (GET_CODE (operands[2]) == CONST_INT)
5824 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5829 (define_insn "*lshrdi3_sp64"
5830 [(set (match_operand:DI 0 "register_operand" "=r")
5831 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5832 (match_operand:SI 2 "arith_operand" "rI")))]
5835 if (GET_CODE (operands[2]) == CONST_INT)
5836 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5837 return "srlx\t%1, %2, %0";
5839 [(set_attr "type" "shift")])
5842 (define_insn "lshrdi3_v8plus"
5843 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5844 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5845 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5846 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5848 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5849 [(set_attr "type" "multi")
5850 (set_attr "length" "5,5,6")])
5853 [(set (match_operand:SI 0 "register_operand" "=r")
5854 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5856 (match_operand:SI 2 "small_int_operand" "I")))]
5857 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5859 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5860 return "srax\t%1, %2, %0";
5862 [(set_attr "type" "shift")])
5865 [(set (match_operand:SI 0 "register_operand" "=r")
5866 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5868 (match_operand:SI 2 "small_int_operand" "I")))]
5869 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5871 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5872 return "srlx\t%1, %2, %0";
5874 [(set_attr "type" "shift")])
5877 [(set (match_operand:SI 0 "register_operand" "=r")
5878 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5879 (match_operand:SI 2 "small_int_operand" "I")) 4)
5880 (match_operand:SI 3 "small_int_operand" "I")))]
5882 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5883 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5884 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5886 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5888 return "srax\t%1, %2, %0";
5890 [(set_attr "type" "shift")])
5893 [(set (match_operand:SI 0 "register_operand" "=r")
5894 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5895 (match_operand:SI 2 "small_int_operand" "I")) 4)
5896 (match_operand:SI 3 "small_int_operand" "I")))]
5898 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5899 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5900 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5902 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5904 return "srlx\t%1, %2, %0";
5906 [(set_attr "type" "shift")])
5909 ;; Unconditional and other jump instructions.
5912 [(set (pc) (label_ref (match_operand 0 "" "")))]
5914 "* return output_ubranch (operands[0], 0, insn);"
5915 [(set_attr "type" "uncond_branch")])
5917 (define_expand "tablejump"
5918 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5919 (use (label_ref (match_operand 1 "" "")))])]
5922 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5924 /* In pic mode, our address differences are against the base of the
5925 table. Add that base value back in; CSE ought to be able to combine
5926 the two address loads. */
5930 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5932 if (CASE_VECTOR_MODE != Pmode)
5933 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5934 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5935 operands[0] = memory_address (Pmode, tmp);
5939 (define_insn "*tablejump_sp32"
5940 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5941 (use (label_ref (match_operand 1 "" "")))]
5944 [(set_attr "type" "uncond_branch")])
5946 (define_insn "*tablejump_sp64"
5947 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5948 (use (label_ref (match_operand 1 "" "")))]
5951 [(set_attr "type" "uncond_branch")])
5954 ;; Jump to subroutine instructions.
5956 (define_expand "call"
5957 ;; Note that this expression is not used for generating RTL.
5958 ;; All the RTL is generated explicitly below.
5959 [(call (match_operand 0 "call_operand" "")
5960 (match_operand 3 "" "i"))]
5961 ;; operands[2] is next_arg_register
5962 ;; operands[3] is struct_value_size_rtx.
5967 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5969 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5971 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5973 /* This is really a PIC sequence. We want to represent
5974 it as a funny jump so its delay slots can be filled.
5976 ??? But if this really *is* a CALL, will not it clobber the
5977 call-clobbered registers? We lose this if it is a JUMP_INSN.
5978 Why cannot we have delay slots filled if it were a CALL? */
5980 /* We accept negative sizes for untyped calls. */
5981 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5986 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5988 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5994 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5995 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5999 fn_rtx = operands[0];
6001 /* We accept negative sizes for untyped calls. */
6002 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6003 sparc_emit_call_insn
6006 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6008 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6011 sparc_emit_call_insn
6014 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6015 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6023 ;; We can't use the same pattern for these two insns, because then registers
6024 ;; in the address may not be properly reloaded.
6026 (define_insn "*call_address_sp32"
6027 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6028 (match_operand 1 "" ""))
6029 (clobber (reg:SI 15))]
6030 ;;- Do not use operand 1 for most machines.
6033 [(set_attr "type" "call")])
6035 (define_insn "*call_symbolic_sp32"
6036 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6037 (match_operand 1 "" ""))
6038 (clobber (reg:SI 15))]
6039 ;;- Do not use operand 1 for most machines.
6042 [(set_attr "type" "call")])
6044 (define_insn "*call_address_sp64"
6045 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6046 (match_operand 1 "" ""))
6047 (clobber (reg:DI 15))]
6048 ;;- Do not use operand 1 for most machines.
6051 [(set_attr "type" "call")])
6053 (define_insn "*call_symbolic_sp64"
6054 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6055 (match_operand 1 "" ""))
6056 (clobber (reg:DI 15))]
6057 ;;- Do not use operand 1 for most machines.
6060 [(set_attr "type" "call")])
6062 ;; This is a call that wants a structure value.
6063 ;; There is no such critter for v9 (??? we may need one anyway).
6064 (define_insn "*call_address_struct_value_sp32"
6065 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6066 (match_operand 1 "" ""))
6067 (match_operand 2 "immediate_operand" "")
6068 (clobber (reg:SI 15))]
6069 ;;- Do not use operand 1 for most machines.
6070 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6072 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6073 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6075 [(set_attr "type" "call_no_delay_slot")
6076 (set_attr "length" "3")])
6078 ;; This is a call that wants a structure value.
6079 ;; There is no such critter for v9 (??? we may need one anyway).
6080 (define_insn "*call_symbolic_struct_value_sp32"
6081 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6082 (match_operand 1 "" ""))
6083 (match_operand 2 "immediate_operand" "")
6084 (clobber (reg:SI 15))]
6085 ;;- Do not use operand 1 for most machines.
6086 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6088 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6089 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6091 [(set_attr "type" "call_no_delay_slot")
6092 (set_attr "length" "3")])
6094 ;; This is a call that may want a structure value. This is used for
6096 (define_insn "*call_address_untyped_struct_value_sp32"
6097 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6098 (match_operand 1 "" ""))
6099 (match_operand 2 "immediate_operand" "")
6100 (clobber (reg:SI 15))]
6101 ;;- Do not use operand 1 for most machines.
6102 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6103 "call\t%a0, %1\n\t nop\n\tnop"
6104 [(set_attr "type" "call_no_delay_slot")
6105 (set_attr "length" "3")])
6107 ;; This is a call that may want a structure value. This is used for
6109 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6110 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6111 (match_operand 1 "" ""))
6112 (match_operand 2 "immediate_operand" "")
6113 (clobber (reg:SI 15))]
6114 ;;- Do not use operand 1 for most machines.
6115 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6116 "call\t%a0, %1\n\t nop\n\tnop"
6117 [(set_attr "type" "call_no_delay_slot")
6118 (set_attr "length" "3")])
6120 (define_expand "call_value"
6121 ;; Note that this expression is not used for generating RTL.
6122 ;; All the RTL is generated explicitly below.
6123 [(set (match_operand 0 "register_operand" "=rf")
6124 (call (match_operand 1 "" "")
6125 (match_operand 4 "" "")))]
6126 ;; operand 2 is stack_size_rtx
6127 ;; operand 3 is next_arg_register
6133 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6135 fn_rtx = operands[1];
6138 gen_rtx_SET (VOIDmode, operands[0],
6139 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6140 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6142 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6147 (define_insn "*call_value_address_sp32"
6148 [(set (match_operand 0 "" "=rf")
6149 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6150 (match_operand 2 "" "")))
6151 (clobber (reg:SI 15))]
6152 ;;- Do not use operand 2 for most machines.
6155 [(set_attr "type" "call")])
6157 (define_insn "*call_value_symbolic_sp32"
6158 [(set (match_operand 0 "" "=rf")
6159 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6160 (match_operand 2 "" "")))
6161 (clobber (reg:SI 15))]
6162 ;;- Do not use operand 2 for most machines.
6165 [(set_attr "type" "call")])
6167 (define_insn "*call_value_address_sp64"
6168 [(set (match_operand 0 "" "")
6169 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6170 (match_operand 2 "" "")))
6171 (clobber (reg:DI 15))]
6172 ;;- Do not use operand 2 for most machines.
6175 [(set_attr "type" "call")])
6177 (define_insn "*call_value_symbolic_sp64"
6178 [(set (match_operand 0 "" "")
6179 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6180 (match_operand 2 "" "")))
6181 (clobber (reg:DI 15))]
6182 ;;- Do not use operand 2 for most machines.
6185 [(set_attr "type" "call")])
6187 (define_expand "untyped_call"
6188 [(parallel [(call (match_operand 0 "" "")
6190 (match_operand:BLK 1 "memory_operand" "")
6191 (match_operand 2 "" "")])]
6194 rtx valreg1 = gen_rtx_REG (DImode, 8);
6195 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6196 rtx result = operands[1];
6198 /* Pass constm1 to indicate that it may expect a structure value, but
6199 we don't know what size it is. */
6200 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6202 /* Save the function value registers. */
6203 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6204 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6207 /* The optimizer does not know that the call sets the function value
6208 registers we stored in the result block. We avoid problems by
6209 claiming that all hard registers are used and clobbered at this
6211 emit_insn (gen_blockage ());
6216 ;; Tail call instructions.
6218 (define_expand "sibcall"
6219 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6224 (define_insn "*sibcall_symbolic_sp32"
6225 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6226 (match_operand 1 "" ""))
6229 "* return output_sibcall(insn, operands[0]);"
6230 [(set_attr "type" "sibcall")])
6232 (define_insn "*sibcall_symbolic_sp64"
6233 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6234 (match_operand 1 "" ""))
6237 "* return output_sibcall(insn, operands[0]);"
6238 [(set_attr "type" "sibcall")])
6240 (define_expand "sibcall_value"
6241 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6242 (call (match_operand 1 "" "") (const_int 0)))
6247 (define_insn "*sibcall_value_symbolic_sp32"
6248 [(set (match_operand 0 "" "=rf")
6249 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6250 (match_operand 2 "" "")))
6253 "* return output_sibcall(insn, operands[1]);"
6254 [(set_attr "type" "sibcall")])
6256 (define_insn "*sibcall_value_symbolic_sp64"
6257 [(set (match_operand 0 "" "")
6258 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6259 (match_operand 2 "" "")))
6262 "* return output_sibcall(insn, operands[1]);"
6263 [(set_attr "type" "sibcall")])
6266 ;; Special instructions.
6268 (define_expand "prologue"
6273 sparc_flat_expand_prologue ();
6275 sparc_expand_prologue ();
6279 ;; The "save register window" insn is modelled as follows. The dwarf2
6280 ;; information is manually added in emit_save_register_window in sparc.c.
6282 (define_insn "save_register_window_1"
6284 [(match_operand 0 "arith_operand" "rI")]
6287 "save\t%%sp, %0, %%sp"
6288 [(set_attr "type" "savew")])
6290 (define_expand "epilogue"
6295 sparc_flat_expand_epilogue (false);
6297 sparc_expand_epilogue (false);
6300 (define_expand "sibcall_epilogue"
6305 sparc_flat_expand_epilogue (false);
6307 sparc_expand_epilogue (false);
6311 (define_expand "eh_return"
6312 [(use (match_operand 0 "general_operand" ""))]
6315 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6316 emit_jump_insn (gen_eh_return_internal ());
6321 (define_insn_and_split "eh_return_internal"
6325 "epilogue_completed"
6329 sparc_flat_expand_epilogue (true);
6331 sparc_expand_epilogue (true);
6334 (define_expand "return"
6336 "sparc_can_use_return_insn_p ()"
6339 (define_insn "*return_internal"
6342 "* return output_return (insn);"
6343 [(set_attr "type" "return")
6344 (set (attr "length")
6345 (cond [(eq_attr "calls_eh_return" "true")
6346 (if_then_else (eq_attr "delayed_branch" "true")
6347 (if_then_else (ior (eq_attr "isa" "v9")
6348 (eq_attr "flat" "true"))
6351 (if_then_else (eq_attr "flat" "true")
6354 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6355 (if_then_else (eq_attr "empty_delay_slot" "true")
6358 (eq_attr "empty_delay_slot" "true")
6359 (if_then_else (eq_attr "delayed_branch" "true")
6364 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6365 ;; all of memory. This blocks insns from being moved across this point.
6367 (define_insn "blockage"
6368 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6371 [(set_attr "length" "0")])
6373 (define_expand "probe_stack"
6374 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6378 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6381 (define_insn "probe_stack_range<P:mode>"
6382 [(set (match_operand:P 0 "register_operand" "=r")
6383 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6384 (match_operand:P 2 "register_operand" "r")]
6385 UNSPECV_PROBE_STACK_RANGE))]
6387 "* return output_probe_stack_range (operands[0], operands[2]);"
6388 [(set_attr "type" "multi")])
6390 ;; Prepare to return any type including a structure value.
6392 (define_expand "untyped_return"
6393 [(match_operand:BLK 0 "memory_operand" "")
6394 (match_operand 1 "" "")]
6397 rtx valreg1 = gen_rtx_REG (DImode, 24);
6398 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6399 rtx result = operands[0];
6401 if (! TARGET_ARCH64)
6403 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6404 rtx value = gen_reg_rtx (SImode);
6406 /* Fetch the instruction where we will return to and see if it's an unimp
6407 instruction (the most significant 10 bits will be zero). If so,
6408 update the return address to skip the unimp instruction. */
6409 emit_move_insn (value,
6410 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6411 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6412 emit_insn (gen_update_return (rtnreg, value));
6415 /* Reload the function value registers. */
6416 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6417 emit_move_insn (valreg2,
6418 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6420 /* Put USE insns before the return. */
6424 /* Construct the return. */
6425 expand_naked_return ();
6430 ;; Adjust the return address conditionally. If the value of op1 is equal
6431 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6432 ;; This is technically *half* the check required by the 32-bit SPARC
6433 ;; psABI. This check only ensures that an "unimp" insn was written by
6434 ;; the caller, but doesn't check to see if the expected size matches
6435 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6436 ;; only used by the above code "untyped_return".
6438 (define_insn "update_return"
6439 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6440 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6443 if (flag_delayed_branch)
6444 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6446 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6448 [(set (attr "type") (const_string "multi"))
6449 (set (attr "length")
6450 (if_then_else (eq_attr "delayed_branch" "true")
6459 (define_expand "indirect_jump"
6460 [(set (pc) (match_operand 0 "address_operand" "p"))]
6464 (define_insn "*branch_sp32"
6465 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6468 [(set_attr "type" "uncond_branch")])
6470 (define_insn "*branch_sp64"
6471 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6474 [(set_attr "type" "uncond_branch")])
6476 (define_expand "save_stack_nonlocal"
6477 [(set (match_operand 0 "memory_operand" "")
6478 (match_operand 1 "register_operand" ""))
6479 (set (match_dup 2) (match_dup 3))]
6482 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6483 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6484 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6487 (define_expand "restore_stack_nonlocal"
6488 [(set (match_operand 0 "register_operand" "")
6489 (match_operand 1 "memory_operand" ""))]
6492 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6495 (define_expand "nonlocal_goto"
6496 [(match_operand 0 "general_operand" "")
6497 (match_operand 1 "general_operand" "")
6498 (match_operand 2 "memory_operand" "")
6499 (match_operand 3 "memory_operand" "")]
6502 rtx r_label = copy_to_reg (operands[1]);
6503 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6504 rtx r_fp = operands[3];
6505 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6507 /* We need to flush all the register windows so that their contents will
6508 be re-synchronized by the restore insn of the target function. */
6510 emit_insn (gen_flush_register_windows ());
6512 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6513 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6515 /* Restore frame pointer for containing function. */
6516 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6517 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6519 /* USE of hard_frame_pointer_rtx added for consistency;
6520 not clear if really needed. */
6521 emit_use (hard_frame_pointer_rtx);
6522 emit_use (stack_pointer_rtx);
6524 /* We need to smuggle the load of %i7 as it is a fixed register. */
6525 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6530 (define_insn "nonlocal_goto_internal"
6531 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6532 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6533 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6535 if (flag_delayed_branch)
6538 return "jmp\t%0\n\t ldx\t%1, %%i7";
6540 return "jmp\t%0\n\t ld\t%1, %%i7";
6545 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6547 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6550 [(set (attr "type") (const_string "multi"))
6551 (set (attr "length")
6552 (if_then_else (eq_attr "delayed_branch" "true")
6556 (define_expand "builtin_setjmp_receiver"
6557 [(label_ref (match_operand 0 "" ""))]
6560 load_got_register ();
6564 ;; Special insn to flush register windows.
6566 (define_insn "flush_register_windows"
6567 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6569 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6570 [(set_attr "type" "flushw")])
6572 ;; Special pattern for the FLUSH instruction.
6574 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6575 ; of the define_insn otherwise missing a mode. We make "flush", aka
6576 ; gen_flush, the default one since sparc_initialize_trampoline uses
6577 ; it on SImode mem values.
6579 (define_insn "flush"
6580 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6582 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6583 [(set_attr "type" "iflush")])
6585 (define_insn "flushdi"
6586 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6588 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6589 [(set_attr "type" "iflush")])
6592 ;; Find first set instructions.
6594 ;; The scan instruction searches from the most significant bit while ffs
6595 ;; searches from the least significant bit. The bit index and treatment of
6596 ;; zero also differ. It takes at least 7 instructions to get the proper
6597 ;; result. Here is an obvious 8 instruction sequence.
6600 (define_insn "ffssi2"
6601 [(set (match_operand:SI 0 "register_operand" "=&r")
6602 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6603 (clobber (match_scratch:SI 2 "=&r"))]
6604 "TARGET_SPARCLITE || TARGET_SPARCLET"
6606 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";
6608 [(set_attr "type" "multi")
6609 (set_attr "length" "8")])
6611 ;; ??? This should be a define expand, so that the extra instruction have
6612 ;; a chance of being optimized away.
6614 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6615 ;; does, but no one uses that and we don't have a switch for it.
6617 ;(define_insn "ffsdi2"
6618 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6619 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6620 ; (clobber (match_scratch:DI 2 "=&r"))]
6622 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6623 ; [(set_attr "type" "multi")
6624 ; (set_attr "length" "4")])
6628 ;; Peepholes go at the end.
6630 ;; Optimize consecutive loads or stores into ldd and std when possible.
6631 ;; The conditions in which we do this are very restricted and are
6632 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6635 [(set (match_operand:SI 0 "memory_operand" "")
6637 (set (match_operand:SI 1 "memory_operand" "")
6640 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6643 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6646 [(set (match_operand:SI 0 "memory_operand" "")
6648 (set (match_operand:SI 1 "memory_operand" "")
6651 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6654 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6657 [(set (match_operand:SI 0 "register_operand" "")
6658 (match_operand:SI 1 "memory_operand" ""))
6659 (set (match_operand:SI 2 "register_operand" "")
6660 (match_operand:SI 3 "memory_operand" ""))]
6661 "registers_ok_for_ldd_peep (operands[0], operands[2])
6662 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6665 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6666 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6669 [(set (match_operand:SI 0 "memory_operand" "")
6670 (match_operand:SI 1 "register_operand" ""))
6671 (set (match_operand:SI 2 "memory_operand" "")
6672 (match_operand:SI 3 "register_operand" ""))]
6673 "registers_ok_for_ldd_peep (operands[1], operands[3])
6674 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6677 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6678 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6681 [(set (match_operand:SF 0 "register_operand" "")
6682 (match_operand:SF 1 "memory_operand" ""))
6683 (set (match_operand:SF 2 "register_operand" "")
6684 (match_operand:SF 3 "memory_operand" ""))]
6685 "registers_ok_for_ldd_peep (operands[0], operands[2])
6686 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6689 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6690 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6693 [(set (match_operand:SF 0 "memory_operand" "")
6694 (match_operand:SF 1 "register_operand" ""))
6695 (set (match_operand:SF 2 "memory_operand" "")
6696 (match_operand:SF 3 "register_operand" ""))]
6697 "registers_ok_for_ldd_peep (operands[1], operands[3])
6698 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6701 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6702 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6705 [(set (match_operand:SI 0 "register_operand" "")
6706 (match_operand:SI 1 "memory_operand" ""))
6707 (set (match_operand:SI 2 "register_operand" "")
6708 (match_operand:SI 3 "memory_operand" ""))]
6709 "registers_ok_for_ldd_peep (operands[2], operands[0])
6710 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6713 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6714 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6717 [(set (match_operand:SI 0 "memory_operand" "")
6718 (match_operand:SI 1 "register_operand" ""))
6719 (set (match_operand:SI 2 "memory_operand" "")
6720 (match_operand:SI 3 "register_operand" ""))]
6721 "registers_ok_for_ldd_peep (operands[3], operands[1])
6722 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6725 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6726 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6730 [(set (match_operand:SF 0 "register_operand" "")
6731 (match_operand:SF 1 "memory_operand" ""))
6732 (set (match_operand:SF 2 "register_operand" "")
6733 (match_operand:SF 3 "memory_operand" ""))]
6734 "registers_ok_for_ldd_peep (operands[2], operands[0])
6735 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6738 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6739 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6742 [(set (match_operand:SF 0 "memory_operand" "")
6743 (match_operand:SF 1 "register_operand" ""))
6744 (set (match_operand:SF 2 "memory_operand" "")
6745 (match_operand:SF 3 "register_operand" ""))]
6746 "registers_ok_for_ldd_peep (operands[3], operands[1])
6747 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6750 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6751 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6753 ;; Optimize the case of following a reg-reg move with a test
6754 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6755 ;; This can result from a float to fix conversion.
6758 [(set (match_operand:SI 0 "register_operand" "")
6759 (match_operand:SI 1 "register_operand" ""))
6761 (compare:CC (match_operand:SI 2 "register_operand" "")
6763 "(rtx_equal_p (operands[2], operands[0])
6764 || rtx_equal_p (operands[2], operands[1]))
6765 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6766 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6767 [(parallel [(set (match_dup 0) (match_dup 1))
6769 (compare:CC (match_dup 1) (const_int 0)))])]
6773 [(set (match_operand:DI 0 "register_operand" "")
6774 (match_operand:DI 1 "register_operand" ""))
6776 (compare:CCX (match_operand:DI 2 "register_operand" "")
6779 && (rtx_equal_p (operands[2], operands[0])
6780 || rtx_equal_p (operands[2], operands[1]))
6781 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6782 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6783 [(parallel [(set (match_dup 0) (match_dup 1))
6785 (compare:CCX (match_dup 1) (const_int 0)))])]
6789 ;; Prefetch instructions.
6791 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6792 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6793 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6795 (define_expand "prefetch"
6796 [(match_operand 0 "address_operand" "")
6797 (match_operand 1 "const_int_operand" "")
6798 (match_operand 2 "const_int_operand" "")]
6802 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6804 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6808 (define_insn "prefetch_64"
6809 [(prefetch (match_operand:DI 0 "address_operand" "p")
6810 (match_operand:DI 1 "const_int_operand" "n")
6811 (match_operand:DI 2 "const_int_operand" "n"))]
6814 static const char * const prefetch_instr[2][2] = {
6816 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6817 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6820 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6821 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6824 int read_or_write = INTVAL (operands[1]);
6825 int locality = INTVAL (operands[2]);
6827 gcc_assert (read_or_write == 0 || read_or_write == 1);
6828 gcc_assert (locality >= 0 && locality < 4);
6829 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6831 [(set_attr "type" "load")])
6833 (define_insn "prefetch_32"
6834 [(prefetch (match_operand:SI 0 "address_operand" "p")
6835 (match_operand:SI 1 "const_int_operand" "n")
6836 (match_operand:SI 2 "const_int_operand" "n"))]
6839 static const char * const prefetch_instr[2][2] = {
6841 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6842 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6845 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6846 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6849 int read_or_write = INTVAL (operands[1]);
6850 int locality = INTVAL (operands[2]);
6852 gcc_assert (read_or_write == 0 || read_or_write == 1);
6853 gcc_assert (locality >= 0 && locality < 4);
6854 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6856 [(set_attr "type" "load")])
6859 ;; Trap instructions.
6862 [(trap_if (const_int 1) (const_int 5))]
6865 [(set_attr "type" "trap")])
6867 (define_expand "ctrapsi4"
6868 [(trap_if (match_operator 0 "noov_compare_operator"
6869 [(match_operand:SI 1 "compare_operand" "")
6870 (match_operand:SI 2 "arith_operand" "")])
6871 (match_operand 3 ""))]
6873 "operands[1] = gen_compare_reg (operands[0]);
6874 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6876 operands[2] = const0_rtx;")
6878 (define_expand "ctrapdi4"
6879 [(trap_if (match_operator 0 "noov_compare_operator"
6880 [(match_operand:DI 1 "compare_operand" "")
6881 (match_operand:DI 2 "arith_operand" "")])
6882 (match_operand 3 ""))]
6884 "operands[1] = gen_compare_reg (operands[0]);
6885 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6887 operands[2] = const0_rtx;")
6891 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6892 (match_operand:SI 1 "arith_operand" "rM"))]
6896 return "t%C0\t%%icc, %1";
6900 [(set_attr "type" "trap")])
6903 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6904 (match_operand:SI 1 "arith_operand" "rM"))]
6907 [(set_attr "type" "trap")])
6910 ;; TLS support instructions.
6912 (define_insn "tgd_hi22"
6913 [(set (match_operand:SI 0 "register_operand" "=r")
6914 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6917 "sethi\\t%%tgd_hi22(%a1), %0")
6919 (define_insn "tgd_lo10"
6920 [(set (match_operand:SI 0 "register_operand" "=r")
6921 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6922 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6925 "add\\t%1, %%tgd_lo10(%a2), %0")
6927 (define_insn "tgd_add32"
6928 [(set (match_operand:SI 0 "register_operand" "=r")
6929 (plus:SI (match_operand:SI 1 "register_operand" "r")
6930 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6931 (match_operand 3 "tgd_symbolic_operand" "")]
6933 "TARGET_TLS && TARGET_ARCH32"
6934 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6936 (define_insn "tgd_add64"
6937 [(set (match_operand:DI 0 "register_operand" "=r")
6938 (plus:DI (match_operand:DI 1 "register_operand" "r")
6939 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6940 (match_operand 3 "tgd_symbolic_operand" "")]
6942 "TARGET_TLS && TARGET_ARCH64"
6943 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6945 (define_insn "tgd_call32"
6946 [(set (match_operand 0 "register_operand" "=r")
6947 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6948 (match_operand 2 "tgd_symbolic_operand" "")]
6950 (match_operand 3 "" "")))
6951 (clobber (reg:SI 15))]
6952 "TARGET_TLS && TARGET_ARCH32"
6953 "call\t%a1, %%tgd_call(%a2)%#"
6954 [(set_attr "type" "call")])
6956 (define_insn "tgd_call64"
6957 [(set (match_operand 0 "register_operand" "=r")
6958 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6959 (match_operand 2 "tgd_symbolic_operand" "")]
6961 (match_operand 3 "" "")))
6962 (clobber (reg:DI 15))]
6963 "TARGET_TLS && TARGET_ARCH64"
6964 "call\t%a1, %%tgd_call(%a2)%#"
6965 [(set_attr "type" "call")])
6967 (define_insn "tldm_hi22"
6968 [(set (match_operand:SI 0 "register_operand" "=r")
6969 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6971 "sethi\\t%%tldm_hi22(%&), %0")
6973 (define_insn "tldm_lo10"
6974 [(set (match_operand:SI 0 "register_operand" "=r")
6975 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6976 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6978 "add\\t%1, %%tldm_lo10(%&), %0")
6980 (define_insn "tldm_add32"
6981 [(set (match_operand:SI 0 "register_operand" "=r")
6982 (plus:SI (match_operand:SI 1 "register_operand" "r")
6983 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6985 "TARGET_TLS && TARGET_ARCH32"
6986 "add\\t%1, %2, %0, %%tldm_add(%&)")
6988 (define_insn "tldm_add64"
6989 [(set (match_operand:DI 0 "register_operand" "=r")
6990 (plus:DI (match_operand:DI 1 "register_operand" "r")
6991 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6993 "TARGET_TLS && TARGET_ARCH64"
6994 "add\\t%1, %2, %0, %%tldm_add(%&)")
6996 (define_insn "tldm_call32"
6997 [(set (match_operand 0 "register_operand" "=r")
6998 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7000 (match_operand 2 "" "")))
7001 (clobber (reg:SI 15))]
7002 "TARGET_TLS && TARGET_ARCH32"
7003 "call\t%a1, %%tldm_call(%&)%#"
7004 [(set_attr "type" "call")])
7006 (define_insn "tldm_call64"
7007 [(set (match_operand 0 "register_operand" "=r")
7008 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7010 (match_operand 2 "" "")))
7011 (clobber (reg:DI 15))]
7012 "TARGET_TLS && TARGET_ARCH64"
7013 "call\t%a1, %%tldm_call(%&)%#"
7014 [(set_attr "type" "call")])
7016 (define_insn "tldo_hix22"
7017 [(set (match_operand:SI 0 "register_operand" "=r")
7018 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7021 "sethi\\t%%tldo_hix22(%a1), %0")
7023 (define_insn "tldo_lox10"
7024 [(set (match_operand:SI 0 "register_operand" "=r")
7025 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7026 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7029 "xor\\t%1, %%tldo_lox10(%a2), %0")
7031 (define_insn "tldo_add32"
7032 [(set (match_operand:SI 0 "register_operand" "=r")
7033 (plus:SI (match_operand:SI 1 "register_operand" "r")
7034 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7035 (match_operand 3 "tld_symbolic_operand" "")]
7037 "TARGET_TLS && TARGET_ARCH32"
7038 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7040 (define_insn "tldo_add64"
7041 [(set (match_operand:DI 0 "register_operand" "=r")
7042 (plus:DI (match_operand:DI 1 "register_operand" "r")
7043 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7044 (match_operand 3 "tld_symbolic_operand" "")]
7046 "TARGET_TLS && TARGET_ARCH64"
7047 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7049 (define_insn "tie_hi22"
7050 [(set (match_operand:SI 0 "register_operand" "=r")
7051 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7054 "sethi\\t%%tie_hi22(%a1), %0")
7056 (define_insn "tie_lo10"
7057 [(set (match_operand:SI 0 "register_operand" "=r")
7058 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7059 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7062 "add\\t%1, %%tie_lo10(%a2), %0")
7064 (define_insn "tie_ld32"
7065 [(set (match_operand:SI 0 "register_operand" "=r")
7066 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7067 (match_operand:SI 2 "register_operand" "r")
7068 (match_operand 3 "tie_symbolic_operand" "")]
7070 "TARGET_TLS && TARGET_ARCH32"
7071 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7072 [(set_attr "type" "load")])
7074 (define_insn "tie_ld64"
7075 [(set (match_operand:DI 0 "register_operand" "=r")
7076 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7077 (match_operand:SI 2 "register_operand" "r")
7078 (match_operand 3 "tie_symbolic_operand" "")]
7080 "TARGET_TLS && TARGET_ARCH64"
7081 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7082 [(set_attr "type" "load")])
7084 (define_insn "tie_add32"
7085 [(set (match_operand:SI 0 "register_operand" "=r")
7086 (plus:SI (match_operand:SI 1 "register_operand" "r")
7087 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7088 (match_operand 3 "tie_symbolic_operand" "")]
7090 "TARGET_SUN_TLS && TARGET_ARCH32"
7091 "add\\t%1, %2, %0, %%tie_add(%a3)")
7093 (define_insn "tie_add64"
7094 [(set (match_operand:DI 0 "register_operand" "=r")
7095 (plus:DI (match_operand:DI 1 "register_operand" "r")
7096 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7097 (match_operand 3 "tie_symbolic_operand" "")]
7099 "TARGET_SUN_TLS && TARGET_ARCH64"
7100 "add\\t%1, %2, %0, %%tie_add(%a3)")
7102 (define_insn "tle_hix22_sp32"
7103 [(set (match_operand:SI 0 "register_operand" "=r")
7104 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7106 "TARGET_TLS && TARGET_ARCH32"
7107 "sethi\\t%%tle_hix22(%a1), %0")
7109 (define_insn "tle_lox10_sp32"
7110 [(set (match_operand:SI 0 "register_operand" "=r")
7111 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7112 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7114 "TARGET_TLS && TARGET_ARCH32"
7115 "xor\\t%1, %%tle_lox10(%a2), %0")
7117 (define_insn "tle_hix22_sp64"
7118 [(set (match_operand:DI 0 "register_operand" "=r")
7119 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7121 "TARGET_TLS && TARGET_ARCH64"
7122 "sethi\\t%%tle_hix22(%a1), %0")
7124 (define_insn "tle_lox10_sp64"
7125 [(set (match_operand:DI 0 "register_operand" "=r")
7126 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7127 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7129 "TARGET_TLS && TARGET_ARCH64"
7130 "xor\\t%1, %%tle_lox10(%a2), %0")
7132 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7133 (define_insn "*tldo_ldub_sp32"
7134 [(set (match_operand:QI 0 "register_operand" "=r")
7135 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7136 (match_operand 3 "tld_symbolic_operand" "")]
7138 (match_operand:SI 1 "register_operand" "r"))))]
7139 "TARGET_TLS && TARGET_ARCH32"
7140 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7141 [(set_attr "type" "load")
7142 (set_attr "us3load_type" "3cycle")])
7144 (define_insn "*tldo_ldub1_sp32"
7145 [(set (match_operand:HI 0 "register_operand" "=r")
7146 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7147 (match_operand 3 "tld_symbolic_operand" "")]
7149 (match_operand:SI 1 "register_operand" "r")))))]
7150 "TARGET_TLS && TARGET_ARCH32"
7151 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7152 [(set_attr "type" "load")
7153 (set_attr "us3load_type" "3cycle")])
7155 (define_insn "*tldo_ldub2_sp32"
7156 [(set (match_operand:SI 0 "register_operand" "=r")
7157 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7158 (match_operand 3 "tld_symbolic_operand" "")]
7160 (match_operand:SI 1 "register_operand" "r")))))]
7161 "TARGET_TLS && TARGET_ARCH32"
7162 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7163 [(set_attr "type" "load")
7164 (set_attr "us3load_type" "3cycle")])
7166 (define_insn "*tldo_ldsb1_sp32"
7167 [(set (match_operand:HI 0 "register_operand" "=r")
7168 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7169 (match_operand 3 "tld_symbolic_operand" "")]
7171 (match_operand:SI 1 "register_operand" "r")))))]
7172 "TARGET_TLS && TARGET_ARCH32"
7173 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7174 [(set_attr "type" "sload")
7175 (set_attr "us3load_type" "3cycle")])
7177 (define_insn "*tldo_ldsb2_sp32"
7178 [(set (match_operand:SI 0 "register_operand" "=r")
7179 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7180 (match_operand 3 "tld_symbolic_operand" "")]
7182 (match_operand:SI 1 "register_operand" "r")))))]
7183 "TARGET_TLS && TARGET_ARCH32"
7184 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7185 [(set_attr "type" "sload")
7186 (set_attr "us3load_type" "3cycle")])
7188 (define_insn "*tldo_ldub_sp64"
7189 [(set (match_operand:QI 0 "register_operand" "=r")
7190 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7191 (match_operand 3 "tld_symbolic_operand" "")]
7193 (match_operand:DI 1 "register_operand" "r"))))]
7194 "TARGET_TLS && TARGET_ARCH64"
7195 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7196 [(set_attr "type" "load")
7197 (set_attr "us3load_type" "3cycle")])
7199 (define_insn "*tldo_ldub1_sp64"
7200 [(set (match_operand:HI 0 "register_operand" "=r")
7201 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7202 (match_operand 3 "tld_symbolic_operand" "")]
7204 (match_operand:DI 1 "register_operand" "r")))))]
7205 "TARGET_TLS && TARGET_ARCH64"
7206 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7207 [(set_attr "type" "load")
7208 (set_attr "us3load_type" "3cycle")])
7210 (define_insn "*tldo_ldub2_sp64"
7211 [(set (match_operand:SI 0 "register_operand" "=r")
7212 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7213 (match_operand 3 "tld_symbolic_operand" "")]
7215 (match_operand:DI 1 "register_operand" "r")))))]
7216 "TARGET_TLS && TARGET_ARCH64"
7217 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7218 [(set_attr "type" "load")
7219 (set_attr "us3load_type" "3cycle")])
7221 (define_insn "*tldo_ldub3_sp64"
7222 [(set (match_operand:DI 0 "register_operand" "=r")
7223 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7224 (match_operand 3 "tld_symbolic_operand" "")]
7226 (match_operand:DI 1 "register_operand" "r")))))]
7227 "TARGET_TLS && TARGET_ARCH64"
7228 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7229 [(set_attr "type" "load")
7230 (set_attr "us3load_type" "3cycle")])
7232 (define_insn "*tldo_ldsb1_sp64"
7233 [(set (match_operand:HI 0 "register_operand" "=r")
7234 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7235 (match_operand 3 "tld_symbolic_operand" "")]
7237 (match_operand:DI 1 "register_operand" "r")))))]
7238 "TARGET_TLS && TARGET_ARCH64"
7239 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7240 [(set_attr "type" "sload")
7241 (set_attr "us3load_type" "3cycle")])
7243 (define_insn "*tldo_ldsb2_sp64"
7244 [(set (match_operand:SI 0 "register_operand" "=r")
7245 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7246 (match_operand 3 "tld_symbolic_operand" "")]
7248 (match_operand:DI 1 "register_operand" "r")))))]
7249 "TARGET_TLS && TARGET_ARCH64"
7250 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7251 [(set_attr "type" "sload")
7252 (set_attr "us3load_type" "3cycle")])
7254 (define_insn "*tldo_ldsb3_sp64"
7255 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7257 (match_operand 3 "tld_symbolic_operand" "")]
7259 (match_operand:DI 1 "register_operand" "r")))))]
7260 "TARGET_TLS && TARGET_ARCH64"
7261 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7262 [(set_attr "type" "sload")
7263 (set_attr "us3load_type" "3cycle")])
7265 (define_insn "*tldo_lduh_sp32"
7266 [(set (match_operand:HI 0 "register_operand" "=r")
7267 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7268 (match_operand 3 "tld_symbolic_operand" "")]
7270 (match_operand:SI 1 "register_operand" "r"))))]
7271 "TARGET_TLS && TARGET_ARCH32"
7272 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7273 [(set_attr "type" "load")
7274 (set_attr "us3load_type" "3cycle")])
7276 (define_insn "*tldo_lduh1_sp32"
7277 [(set (match_operand:SI 0 "register_operand" "=r")
7278 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7279 (match_operand 3 "tld_symbolic_operand" "")]
7281 (match_operand:SI 1 "register_operand" "r")))))]
7282 "TARGET_TLS && TARGET_ARCH32"
7283 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7284 [(set_attr "type" "load")
7285 (set_attr "us3load_type" "3cycle")])
7287 (define_insn "*tldo_ldsh1_sp32"
7288 [(set (match_operand:SI 0 "register_operand" "=r")
7289 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7290 (match_operand 3 "tld_symbolic_operand" "")]
7292 (match_operand:SI 1 "register_operand" "r")))))]
7293 "TARGET_TLS && TARGET_ARCH32"
7294 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7295 [(set_attr "type" "sload")
7296 (set_attr "us3load_type" "3cycle")])
7298 (define_insn "*tldo_lduh_sp64"
7299 [(set (match_operand:HI 0 "register_operand" "=r")
7300 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7301 (match_operand 3 "tld_symbolic_operand" "")]
7303 (match_operand:DI 1 "register_operand" "r"))))]
7304 "TARGET_TLS && TARGET_ARCH64"
7305 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7306 [(set_attr "type" "load")
7307 (set_attr "us3load_type" "3cycle")])
7309 (define_insn "*tldo_lduh1_sp64"
7310 [(set (match_operand:SI 0 "register_operand" "=r")
7311 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7312 (match_operand 3 "tld_symbolic_operand" "")]
7314 (match_operand:DI 1 "register_operand" "r")))))]
7315 "TARGET_TLS && TARGET_ARCH64"
7316 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7317 [(set_attr "type" "load")
7318 (set_attr "us3load_type" "3cycle")])
7320 (define_insn "*tldo_lduh2_sp64"
7321 [(set (match_operand:DI 0 "register_operand" "=r")
7322 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7323 (match_operand 3 "tld_symbolic_operand" "")]
7325 (match_operand:DI 1 "register_operand" "r")))))]
7326 "TARGET_TLS && TARGET_ARCH64"
7327 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7328 [(set_attr "type" "load")
7329 (set_attr "us3load_type" "3cycle")])
7331 (define_insn "*tldo_ldsh1_sp64"
7332 [(set (match_operand:SI 0 "register_operand" "=r")
7333 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7334 (match_operand 3 "tld_symbolic_operand" "")]
7336 (match_operand:DI 1 "register_operand" "r")))))]
7337 "TARGET_TLS && TARGET_ARCH64"
7338 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7339 [(set_attr "type" "sload")
7340 (set_attr "us3load_type" "3cycle")])
7342 (define_insn "*tldo_ldsh2_sp64"
7343 [(set (match_operand:DI 0 "register_operand" "=r")
7344 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7345 (match_operand 3 "tld_symbolic_operand" "")]
7347 (match_operand:DI 1 "register_operand" "r")))))]
7348 "TARGET_TLS && TARGET_ARCH64"
7349 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7350 [(set_attr "type" "sload")
7351 (set_attr "us3load_type" "3cycle")])
7353 (define_insn "*tldo_lduw_sp32"
7354 [(set (match_operand:SI 0 "register_operand" "=r")
7355 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7356 (match_operand 3 "tld_symbolic_operand" "")]
7358 (match_operand:SI 1 "register_operand" "r"))))]
7359 "TARGET_TLS && TARGET_ARCH32"
7360 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7361 [(set_attr "type" "load")])
7363 (define_insn "*tldo_lduw_sp64"
7364 [(set (match_operand:SI 0 "register_operand" "=r")
7365 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7366 (match_operand 3 "tld_symbolic_operand" "")]
7368 (match_operand:DI 1 "register_operand" "r"))))]
7369 "TARGET_TLS && TARGET_ARCH64"
7370 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7371 [(set_attr "type" "load")])
7373 (define_insn "*tldo_lduw1_sp64"
7374 [(set (match_operand:DI 0 "register_operand" "=r")
7375 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7376 (match_operand 3 "tld_symbolic_operand" "")]
7378 (match_operand:DI 1 "register_operand" "r")))))]
7379 "TARGET_TLS && TARGET_ARCH64"
7380 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7381 [(set_attr "type" "load")])
7383 (define_insn "*tldo_ldsw1_sp64"
7384 [(set (match_operand:DI 0 "register_operand" "=r")
7385 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7386 (match_operand 3 "tld_symbolic_operand" "")]
7388 (match_operand:DI 1 "register_operand" "r")))))]
7389 "TARGET_TLS && TARGET_ARCH64"
7390 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7391 [(set_attr "type" "sload")
7392 (set_attr "us3load_type" "3cycle")])
7394 (define_insn "*tldo_ldx_sp64"
7395 [(set (match_operand:DI 0 "register_operand" "=r")
7396 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7397 (match_operand 3 "tld_symbolic_operand" "")]
7399 (match_operand:DI 1 "register_operand" "r"))))]
7400 "TARGET_TLS && TARGET_ARCH64"
7401 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7402 [(set_attr "type" "load")])
7404 (define_insn "*tldo_stb_sp32"
7405 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7406 (match_operand 3 "tld_symbolic_operand" "")]
7408 (match_operand:SI 1 "register_operand" "r")))
7409 (match_operand:QI 0 "register_operand" "=r"))]
7410 "TARGET_TLS && TARGET_ARCH32"
7411 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7412 [(set_attr "type" "store")])
7414 (define_insn "*tldo_stb_sp64"
7415 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7416 (match_operand 3 "tld_symbolic_operand" "")]
7418 (match_operand:DI 1 "register_operand" "r")))
7419 (match_operand:QI 0 "register_operand" "=r"))]
7420 "TARGET_TLS && TARGET_ARCH64"
7421 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7422 [(set_attr "type" "store")])
7424 (define_insn "*tldo_sth_sp32"
7425 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7426 (match_operand 3 "tld_symbolic_operand" "")]
7428 (match_operand:SI 1 "register_operand" "r")))
7429 (match_operand:HI 0 "register_operand" "=r"))]
7430 "TARGET_TLS && TARGET_ARCH32"
7431 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7432 [(set_attr "type" "store")])
7434 (define_insn "*tldo_sth_sp64"
7435 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7436 (match_operand 3 "tld_symbolic_operand" "")]
7438 (match_operand:DI 1 "register_operand" "r")))
7439 (match_operand:HI 0 "register_operand" "=r"))]
7440 "TARGET_TLS && TARGET_ARCH64"
7441 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7442 [(set_attr "type" "store")])
7444 (define_insn "*tldo_stw_sp32"
7445 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7446 (match_operand 3 "tld_symbolic_operand" "")]
7448 (match_operand:SI 1 "register_operand" "r")))
7449 (match_operand:SI 0 "register_operand" "=r"))]
7450 "TARGET_TLS && TARGET_ARCH32"
7451 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7452 [(set_attr "type" "store")])
7454 (define_insn "*tldo_stw_sp64"
7455 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7456 (match_operand 3 "tld_symbolic_operand" "")]
7458 (match_operand:DI 1 "register_operand" "r")))
7459 (match_operand:SI 0 "register_operand" "=r"))]
7460 "TARGET_TLS && TARGET_ARCH64"
7461 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7462 [(set_attr "type" "store")])
7464 (define_insn "*tldo_stx_sp64"
7465 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7466 (match_operand 3 "tld_symbolic_operand" "")]
7468 (match_operand:DI 1 "register_operand" "r")))
7469 (match_operand:DI 0 "register_operand" "=r"))]
7470 "TARGET_TLS && TARGET_ARCH64"
7471 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7472 [(set_attr "type" "store")])
7475 ;; Stack protector instructions.
7477 (define_expand "stack_protect_set"
7478 [(match_operand 0 "memory_operand" "")
7479 (match_operand 1 "memory_operand" "")]
7482 #ifdef TARGET_THREAD_SSP_OFFSET
7483 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7484 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7485 operands[1] = gen_rtx_MEM (Pmode, addr);
7488 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7490 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7494 (define_insn "stack_protect_setsi"
7495 [(set (match_operand:SI 0 "memory_operand" "=m")
7496 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7497 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7499 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7500 [(set_attr "type" "multi")
7501 (set_attr "length" "3")])
7503 (define_insn "stack_protect_setdi"
7504 [(set (match_operand:DI 0 "memory_operand" "=m")
7505 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7506 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7508 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7509 [(set_attr "type" "multi")
7510 (set_attr "length" "3")])
7512 (define_expand "stack_protect_test"
7513 [(match_operand 0 "memory_operand" "")
7514 (match_operand 1 "memory_operand" "")
7515 (match_operand 2 "" "")]
7519 #ifdef TARGET_THREAD_SSP_OFFSET
7520 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7521 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7522 operands[1] = gen_rtx_MEM (Pmode, addr);
7526 result = gen_reg_rtx (Pmode);
7527 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7528 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7529 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7533 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7534 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7535 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7536 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7541 (define_insn "stack_protect_testsi"
7543 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7544 (match_operand:SI 1 "memory_operand" "m")]
7546 (set (match_scratch:SI 3 "=r") (const_int 0))
7547 (clobber (match_scratch:SI 2 "=&r"))]
7549 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7550 [(set_attr "type" "multi")
7551 (set_attr "length" "4")])
7553 (define_insn "stack_protect_testdi"
7554 [(set (match_operand:DI 0 "register_operand" "=&r")
7555 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7556 (match_operand:DI 2 "memory_operand" "m")]
7558 (set (match_scratch:DI 3 "=r") (const_int 0))]
7560 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7561 [(set_attr "type" "multi")
7562 (set_attr "length" "4")])
7565 ;; Vector instructions.
7567 (define_insn "addv2si3"
7568 [(set (match_operand:V2SI 0 "register_operand" "=e")
7569 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7570 (match_operand:V2SI 2 "register_operand" "e")))]
7572 "fpadd32\t%1, %2, %0"
7573 [(set_attr "type" "fga")
7574 (set_attr "fptype" "double")])
7576 (define_insn "addv4hi3"
7577 [(set (match_operand:V4HI 0 "register_operand" "=e")
7578 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7579 (match_operand:V4HI 2 "register_operand" "e")))]
7581 "fpadd16\t%1, %2, %0"
7582 [(set_attr "type" "fga")
7583 (set_attr "fptype" "double")])
7585 ;; fpadd32s is emitted by the addsi3 pattern.
7587 (define_insn "addv2hi3"
7588 [(set (match_operand:V2HI 0 "register_operand" "=f")
7589 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7590 (match_operand:V2HI 2 "register_operand" "f")))]
7592 "fpadd16s\t%1, %2, %0"
7593 [(set_attr "type" "fga")
7594 (set_attr "fptype" "single")])
7596 (define_insn "subv2si3"
7597 [(set (match_operand:V2SI 0 "register_operand" "=e")
7598 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7599 (match_operand:V2SI 2 "register_operand" "e")))]
7601 "fpsub32\t%1, %2, %0"
7602 [(set_attr "type" "fga")
7603 (set_attr "fptype" "double")])
7605 (define_insn "subv4hi3"
7606 [(set (match_operand:V4HI 0 "register_operand" "=e")
7607 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7608 (match_operand:V4HI 2 "register_operand" "e")))]
7610 "fpsub16\t%1, %2, %0"
7611 [(set_attr "type" "fga")
7612 (set_attr "fptype" "double")])
7614 ;; fpsub32s is emitted by the subsi3 pattern.
7616 (define_insn "subv2hi3"
7617 [(set (match_operand:V2HI 0 "register_operand" "=f")
7618 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7619 (match_operand:V2HI 2 "register_operand" "f")))]
7621 "fpsub16s\t%1, %2, %0"
7622 [(set_attr "type" "fga")
7623 (set_attr "fptype" "single")])
7625 ;; All other logical instructions have integer equivalents so they
7626 ;; are defined together.
7628 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7630 (define_insn "*nand<V64:mode>_vis"
7631 [(set (match_operand:V64 0 "register_operand" "=e")
7632 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7633 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7636 [(set_attr "type" "fga")
7637 (set_attr "fptype" "double")])
7639 (define_insn "*nand<V32:mode>_vis"
7640 [(set (match_operand:V32 0 "register_operand" "=f")
7641 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7642 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7644 "fnands\t%1, %2, %0"
7645 [(set_attr "type" "fga")
7646 (set_attr "fptype" "single")])
7648 ;; Hard to generate VIS instructions. We have builtins for these.
7650 (define_insn "fpack16_vis"
7651 [(set (match_operand:V4QI 0 "register_operand" "=f")
7652 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7656 [(set_attr "type" "fga")
7657 (set_attr "fptype" "double")])
7659 (define_insn "fpackfix_vis"
7660 [(set (match_operand:V2HI 0 "register_operand" "=f")
7661 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7665 [(set_attr "type" "fga")
7666 (set_attr "fptype" "double")])
7668 (define_insn "fpack32_vis"
7669 [(set (match_operand:V8QI 0 "register_operand" "=e")
7670 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7671 (match_operand:V8QI 2 "register_operand" "e")]
7674 "fpack32\t%1, %2, %0"
7675 [(set_attr "type" "fga")
7676 (set_attr "fptype" "double")])
7678 (define_insn "fexpand_vis"
7679 [(set (match_operand:V4HI 0 "register_operand" "=e")
7680 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7684 [(set_attr "type" "fga")
7685 (set_attr "fptype" "double")])
7687 ;; It may be possible to describe this operation as (1 indexed):
7688 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7689 ;; 1,5,10,14,19,23,28,32)
7690 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7691 ;; because vec_merge expects all the operands to be of the same type.
7692 (define_insn "fpmerge_vis"
7693 [(set (match_operand:V8QI 0 "register_operand" "=e")
7694 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7695 (match_operand:V4QI 2 "register_operand" "f")]
7698 "fpmerge\t%1, %2, %0"
7699 [(set_attr "type" "fga")
7700 (set_attr "fptype" "double")])
7702 ;; Partitioned multiply instructions
7703 (define_insn "fmul8x16_vis"
7704 [(set (match_operand:V4HI 0 "register_operand" "=e")
7705 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7706 (match_operand:V4HI 2 "register_operand" "e")))]
7708 "fmul8x16\t%1, %2, %0"
7709 [(set_attr "type" "fpmul")
7710 (set_attr "fptype" "double")])
7712 ;; Only one of the following two insns can be a multiply.
7713 (define_insn "fmul8x16au_vis"
7714 [(set (match_operand:V4HI 0 "register_operand" "=e")
7715 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7716 (match_operand:V2HI 2 "register_operand" "f")))]
7718 "fmul8x16au\t%1, %2, %0"
7719 [(set_attr "type" "fpmul")
7720 (set_attr "fptype" "double")])
7722 (define_insn "fmul8x16al_vis"
7723 [(set (match_operand:V4HI 0 "register_operand" "=e")
7724 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7725 (match_operand:V2HI 2 "register_operand" "f")]
7728 "fmul8x16al\t%1, %2, %0"
7729 [(set_attr "type" "fpmul")
7730 (set_attr "fptype" "double")])
7732 ;; Only one of the following two insns can be a multiply.
7733 (define_insn "fmul8sux16_vis"
7734 [(set (match_operand:V4HI 0 "register_operand" "=e")
7735 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7736 (match_operand:V4HI 2 "register_operand" "e")))]
7738 "fmul8sux16\t%1, %2, %0"
7739 [(set_attr "type" "fpmul")
7740 (set_attr "fptype" "double")])
7742 (define_insn "fmul8ulx16_vis"
7743 [(set (match_operand:V4HI 0 "register_operand" "=e")
7744 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7745 (match_operand:V4HI 2 "register_operand" "e")]
7748 "fmul8ulx16\t%1, %2, %0"
7749 [(set_attr "type" "fpmul")
7750 (set_attr "fptype" "double")])
7752 ;; Only one of the following two insns can be a multiply.
7753 (define_insn "fmuld8sux16_vis"
7754 [(set (match_operand:V2SI 0 "register_operand" "=e")
7755 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7756 (match_operand:V2HI 2 "register_operand" "f")))]
7758 "fmuld8sux16\t%1, %2, %0"
7759 [(set_attr "type" "fpmul")
7760 (set_attr "fptype" "double")])
7762 (define_insn "fmuld8ulx16_vis"
7763 [(set (match_operand:V2SI 0 "register_operand" "=e")
7764 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7765 (match_operand:V2HI 2 "register_operand" "f")]
7768 "fmuld8ulx16\t%1, %2, %0"
7769 [(set_attr "type" "fpmul")
7770 (set_attr "fptype" "double")])
7772 ;; Using faligndata only makes sense after an alignaddr since the choice of
7773 ;; bytes to take out of each operand is dependent on the results of the last
7775 (define_insn "faligndata<V64I:mode>_vis"
7776 [(set (match_operand:V64I 0 "register_operand" "=e")
7777 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7778 (match_operand:V64I 2 "register_operand" "e")]
7781 "faligndata\t%1, %2, %0"
7782 [(set_attr "type" "fga")
7783 (set_attr "fptype" "double")])
7785 (define_insn "alignaddr<P:mode>_vis"
7786 [(set (match_operand:P 0 "register_operand" "=r")
7787 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7788 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7791 "alignaddr\t%r1, %r2, %0")
7793 (define_insn "pdist_vis"
7794 [(set (match_operand:DI 0 "register_operand" "=e")
7795 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7796 (match_operand:V8QI 2 "register_operand" "e")
7797 (match_operand:DI 3 "register_operand" "0")]
7801 [(set_attr "type" "fga")
7802 (set_attr "fptype" "double")])