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)
100 (UNSPECV_PROBE_STACK_RANGE 11)
193 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
194 (define_mode_iterator I [QI HI SI DI])
195 (define_mode_iterator F [SF DF TF])
197 ;; We don't define V1SI because SI should work just fine.
198 (define_mode_iterator V32 [SF V2HI V4QI])
199 (define_mode_iterator V32I [SI V2HI V4QI])
201 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
202 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
204 (define_mode_iterator V64N8 [V2SI V4HI])
206 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
207 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
208 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
209 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
210 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
212 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (SI "32s") (V2HI "16s")])
213 (define_mode_attr vconstr [(V2SI "e") (V4HI "e") (SI "f") (V2HI "f")])
215 ;; Attribute for cpu type.
216 ;; These must match the values for enum processor_type in sparc.h.
237 (const (symbol_ref "sparc_cpu_attr")))
239 ;; Attribute for the instruction set.
240 ;; At present we only need to distinguish v9/!v9, but for clarity we
241 ;; test TARGET_V8 too.
242 (define_attr "isa" "v7,v8,v9,sparclet"
244 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
245 (symbol_ref "TARGET_V8") (const_string "v8")
246 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
247 (const_string "v7"))))
253 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
261 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
264 multi,savew,flushw,iflush,trap"
265 (const_string "ialu"))
267 ;; True if branch/call has empty delay slot and will emit a nop in it
268 (define_attr "empty_delay_slot" "false,true"
269 (symbol_ref "(empty_delay_slot (insn)
270 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
272 (define_attr "branch_type" "none,icc,fcc,reg"
273 (const_string "none"))
275 (define_attr "pic" "false,true"
276 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
278 (define_attr "calls_alloca" "false,true"
279 (symbol_ref "(cfun->calls_alloca != 0
280 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
282 (define_attr "calls_eh_return" "false,true"
283 (symbol_ref "(crtl->calls_eh_return != 0
284 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
286 (define_attr "leaf_function" "false,true"
287 (symbol_ref "(current_function_uses_only_leaf_regs != 0
288 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
290 (define_attr "delayed_branch" "false,true"
291 (symbol_ref "(flag_delayed_branch != 0
292 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
294 (define_attr "flat" "false,true"
295 (symbol_ref "(TARGET_FLAT != 0
296 ? FLAT_TRUE : FLAT_FALSE)"))
298 ;; Length (in # of insns).
299 ;; Beware that setting a length greater or equal to 3 for conditional branches
300 ;; has a side-effect (see output_cbranch and output_v9branch).
301 (define_attr "length" ""
302 (cond [(eq_attr "type" "uncond_branch,call")
303 (if_then_else (eq_attr "empty_delay_slot" "true")
306 (eq_attr "type" "sibcall")
307 (if_then_else (eq_attr "leaf_function" "true")
308 (if_then_else (eq_attr "empty_delay_slot" "true")
311 (if_then_else (eq_attr "empty_delay_slot" "true")
314 (eq_attr "branch_type" "icc")
315 (if_then_else (match_operand 0 "noov_compare64_operator" "")
316 (if_then_else (lt (pc) (match_dup 1))
317 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
318 (if_then_else (eq_attr "empty_delay_slot" "true")
321 (if_then_else (eq_attr "empty_delay_slot" "true")
324 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
325 (if_then_else (eq_attr "empty_delay_slot" "true")
328 (if_then_else (eq_attr "empty_delay_slot" "true")
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (eq_attr "branch_type" "fcc")
335 (if_then_else (match_operand 0 "fcc0_register_operand" "")
336 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (if_then_else (not (match_test "TARGET_V9"))
340 (if_then_else (not (match_test "TARGET_V9"))
343 (if_then_else (lt (pc) (match_dup 2))
344 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
345 (if_then_else (eq_attr "empty_delay_slot" "true")
348 (if_then_else (eq_attr "empty_delay_slot" "true")
351 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
352 (if_then_else (eq_attr "empty_delay_slot" "true")
355 (if_then_else (eq_attr "empty_delay_slot" "true")
358 (eq_attr "branch_type" "reg")
359 (if_then_else (lt (pc) (match_dup 2))
360 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
361 (if_then_else (eq_attr "empty_delay_slot" "true")
364 (if_then_else (eq_attr "empty_delay_slot" "true")
367 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
368 (if_then_else (eq_attr "empty_delay_slot" "true")
371 (if_then_else (eq_attr "empty_delay_slot" "true")
377 (define_attr "fptype" "single,double"
378 (const_string "single"))
380 ;; UltraSPARC-III integer load type.
381 (define_attr "us3load_type" "2cycle,3cycle"
382 (const_string "2cycle"))
384 (define_asm_attributes
385 [(set_attr "length" "2")
386 (set_attr "type" "multi")])
388 ;; Attributes for instruction and branch scheduling
389 (define_attr "tls_call_delay" "false,true"
390 (symbol_ref "(tls_call_delay (insn)
391 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
393 (define_attr "in_call_delay" "false,true"
394 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
395 (const_string "false")
396 (eq_attr "type" "load,fpload,store,fpstore")
397 (if_then_else (eq_attr "length" "1")
398 (const_string "true")
399 (const_string "false"))]
400 (if_then_else (and (eq_attr "length" "1")
401 (eq_attr "tls_call_delay" "true"))
402 (const_string "true")
403 (const_string "false"))))
405 (define_attr "eligible_for_sibcall_delay" "false,true"
406 (symbol_ref "(eligible_for_sibcall_delay (insn)
407 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
408 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
410 (define_attr "eligible_for_return_delay" "false,true"
411 (symbol_ref "(eligible_for_return_delay (insn)
412 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
413 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
415 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
416 ;; branches. This would allow us to remove the nop always inserted before
417 ;; a floating point branch.
419 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
420 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
421 ;; This is because doing so will add several pipeline stalls to the path
422 ;; that the load/store did not come from. Unfortunately, there is no way
423 ;; to prevent fill_eager_delay_slots from using load/store without completely
424 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
425 ;; because it prevents us from moving back the final store of inner loops.
427 (define_attr "in_branch_delay" "false,true"
428 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
429 (eq_attr "length" "1"))
430 (const_string "true")
431 (const_string "false")))
433 (define_attr "in_uncond_branch_delay" "false,true"
434 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
435 (eq_attr "length" "1"))
436 (const_string "true")
437 (const_string "false")))
439 (define_attr "in_annul_branch_delay" "false,true"
440 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
441 (eq_attr "length" "1"))
442 (const_string "true")
443 (const_string "false")))
445 (define_delay (eq_attr "type" "call")
446 [(eq_attr "in_call_delay" "true") (nil) (nil)])
448 (define_delay (eq_attr "type" "sibcall")
449 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
451 (define_delay (eq_attr "type" "branch")
452 [(eq_attr "in_branch_delay" "true")
453 (nil) (eq_attr "in_annul_branch_delay" "true")])
455 (define_delay (eq_attr "type" "uncond_branch")
456 [(eq_attr "in_uncond_branch_delay" "true")
459 (define_delay (eq_attr "type" "return")
460 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
463 ;; Include SPARC DFA schedulers
465 (include "cypress.md")
466 (include "supersparc.md")
467 (include "hypersparc.md")
469 (include "sparclet.md")
470 (include "ultra1_2.md")
471 (include "ultra3.md")
472 (include "niagara.md")
473 (include "niagara2.md")
476 ;; Operand and operator predicates and constraints
478 (include "predicates.md")
479 (include "constraints.md")
482 ;; Compare instructions.
484 ;; These are just the DEFINE_INSNs to match the patterns and the
485 ;; DEFINE_SPLITs for some of the scc insns that actually require
486 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
488 ;; The compare DEFINE_INSNs.
490 (define_insn "*cmpsi_insn"
491 [(set (reg:CC CC_REG)
492 (compare:CC (match_operand:SI 0 "register_operand" "r")
493 (match_operand:SI 1 "arith_operand" "rI")))]
496 [(set_attr "type" "compare")])
498 (define_insn "*cmpdi_sp64"
499 [(set (reg:CCX CC_REG)
500 (compare:CCX (match_operand:DI 0 "register_operand" "r")
501 (match_operand:DI 1 "arith_operand" "rI")))]
504 [(set_attr "type" "compare")])
506 (define_insn "*cmpsf_fpe"
507 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
508 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
509 (match_operand:SF 2 "register_operand" "f")))]
513 return "fcmpes\t%0, %1, %2";
514 return "fcmpes\t%1, %2";
516 [(set_attr "type" "fpcmp")])
518 (define_insn "*cmpdf_fpe"
519 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
520 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
521 (match_operand:DF 2 "register_operand" "e")))]
525 return "fcmped\t%0, %1, %2";
526 return "fcmped\t%1, %2";
528 [(set_attr "type" "fpcmp")
529 (set_attr "fptype" "double")])
531 (define_insn "*cmptf_fpe"
532 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
533 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
534 (match_operand:TF 2 "register_operand" "e")))]
535 "TARGET_FPU && TARGET_HARD_QUAD"
538 return "fcmpeq\t%0, %1, %2";
539 return "fcmpeq\t%1, %2";
541 [(set_attr "type" "fpcmp")])
543 (define_insn "*cmpsf_fp"
544 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
545 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
546 (match_operand:SF 2 "register_operand" "f")))]
550 return "fcmps\t%0, %1, %2";
551 return "fcmps\t%1, %2";
553 [(set_attr "type" "fpcmp")])
555 (define_insn "*cmpdf_fp"
556 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
557 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
558 (match_operand:DF 2 "register_operand" "e")))]
562 return "fcmpd\t%0, %1, %2";
563 return "fcmpd\t%1, %2";
565 [(set_attr "type" "fpcmp")
566 (set_attr "fptype" "double")])
568 (define_insn "*cmptf_fp"
569 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
570 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
571 (match_operand:TF 2 "register_operand" "e")))]
572 "TARGET_FPU && TARGET_HARD_QUAD"
575 return "fcmpq\t%0, %1, %2";
576 return "fcmpq\t%1, %2";
578 [(set_attr "type" "fpcmp")])
580 ;; Next come the scc insns.
582 (define_expand "cstoresi4"
583 [(use (match_operator 1 "comparison_operator"
584 [(match_operand:SI 2 "compare_operand" "")
585 (match_operand:SI 3 "arith_operand" "")]))
586 (clobber (match_operand:SI 0 "register_operand"))]
589 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
590 operands[2] = force_reg (SImode, operands[2]);
591 if (emit_scc_insn (operands)) DONE; else FAIL;
594 (define_expand "cstoredi4"
595 [(use (match_operator 1 "comparison_operator"
596 [(match_operand:DI 2 "compare_operand" "")
597 (match_operand:DI 3 "arith_operand" "")]))
598 (clobber (match_operand:SI 0 "register_operand"))]
601 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
602 operands[2] = force_reg (DImode, operands[2]);
603 if (emit_scc_insn (operands)) DONE; else FAIL;
606 (define_expand "cstore<F:mode>4"
607 [(use (match_operator 1 "comparison_operator"
608 [(match_operand:F 2 "register_operand" "")
609 (match_operand:F 3 "register_operand" "")]))
610 (clobber (match_operand:SI 0 "register_operand"))]
612 { if (emit_scc_insn (operands)) DONE; else FAIL; })
616 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
617 ;; generate addcc/subcc instructions.
619 (define_expand "seqsi_special"
621 (xor:SI (match_operand:SI 1 "register_operand" "")
622 (match_operand:SI 2 "register_operand" "")))
623 (parallel [(set (match_operand:SI 0 "register_operand" "")
624 (eq:SI (match_dup 3) (const_int 0)))
625 (clobber (reg:CC CC_REG))])]
627 { operands[3] = gen_reg_rtx (SImode); })
629 (define_expand "seqdi_special"
631 (xor:DI (match_operand:DI 1 "register_operand" "")
632 (match_operand:DI 2 "register_operand" "")))
633 (set (match_operand:SI 0 "register_operand" "")
634 (eq:SI (match_dup 3) (const_int 0)))]
636 { operands[3] = gen_reg_rtx (DImode); })
638 (define_expand "snesi_special"
640 (xor:SI (match_operand:SI 1 "register_operand" "")
641 (match_operand:SI 2 "register_operand" "")))
642 (parallel [(set (match_operand:SI 0 "register_operand" "")
643 (ne:SI (match_dup 3) (const_int 0)))
644 (clobber (reg:CC CC_REG))])]
646 { operands[3] = gen_reg_rtx (SImode); })
648 (define_expand "snedi_special"
650 (xor:DI (match_operand:DI 1 "register_operand" "")
651 (match_operand:DI 2 "register_operand" "")))
652 (set (match_operand:SI 0 "register_operand" "")
653 (ne:SI (match_dup 3) (const_int 0)))]
655 { operands[3] = gen_reg_rtx (DImode); })
658 ;; Now the DEFINE_INSNs for the scc cases.
660 ;; The SEQ and SNE patterns are special because they can be done
661 ;; without any branching and do not involve a COMPARE. We want
662 ;; them to always use the splits below so the results can be
665 (define_insn_and_split "*snesi_zero"
666 [(set (match_operand:SI 0 "register_operand" "=r")
667 (ne:SI (match_operand:SI 1 "register_operand" "r")
669 (clobber (reg:CC CC_REG))]
673 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
675 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
677 [(set_attr "length" "2")])
679 (define_insn_and_split "*neg_snesi_zero"
680 [(set (match_operand:SI 0 "register_operand" "=r")
681 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
683 (clobber (reg:CC CC_REG))]
687 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
689 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
691 [(set_attr "length" "2")])
693 (define_insn_and_split "*snesi_zero_extend"
694 [(set (match_operand:DI 0 "register_operand" "=r")
695 (ne:DI (match_operand:SI 1 "register_operand" "r")
697 (clobber (reg:CC CC_REG))]
701 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
704 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
706 (ltu:SI (reg:CC_NOOV CC_REG)
709 [(set_attr "length" "2")])
711 (define_insn_and_split "*snedi_zero"
712 [(set (match_operand:DI 0 "register_operand" "=&r")
713 (ne:DI (match_operand:DI 1 "register_operand" "r")
717 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
718 [(set (match_dup 0) (const_int 0))
719 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
724 [(set_attr "length" "2")])
726 (define_insn_and_split "*neg_snedi_zero"
727 [(set (match_operand:DI 0 "register_operand" "=&r")
728 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
732 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
733 [(set (match_dup 0) (const_int 0))
734 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
739 [(set_attr "length" "2")])
741 (define_insn_and_split "*snedi_zero_trunc"
742 [(set (match_operand:SI 0 "register_operand" "=&r")
743 (ne:SI (match_operand:DI 1 "register_operand" "r")
747 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
748 [(set (match_dup 0) (const_int 0))
749 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
754 [(set_attr "length" "2")])
756 (define_insn_and_split "*seqsi_zero"
757 [(set (match_operand:SI 0 "register_operand" "=r")
758 (eq:SI (match_operand:SI 1 "register_operand" "r")
760 (clobber (reg:CC CC_REG))]
764 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
766 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
768 [(set_attr "length" "2")])
770 (define_insn_and_split "*neg_seqsi_zero"
771 [(set (match_operand:SI 0 "register_operand" "=r")
772 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
774 (clobber (reg:CC CC_REG))]
778 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
780 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
782 [(set_attr "length" "2")])
784 (define_insn_and_split "*seqsi_zero_extend"
785 [(set (match_operand:DI 0 "register_operand" "=r")
786 (eq:DI (match_operand:SI 1 "register_operand" "r")
788 (clobber (reg:CC CC_REG))]
792 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
795 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
797 (ltu:SI (reg:CC_NOOV CC_REG)
800 [(set_attr "length" "2")])
802 (define_insn_and_split "*seqdi_zero"
803 [(set (match_operand:DI 0 "register_operand" "=&r")
804 (eq:DI (match_operand:DI 1 "register_operand" "r")
808 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
809 [(set (match_dup 0) (const_int 0))
810 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
815 [(set_attr "length" "2")])
817 (define_insn_and_split "*neg_seqdi_zero"
818 [(set (match_operand:DI 0 "register_operand" "=&r")
819 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
823 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
824 [(set (match_dup 0) (const_int 0))
825 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
830 [(set_attr "length" "2")])
832 (define_insn_and_split "*seqdi_zero_trunc"
833 [(set (match_operand:SI 0 "register_operand" "=&r")
834 (eq:SI (match_operand:DI 1 "register_operand" "r")
838 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
839 [(set (match_dup 0) (const_int 0))
840 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
845 [(set_attr "length" "2")])
847 ;; We can also do (x + (i == 0)) and related, so put them in.
848 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
851 (define_insn_and_split "*x_plus_i_ne_0"
852 [(set (match_operand:SI 0 "register_operand" "=r")
853 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
855 (match_operand:SI 2 "register_operand" "r")))
856 (clobber (reg:CC CC_REG))]
860 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
862 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
865 [(set_attr "length" "2")])
867 (define_insn_and_split "*x_minus_i_ne_0"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (minus:SI (match_operand:SI 2 "register_operand" "r")
870 (ne:SI (match_operand:SI 1 "register_operand" "r")
872 (clobber (reg:CC CC_REG))]
876 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
878 (set (match_dup 0) (minus:SI (match_dup 2)
879 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
881 [(set_attr "length" "2")])
883 (define_insn_and_split "*x_plus_i_eq_0"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
887 (match_operand:SI 2 "register_operand" "r")))
888 (clobber (reg:CC CC_REG))]
892 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
894 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
897 [(set_attr "length" "2")])
899 (define_insn_and_split "*x_minus_i_eq_0"
900 [(set (match_operand:SI 0 "register_operand" "=r")
901 (minus:SI (match_operand:SI 2 "register_operand" "r")
902 (eq:SI (match_operand:SI 1 "register_operand" "r")
904 (clobber (reg:CC CC_REG))]
908 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
910 (set (match_dup 0) (minus:SI (match_dup 2)
911 (geu:SI (reg:CC CC_REG) (const_int 0))))]
913 [(set_attr "length" "2")])
915 ;; We can also do GEU and LTU directly, but these operate after a compare.
916 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
919 (define_insn "*sltu_insn"
920 [(set (match_operand:SI 0 "register_operand" "=r")
921 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
924 [(set_attr "type" "ialuX")])
926 (define_insn "*neg_sltu_insn"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
931 [(set_attr "type" "ialuX")])
933 ;; ??? Combine should canonicalize these next two to the same pattern.
934 (define_insn "*neg_sltu_minus_x"
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
937 (match_operand:SI 1 "arith_operand" "rI")))]
940 [(set_attr "type" "ialuX")])
942 (define_insn "*neg_sltu_plus_x"
943 [(set (match_operand:SI 0 "register_operand" "=r")
944 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
945 (match_operand:SI 1 "arith_operand" "rI"))))]
948 [(set_attr "type" "ialuX")])
950 (define_insn "*sgeu_insn"
951 [(set (match_operand:SI 0 "register_operand" "=r")
952 (geu:SI (reg:CC CC_REG) (const_int 0)))]
955 [(set_attr "type" "ialuX")])
957 (define_insn "*neg_sgeu_insn"
958 [(set (match_operand:SI 0 "register_operand" "=r")
959 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
962 [(set_attr "type" "ialuX")])
964 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
965 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
968 (define_insn "*sltu_plus_x"
969 [(set (match_operand:SI 0 "register_operand" "=r")
970 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
971 (match_operand:SI 1 "arith_operand" "rI")))]
974 [(set_attr "type" "ialuX")])
976 (define_insn "*sltu_plus_x_plus_y"
977 [(set (match_operand:SI 0 "register_operand" "=r")
978 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
979 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
980 (match_operand:SI 2 "arith_operand" "rI"))))]
983 [(set_attr "type" "ialuX")])
985 (define_insn "*x_minus_sltu"
986 [(set (match_operand:SI 0 "register_operand" "=r")
987 (minus:SI (match_operand:SI 1 "register_operand" "r")
988 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
991 [(set_attr "type" "ialuX")])
993 ;; ??? Combine should canonicalize these next two to the same pattern.
994 (define_insn "*x_minus_y_minus_sltu"
995 [(set (match_operand:SI 0 "register_operand" "=r")
996 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
997 (match_operand:SI 2 "arith_operand" "rI"))
998 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1001 [(set_attr "type" "ialuX")])
1003 (define_insn "*x_minus_sltu_plus_y"
1004 [(set (match_operand:SI 0 "register_operand" "=r")
1005 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1006 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1007 (match_operand:SI 2 "arith_operand" "rI"))))]
1010 [(set_attr "type" "ialuX")])
1012 (define_insn "*sgeu_plus_x"
1013 [(set (match_operand:SI 0 "register_operand" "=r")
1014 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1015 (match_operand:SI 1 "register_operand" "r")))]
1018 [(set_attr "type" "ialuX")])
1020 (define_insn "*x_minus_sgeu"
1021 [(set (match_operand:SI 0 "register_operand" "=r")
1022 (minus:SI (match_operand:SI 1 "register_operand" "r")
1023 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1026 [(set_attr "type" "ialuX")])
1029 [(set (match_operand:SI 0 "register_operand" "")
1030 (match_operator:SI 2 "noov_compare_operator"
1031 [(match_operand 1 "icc_or_fcc_register_operand" "")
1034 && REGNO (operands[1]) == SPARC_ICC_REG
1035 && (GET_MODE (operands[1]) == CCXmode
1036 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1037 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1038 [(set (match_dup 0) (const_int 0))
1040 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1046 ;; These control RTL generation for conditional jump insns
1048 (define_expand "cbranchcc4"
1050 (if_then_else (match_operator 0 "comparison_operator"
1051 [(match_operand 1 "compare_operand" "")
1052 (match_operand 2 "const_zero_operand" "")])
1053 (label_ref (match_operand 3 "" ""))
1058 (define_expand "cbranchsi4"
1059 [(use (match_operator 0 "comparison_operator"
1060 [(match_operand:SI 1 "compare_operand" "")
1061 (match_operand:SI 2 "arith_operand" "")]))
1062 (use (match_operand 3 ""))]
1065 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1066 operands[1] = force_reg (SImode, operands[1]);
1067 emit_conditional_branch_insn (operands);
1071 (define_expand "cbranchdi4"
1072 [(use (match_operator 0 "comparison_operator"
1073 [(match_operand:DI 1 "compare_operand" "")
1074 (match_operand:DI 2 "arith_operand" "")]))
1075 (use (match_operand 3 ""))]
1078 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1079 operands[1] = force_reg (DImode, operands[1]);
1080 emit_conditional_branch_insn (operands);
1084 (define_expand "cbranch<F:mode>4"
1085 [(use (match_operator 0 "comparison_operator"
1086 [(match_operand:F 1 "register_operand" "")
1087 (match_operand:F 2 "register_operand" "")]))
1088 (use (match_operand 3 ""))]
1090 { emit_conditional_branch_insn (operands); DONE; })
1093 ;; Now match both normal and inverted jump.
1095 ;; XXX fpcmp nop braindamage
1096 (define_insn "*normal_branch"
1098 (if_then_else (match_operator 0 "noov_compare_operator"
1099 [(reg CC_REG) (const_int 0)])
1100 (label_ref (match_operand 1 "" ""))
1104 return output_cbranch (operands[0], operands[1], 1, 0,
1105 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1108 [(set_attr "type" "branch")
1109 (set_attr "branch_type" "icc")])
1111 ;; XXX fpcmp nop braindamage
1112 (define_insn "*inverted_branch"
1114 (if_then_else (match_operator 0 "noov_compare_operator"
1115 [(reg CC_REG) (const_int 0)])
1117 (label_ref (match_operand 1 "" ""))))]
1120 return output_cbranch (operands[0], operands[1], 1, 1,
1121 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1124 [(set_attr "type" "branch")
1125 (set_attr "branch_type" "icc")])
1127 ;; XXX fpcmp nop braindamage
1128 (define_insn "*normal_fp_branch"
1130 (if_then_else (match_operator 1 "comparison_operator"
1131 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1133 (label_ref (match_operand 2 "" ""))
1137 return output_cbranch (operands[1], operands[2], 2, 0,
1138 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1141 [(set_attr "type" "branch")
1142 (set_attr "branch_type" "fcc")])
1144 ;; XXX fpcmp nop braindamage
1145 (define_insn "*inverted_fp_branch"
1147 (if_then_else (match_operator 1 "comparison_operator"
1148 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1151 (label_ref (match_operand 2 "" ""))))]
1154 return output_cbranch (operands[1], operands[2], 2, 1,
1155 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1158 [(set_attr "type" "branch")
1159 (set_attr "branch_type" "fcc")])
1161 ;; XXX fpcmp nop braindamage
1162 (define_insn "*normal_fpe_branch"
1164 (if_then_else (match_operator 1 "comparison_operator"
1165 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1167 (label_ref (match_operand 2 "" ""))
1171 return output_cbranch (operands[1], operands[2], 2, 0,
1172 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1175 [(set_attr "type" "branch")
1176 (set_attr "branch_type" "fcc")])
1178 ;; XXX fpcmp nop braindamage
1179 (define_insn "*inverted_fpe_branch"
1181 (if_then_else (match_operator 1 "comparison_operator"
1182 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1185 (label_ref (match_operand 2 "" ""))))]
1188 return output_cbranch (operands[1], operands[2], 2, 1,
1189 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1192 [(set_attr "type" "branch")
1193 (set_attr "branch_type" "fcc")])
1195 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1196 ;; in the architecture.
1198 ;; There are no 32 bit brreg insns.
1201 (define_insn "*normal_int_branch_sp64"
1203 (if_then_else (match_operator 0 "v9_register_compare_operator"
1204 [(match_operand:DI 1 "register_operand" "r")
1206 (label_ref (match_operand 2 "" ""))
1210 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1211 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1214 [(set_attr "type" "branch")
1215 (set_attr "branch_type" "reg")])
1218 (define_insn "*inverted_int_branch_sp64"
1220 (if_then_else (match_operator 0 "v9_register_compare_operator"
1221 [(match_operand:DI 1 "register_operand" "r")
1224 (label_ref (match_operand 2 "" ""))))]
1227 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1228 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1231 [(set_attr "type" "branch")
1232 (set_attr "branch_type" "reg")])
1235 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1236 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1237 ;; that adds the PC value at the call point to register #(operand 3).
1239 (define_insn "load_pcrel_sym<P:mode>"
1240 [(set (match_operand:P 0 "register_operand" "=r")
1241 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1242 (match_operand:P 2 "call_address_operand" "")
1243 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1244 (clobber (reg:P O7_REG))]
1245 "REGNO (operands[0]) == INTVAL (operands[3])"
1247 if (flag_delayed_branch)
1248 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1250 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1252 [(set (attr "type") (const_string "multi"))
1253 (set (attr "length")
1254 (if_then_else (eq_attr "delayed_branch" "true")
1259 ;; Integer move instructions
1261 (define_expand "movqi"
1262 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1263 (match_operand:QI 1 "general_operand" ""))]
1266 if (sparc_expand_move (QImode, operands))
1270 (define_insn "*movqi_insn"
1271 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1272 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1273 "(register_operand (operands[0], QImode)
1274 || register_or_zero_operand (operands[1], QImode))"
1279 [(set_attr "type" "*,load,store")
1280 (set_attr "us3load_type" "*,3cycle,*")])
1282 (define_expand "movhi"
1283 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1284 (match_operand:HI 1 "general_operand" ""))]
1287 if (sparc_expand_move (HImode, operands))
1291 (define_insn "*movhi_insn"
1292 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1293 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1294 "(register_operand (operands[0], HImode)
1295 || register_or_zero_operand (operands[1], HImode))"
1298 sethi\t%%hi(%a1), %0
1301 [(set_attr "type" "*,*,load,store")
1302 (set_attr "us3load_type" "*,*,3cycle,*")])
1304 ;; We always work with constants here.
1305 (define_insn "*movhi_lo_sum"
1306 [(set (match_operand:HI 0 "register_operand" "=r")
1307 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1308 (match_operand:HI 2 "small_int_operand" "I")))]
1312 (define_expand "movsi"
1313 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1314 (match_operand:SI 1 "general_operand" ""))]
1317 if (sparc_expand_move (SImode, operands))
1321 (define_insn "*movsi_insn"
1322 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1323 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1324 "(register_operand (operands[0], SImode)
1325 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1328 sethi\t%%hi(%a1), %0
1336 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1338 (define_insn "*movsi_lo_sum"
1339 [(set (match_operand:SI 0 "register_operand" "=r")
1340 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1341 (match_operand:SI 2 "immediate_operand" "in")))]
1343 "or\t%1, %%lo(%a2), %0")
1345 (define_insn "*movsi_high"
1346 [(set (match_operand:SI 0 "register_operand" "=r")
1347 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1349 "sethi\t%%hi(%a1), %0")
1351 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1352 ;; so that CSE won't optimize the address computation away.
1353 (define_insn "movsi_lo_sum_pic"
1354 [(set (match_operand:SI 0 "register_operand" "=r")
1355 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1356 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1359 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1360 return "xor\t%1, %%gdop_lox10(%a2), %0";
1362 return "or\t%1, %%lo(%a2), %0";
1366 (define_insn "movsi_high_pic"
1367 [(set (match_operand:SI 0 "register_operand" "=r")
1368 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1369 "flag_pic && check_pic (1)"
1371 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1372 return "sethi\t%%gdop_hix22(%a1), %0";
1374 return "sethi\t%%hi(%a1), %0";
1378 (define_insn "movsi_pic_gotdata_op"
1379 [(set (match_operand:SI 0 "register_operand" "=r")
1380 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1381 (match_operand:SI 2 "register_operand" "r")
1382 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1383 "flag_pic && check_pic (1)"
1385 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1386 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1388 return "ld\t[%1 + %2], %0";
1391 [(set_attr "type" "load")])
1393 (define_expand "movsi_pic_label_ref"
1394 [(set (match_dup 3) (high:SI
1395 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1396 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1397 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1398 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1399 (set (match_operand:SI 0 "register_operand" "=r")
1400 (minus:SI (match_dup 5) (match_dup 4)))]
1403 crtl->uses_pic_offset_table = 1;
1404 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1405 if (!can_create_pseudo_p ())
1407 operands[3] = operands[0];
1408 operands[4] = operands[0];
1412 operands[3] = gen_reg_rtx (SImode);
1413 operands[4] = gen_reg_rtx (SImode);
1415 operands[5] = pic_offset_table_rtx;
1418 (define_insn "*movsi_high_pic_label_ref"
1419 [(set (match_operand:SI 0 "register_operand" "=r")
1421 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1422 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1424 "sethi\t%%hi(%a2-(%a1-.)), %0")
1426 (define_insn "*movsi_lo_sum_pic_label_ref"
1427 [(set (match_operand:SI 0 "register_operand" "=r")
1428 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1429 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1430 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1432 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1434 ;; Set up the PIC register for VxWorks.
1436 (define_expand "vxworks_load_got"
1438 (high:SI (match_dup 1)))
1440 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1442 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1443 "TARGET_VXWORKS_RTP"
1445 operands[0] = pic_offset_table_rtx;
1446 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1447 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1450 (define_expand "movdi"
1451 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1452 (match_operand:DI 1 "general_operand" ""))]
1455 if (sparc_expand_move (DImode, operands))
1459 ;; Be careful, fmovd does not exist when !v9.
1460 ;; We match MEM moves directly when we have correct even
1461 ;; numbered registers, but fall into splits otherwise.
1462 ;; The constraint ordering here is really important to
1463 ;; avoid insane problems in reload, especially for patterns
1466 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1467 ;; (const_int -5016)))
1471 (define_insn "*movdi_insn_sp32"
1472 [(set (match_operand:DI 0 "nonimmediate_operand"
1473 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1474 (match_operand:DI 1 "input_operand"
1475 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1477 && (register_operand (operands[0], DImode)
1478 || register_or_zero_operand (operands[1], DImode))"
1492 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1493 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1495 (define_insn "*movdi_insn_sp32_v9"
1496 [(set (match_operand:DI 0 "nonimmediate_operand"
1497 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1498 (match_operand:DI 1 "input_operand"
1499 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1502 && (register_operand (operands[0], DImode)
1503 || register_or_zero_operand (operands[1], DImode))"
1520 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1521 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1522 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1524 (define_insn "*movdi_insn_sp64"
1525 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1526 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1528 && (register_operand (operands[0], DImode)
1529 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1532 sethi\t%%hi(%a1), %0
1540 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1541 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1543 (define_expand "movdi_pic_label_ref"
1544 [(set (match_dup 3) (high:DI
1545 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1546 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1547 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1548 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1549 (set (match_operand:DI 0 "register_operand" "=r")
1550 (minus:DI (match_dup 5) (match_dup 4)))]
1551 "TARGET_ARCH64 && flag_pic"
1553 crtl->uses_pic_offset_table = 1;
1554 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1555 if (!can_create_pseudo_p ())
1557 operands[3] = operands[0];
1558 operands[4] = operands[0];
1562 operands[3] = gen_reg_rtx (DImode);
1563 operands[4] = gen_reg_rtx (DImode);
1565 operands[5] = pic_offset_table_rtx;
1568 (define_insn "*movdi_high_pic_label_ref"
1569 [(set (match_operand:DI 0 "register_operand" "=r")
1571 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1572 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1573 "TARGET_ARCH64 && flag_pic"
1574 "sethi\t%%hi(%a2-(%a1-.)), %0")
1576 (define_insn "*movdi_lo_sum_pic_label_ref"
1577 [(set (match_operand:DI 0 "register_operand" "=r")
1578 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1579 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1580 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1581 "TARGET_ARCH64 && flag_pic"
1582 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1584 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1585 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1587 (define_insn "movdi_lo_sum_pic"
1588 [(set (match_operand:DI 0 "register_operand" "=r")
1589 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1590 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1591 "TARGET_ARCH64 && flag_pic"
1593 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1594 return "xor\t%1, %%gdop_lox10(%a2), %0";
1596 return "or\t%1, %%lo(%a2), %0";
1600 (define_insn "movdi_high_pic"
1601 [(set (match_operand:DI 0 "register_operand" "=r")
1602 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1603 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1605 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1606 return "sethi\t%%gdop_hix22(%a1), %0";
1608 return "sethi\t%%hi(%a1), %0";
1612 (define_insn "movdi_pic_gotdata_op"
1613 [(set (match_operand:DI 0 "register_operand" "=r")
1614 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1615 (match_operand:DI 2 "register_operand" "r")
1616 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1617 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1619 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1620 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1622 return "ldx\t[%1 + %2], %0";
1625 [(set_attr "type" "load")])
1627 (define_insn "*sethi_di_medlow_embmedany_pic"
1628 [(set (match_operand:DI 0 "register_operand" "=r")
1629 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1630 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1631 "sethi\t%%hi(%a1), %0")
1633 (define_insn "*sethi_di_medlow"
1634 [(set (match_operand:DI 0 "register_operand" "=r")
1635 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1636 "TARGET_CM_MEDLOW && check_pic (1)"
1637 "sethi\t%%hi(%a1), %0")
1639 (define_insn "*losum_di_medlow"
1640 [(set (match_operand:DI 0 "register_operand" "=r")
1641 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1642 (match_operand:DI 2 "symbolic_operand" "")))]
1644 "or\t%1, %%lo(%a2), %0")
1646 (define_insn "seth44"
1647 [(set (match_operand:DI 0 "register_operand" "=r")
1648 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1650 "sethi\t%%h44(%a1), %0")
1652 (define_insn "setm44"
1653 [(set (match_operand:DI 0 "register_operand" "=r")
1654 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1655 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1657 "or\t%1, %%m44(%a2), %0")
1659 (define_insn "setl44"
1660 [(set (match_operand:DI 0 "register_operand" "=r")
1661 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1662 (match_operand:DI 2 "symbolic_operand" "")))]
1664 "or\t%1, %%l44(%a2), %0")
1666 (define_insn "sethh"
1667 [(set (match_operand:DI 0 "register_operand" "=r")
1668 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1670 "sethi\t%%hh(%a1), %0")
1672 (define_insn "setlm"
1673 [(set (match_operand:DI 0 "register_operand" "=r")
1674 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1676 "sethi\t%%lm(%a1), %0")
1678 (define_insn "sethm"
1679 [(set (match_operand:DI 0 "register_operand" "=r")
1680 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1681 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1683 "or\t%1, %%hm(%a2), %0")
1685 (define_insn "setlo"
1686 [(set (match_operand:DI 0 "register_operand" "=r")
1687 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1688 (match_operand:DI 2 "symbolic_operand" "")))]
1690 "or\t%1, %%lo(%a2), %0")
1692 (define_insn "embmedany_sethi"
1693 [(set (match_operand:DI 0 "register_operand" "=r")
1694 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1695 "TARGET_CM_EMBMEDANY && check_pic (1)"
1696 "sethi\t%%hi(%a1), %0")
1698 (define_insn "embmedany_losum"
1699 [(set (match_operand:DI 0 "register_operand" "=r")
1700 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1701 (match_operand:DI 2 "data_segment_operand" "")))]
1702 "TARGET_CM_EMBMEDANY"
1703 "add\t%1, %%lo(%a2), %0")
1705 (define_insn "embmedany_brsum"
1706 [(set (match_operand:DI 0 "register_operand" "=r")
1707 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1708 "TARGET_CM_EMBMEDANY"
1711 (define_insn "embmedany_textuhi"
1712 [(set (match_operand:DI 0 "register_operand" "=r")
1713 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1714 "TARGET_CM_EMBMEDANY && check_pic (1)"
1715 "sethi\t%%uhi(%a1), %0")
1717 (define_insn "embmedany_texthi"
1718 [(set (match_operand:DI 0 "register_operand" "=r")
1719 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1720 "TARGET_CM_EMBMEDANY && check_pic (1)"
1721 "sethi\t%%hi(%a1), %0")
1723 (define_insn "embmedany_textulo"
1724 [(set (match_operand:DI 0 "register_operand" "=r")
1725 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1726 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1727 "TARGET_CM_EMBMEDANY"
1728 "or\t%1, %%ulo(%a2), %0")
1730 (define_insn "embmedany_textlo"
1731 [(set (match_operand:DI 0 "register_operand" "=r")
1732 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1733 (match_operand:DI 2 "text_segment_operand" "")))]
1734 "TARGET_CM_EMBMEDANY"
1735 "or\t%1, %%lo(%a2), %0")
1737 ;; Now some patterns to help reload out a bit.
1738 (define_expand "reload_indi"
1739 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1740 (match_operand:DI 1 "immediate_operand" "")
1741 (match_operand:TI 2 "register_operand" "=&r")])]
1743 || TARGET_CM_EMBMEDANY)
1746 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1750 (define_expand "reload_outdi"
1751 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1752 (match_operand:DI 1 "immediate_operand" "")
1753 (match_operand:TI 2 "register_operand" "=&r")])]
1755 || TARGET_CM_EMBMEDANY)
1758 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1762 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1764 [(set (match_operand:DI 0 "register_operand" "")
1765 (match_operand:DI 1 "const_int_operand" ""))]
1766 "! TARGET_ARCH64 && reload_completed"
1767 [(clobber (const_int 0))]
1769 #if HOST_BITS_PER_WIDE_INT == 32
1770 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1771 (INTVAL (operands[1]) < 0) ?
1774 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1777 unsigned int low, high;
1779 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1780 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1781 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1783 /* Slick... but this trick loses if this subreg constant part
1784 can be done in one insn. */
1786 && ! SPARC_SETHI32_P (high)
1787 && ! SPARC_SIMM13_P (high))
1788 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1789 gen_highpart (SImode, operands[0])));
1791 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1797 [(set (match_operand:DI 0 "register_operand" "")
1798 (match_operand:DI 1 "const_double_operand" ""))]
1802 && ((GET_CODE (operands[0]) == REG
1803 && REGNO (operands[0]) < 32)
1804 || (GET_CODE (operands[0]) == SUBREG
1805 && GET_CODE (SUBREG_REG (operands[0])) == REG
1806 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1807 [(clobber (const_int 0))]
1809 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1810 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1812 /* Slick... but this trick loses if this subreg constant part
1813 can be done in one insn. */
1814 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1815 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1816 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1818 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1819 gen_highpart (SImode, operands[0])));
1823 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1824 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1830 [(set (match_operand:DI 0 "register_operand" "")
1831 (match_operand:DI 1 "register_operand" ""))]
1835 && ((GET_CODE (operands[0]) == REG
1836 && REGNO (operands[0]) < 32)
1837 || (GET_CODE (operands[0]) == SUBREG
1838 && GET_CODE (SUBREG_REG (operands[0])) == REG
1839 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1840 [(clobber (const_int 0))]
1842 rtx set_dest = operands[0];
1843 rtx set_src = operands[1];
1847 dest1 = gen_highpart (SImode, set_dest);
1848 dest2 = gen_lowpart (SImode, set_dest);
1849 src1 = gen_highpart (SImode, set_src);
1850 src2 = gen_lowpart (SImode, set_src);
1852 /* Now emit using the real source and destination we found, swapping
1853 the order if we detect overlap. */
1854 if (reg_overlap_mentioned_p (dest1, src2))
1856 emit_insn (gen_movsi (dest2, src2));
1857 emit_insn (gen_movsi (dest1, src1));
1861 emit_insn (gen_movsi (dest1, src1));
1862 emit_insn (gen_movsi (dest2, src2));
1867 ;; Now handle the cases of memory moves from/to non-even
1868 ;; DI mode register pairs.
1870 [(set (match_operand:DI 0 "register_operand" "")
1871 (match_operand:DI 1 "memory_operand" ""))]
1874 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1875 [(clobber (const_int 0))]
1877 rtx word0 = adjust_address (operands[1], SImode, 0);
1878 rtx word1 = adjust_address (operands[1], SImode, 4);
1879 rtx high_part = gen_highpart (SImode, operands[0]);
1880 rtx low_part = gen_lowpart (SImode, operands[0]);
1882 if (reg_overlap_mentioned_p (high_part, word1))
1884 emit_insn (gen_movsi (low_part, word1));
1885 emit_insn (gen_movsi (high_part, word0));
1889 emit_insn (gen_movsi (high_part, word0));
1890 emit_insn (gen_movsi (low_part, word1));
1896 [(set (match_operand:DI 0 "memory_operand" "")
1897 (match_operand:DI 1 "register_operand" ""))]
1900 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1901 [(clobber (const_int 0))]
1903 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1904 gen_highpart (SImode, operands[1])));
1905 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1906 gen_lowpart (SImode, operands[1])));
1911 [(set (match_operand:DI 0 "memory_operand" "")
1912 (match_operand:DI 1 "const_zero_operand" ""))]
1916 && ! mem_min_alignment (operands[0], 8)))
1917 && offsettable_memref_p (operands[0])"
1918 [(clobber (const_int 0))]
1920 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1921 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1926 ;; Floating point and vector move instructions
1928 ;; Yes, you guessed it right, the former movsf expander.
1929 (define_expand "mov<V32:mode>"
1930 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1931 (match_operand:V32 1 "general_operand" ""))]
1932 "<V32:MODE>mode == SFmode || TARGET_VIS"
1934 if (sparc_expand_move (<V32:MODE>mode, operands))
1938 (define_insn "*movsf_insn"
1939 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1940 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1942 && (register_operand (operands[0], <V32:MODE>mode)
1943 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1945 if (GET_CODE (operands[1]) == CONST_DOUBLE
1946 && (which_alternative == 3
1947 || which_alternative == 4
1948 || which_alternative == 5))
1953 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1954 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1955 operands[1] = GEN_INT (i);
1958 switch (which_alternative)
1961 return "fzeros\t%0";
1965 return "fmovs\t%1, %0";
1967 return "mov\t%1, %0";
1969 return "sethi\t%%hi(%a1), %0";
1974 return "ld\t%1, %0";
1977 return "st\t%r1, %0";
1982 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1984 ;; Exactly the same as above, except that all `f' cases are deleted.
1985 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1988 (define_insn "*movsf_insn_no_fpu"
1989 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1990 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1992 && (register_operand (operands[0], SFmode)
1993 || register_or_zero_operand (operands[1], SFmode))"
1995 if (GET_CODE (operands[1]) == CONST_DOUBLE
1996 && (which_alternative == 0
1997 || which_alternative == 1
1998 || which_alternative == 2))
2003 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2004 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2005 operands[1] = GEN_INT (i);
2008 switch (which_alternative)
2011 return "mov\t%1, %0";
2013 return "sethi\t%%hi(%a1), %0";
2017 return "ld\t%1, %0";
2019 return "st\t%r1, %0";
2024 [(set_attr "type" "*,*,*,load,store")])
2026 ;; The following 3 patterns build SFmode constants in integer registers.
2028 (define_insn "*movsf_lo_sum"
2029 [(set (match_operand:SF 0 "register_operand" "=r")
2030 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2031 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2037 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2038 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2039 operands[2] = GEN_INT (i);
2040 return "or\t%1, %%lo(%a2), %0";
2043 (define_insn "*movsf_high"
2044 [(set (match_operand:SF 0 "register_operand" "=r")
2045 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2051 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2052 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2053 operands[1] = GEN_INT (i);
2054 return "sethi\t%%hi(%1), %0";
2058 [(set (match_operand:SF 0 "register_operand" "")
2059 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2060 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2061 [(set (match_dup 0) (high:SF (match_dup 1)))
2062 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2064 ;; Yes, you again guessed it right, the former movdf expander.
2065 (define_expand "mov<V64:mode>"
2066 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2067 (match_operand:V64 1 "general_operand" ""))]
2068 "<V64:MODE>mode == DFmode || TARGET_VIS"
2070 if (sparc_expand_move (<V64:MODE>mode, operands))
2074 ;; Be careful, fmovd does not exist when !v9.
2075 (define_insn "*movdf_insn_sp32"
2076 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2077 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2080 && (register_operand (operands[0], DFmode)
2081 || register_or_zero_operand (operands[1], DFmode))"
2093 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2094 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2096 (define_insn "*movdf_insn_sp32_no_fpu"
2097 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2098 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2101 && (register_operand (operands[0], DFmode)
2102 || register_or_zero_operand (operands[1], DFmode))"
2109 [(set_attr "type" "load,store,*,*,*")
2110 (set_attr "length" "*,*,2,2,2")])
2112 ;; We have available v9 double floats but not 64-bit integer registers.
2113 (define_insn "*movdf_insn_sp32_v9"
2114 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2115 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2119 && (register_operand (operands[0], <V64:MODE>mode)
2120 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2133 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2134 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2135 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2137 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2138 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2139 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2143 && (register_operand (operands[0], DFmode)
2144 || register_or_zero_operand (operands[1], DFmode))"
2151 [(set_attr "type" "load,store,store,*,*")
2152 (set_attr "length" "*,*,*,2,2")])
2154 ;; We have available both v9 double floats and 64-bit integer registers.
2155 (define_insn "*movdf_insn_sp64"
2156 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2157 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2160 && (register_operand (operands[0], <V64:MODE>mode)
2161 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2172 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2173 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2174 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2176 (define_insn "*movdf_insn_sp64_no_fpu"
2177 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2178 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2181 && (register_operand (operands[0], DFmode)
2182 || register_or_zero_operand (operands[1], DFmode))"
2187 [(set_attr "type" "*,load,store")])
2189 ;; This pattern builds V64mode constants in integer registers.
2191 [(set (match_operand:V64 0 "register_operand" "")
2192 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2194 && (GET_CODE (operands[0]) == REG
2195 && REGNO (operands[0]) < 32)
2196 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2197 && reload_completed"
2198 [(clobber (const_int 0))]
2200 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2204 #if HOST_BITS_PER_WIDE_INT == 32
2207 enum machine_mode mode = GET_MODE (operands[1]);
2208 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2209 emit_insn (gen_movdi (operands[0], tem));
2214 enum machine_mode mode = GET_MODE (operands[1]);
2215 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2216 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2218 gcc_assert (GET_CODE (hi) == CONST_INT);
2219 gcc_assert (GET_CODE (lo) == CONST_INT);
2221 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2223 /* Slick... but this trick loses if this subreg constant part
2224 can be done in one insn. */
2226 && ! SPARC_SETHI32_P (INTVAL (hi))
2227 && ! SPARC_SIMM13_P (INTVAL (hi)))
2229 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2230 gen_highpart (SImode, operands[0])));
2234 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2240 ;; Ok, now the splits to handle all the multi insn and
2241 ;; mis-aligned memory address cases.
2242 ;; In these splits please take note that we must be
2243 ;; careful when V9 but not ARCH64 because the integer
2244 ;; register DFmode cases must be handled.
2246 [(set (match_operand:V64 0 "register_operand" "")
2247 (match_operand:V64 1 "register_operand" ""))]
2250 && ((GET_CODE (operands[0]) == REG
2251 && REGNO (operands[0]) < 32)
2252 || (GET_CODE (operands[0]) == SUBREG
2253 && GET_CODE (SUBREG_REG (operands[0])) == REG
2254 && REGNO (SUBREG_REG (operands[0])) < 32))))
2255 && reload_completed"
2256 [(clobber (const_int 0))]
2258 rtx set_dest = operands[0];
2259 rtx set_src = operands[1];
2262 enum machine_mode half_mode;
2264 /* We can be expanded for DFmode or integral vector modes. */
2265 if (<V64:MODE>mode == DFmode)
2270 dest1 = gen_highpart (half_mode, set_dest);
2271 dest2 = gen_lowpart (half_mode, set_dest);
2272 src1 = gen_highpart (half_mode, set_src);
2273 src2 = gen_lowpart (half_mode, set_src);
2275 /* Now emit using the real source and destination we found, swapping
2276 the order if we detect overlap. */
2277 if (reg_overlap_mentioned_p (dest1, src2))
2279 emit_move_insn_1 (dest2, src2);
2280 emit_move_insn_1 (dest1, src1);
2284 emit_move_insn_1 (dest1, src1);
2285 emit_move_insn_1 (dest2, src2);
2291 [(set (match_operand:V64 0 "register_operand" "")
2292 (match_operand:V64 1 "memory_operand" ""))]
2295 && (((REGNO (operands[0]) % 2) != 0)
2296 || ! mem_min_alignment (operands[1], 8))
2297 && offsettable_memref_p (operands[1])"
2298 [(clobber (const_int 0))]
2300 enum machine_mode half_mode;
2303 /* We can be expanded for DFmode or integral vector modes. */
2304 if (<V64:MODE>mode == DFmode)
2309 word0 = adjust_address (operands[1], half_mode, 0);
2310 word1 = adjust_address (operands[1], half_mode, 4);
2312 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2314 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2315 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2319 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2320 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2326 [(set (match_operand:V64 0 "memory_operand" "")
2327 (match_operand:V64 1 "register_operand" ""))]
2330 && (((REGNO (operands[1]) % 2) != 0)
2331 || ! mem_min_alignment (operands[0], 8))
2332 && offsettable_memref_p (operands[0])"
2333 [(clobber (const_int 0))]
2335 enum machine_mode half_mode;
2338 /* We can be expanded for DFmode or integral vector modes. */
2339 if (<V64:MODE>mode == DFmode)
2344 word0 = adjust_address (operands[0], half_mode, 0);
2345 word1 = adjust_address (operands[0], half_mode, 4);
2347 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2348 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2353 [(set (match_operand:V64 0 "memory_operand" "")
2354 (match_operand:V64 1 "const_zero_operand" ""))]
2358 && ! mem_min_alignment (operands[0], 8)))
2359 && offsettable_memref_p (operands[0])"
2360 [(clobber (const_int 0))]
2362 enum machine_mode half_mode;
2365 /* We can be expanded for DFmode or integral vector modes. */
2366 if (<V64:MODE>mode == DFmode)
2371 dest1 = adjust_address (operands[0], half_mode, 0);
2372 dest2 = adjust_address (operands[0], half_mode, 4);
2374 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2375 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2380 [(set (match_operand:V64 0 "register_operand" "")
2381 (match_operand:V64 1 "const_zero_operand" ""))]
2384 && ((GET_CODE (operands[0]) == REG
2385 && REGNO (operands[0]) < 32)
2386 || (GET_CODE (operands[0]) == SUBREG
2387 && GET_CODE (SUBREG_REG (operands[0])) == REG
2388 && REGNO (SUBREG_REG (operands[0])) < 32))"
2389 [(clobber (const_int 0))]
2391 enum machine_mode half_mode;
2392 rtx set_dest = operands[0];
2395 /* We can be expanded for DFmode or integral vector modes. */
2396 if (<V64:MODE>mode == DFmode)
2401 dest1 = gen_highpart (half_mode, set_dest);
2402 dest2 = gen_lowpart (half_mode, set_dest);
2403 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2404 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2408 (define_expand "movtf"
2409 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2410 (match_operand:TF 1 "general_operand" ""))]
2413 if (sparc_expand_move (TFmode, operands))
2417 (define_insn "*movtf_insn_sp32"
2418 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2419 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2422 && (register_operand (operands[0], TFmode)
2423 || register_or_zero_operand (operands[1], TFmode))"
2425 [(set_attr "length" "4")])
2427 ;; Exactly the same as above, except that all `e' cases are deleted.
2428 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2431 (define_insn "*movtf_insn_sp32_no_fpu"
2432 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2433 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2436 && (register_operand (operands[0], TFmode)
2437 || register_or_zero_operand (operands[1], TFmode))"
2439 [(set_attr "length" "4")])
2441 (define_insn "*movtf_insn_sp64"
2442 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2443 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2446 && ! TARGET_HARD_QUAD
2447 && (register_operand (operands[0], TFmode)
2448 || register_or_zero_operand (operands[1], TFmode))"
2450 [(set_attr "length" "2")])
2452 (define_insn "*movtf_insn_sp64_hq"
2453 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2454 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2458 && (register_operand (operands[0], TFmode)
2459 || register_or_zero_operand (operands[1], TFmode))"
2467 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2468 (set_attr "length" "2,*,*,*,2,2")])
2470 (define_insn "*movtf_insn_sp64_no_fpu"
2471 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2472 (match_operand:TF 1 "input_operand" "orG,rG"))]
2475 && (register_operand (operands[0], TFmode)
2476 || register_or_zero_operand (operands[1], TFmode))"
2478 [(set_attr "length" "2")])
2480 ;; Now all the splits to handle multi-insn TF mode moves.
2482 [(set (match_operand:TF 0 "register_operand" "")
2483 (match_operand:TF 1 "register_operand" ""))]
2487 && ! TARGET_HARD_QUAD)
2488 || ! fp_register_operand (operands[0], TFmode))"
2489 [(clobber (const_int 0))]
2491 rtx set_dest = operands[0];
2492 rtx set_src = operands[1];
2496 dest1 = gen_df_reg (set_dest, 0);
2497 dest2 = gen_df_reg (set_dest, 1);
2498 src1 = gen_df_reg (set_src, 0);
2499 src2 = gen_df_reg (set_src, 1);
2501 /* Now emit using the real source and destination we found, swapping
2502 the order if we detect overlap. */
2503 if (reg_overlap_mentioned_p (dest1, src2))
2505 emit_insn (gen_movdf (dest2, src2));
2506 emit_insn (gen_movdf (dest1, src1));
2510 emit_insn (gen_movdf (dest1, src1));
2511 emit_insn (gen_movdf (dest2, src2));
2517 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2518 (match_operand:TF 1 "const_zero_operand" ""))]
2520 [(clobber (const_int 0))]
2522 rtx set_dest = operands[0];
2525 switch (GET_CODE (set_dest))
2528 dest1 = gen_df_reg (set_dest, 0);
2529 dest2 = gen_df_reg (set_dest, 1);
2532 dest1 = adjust_address (set_dest, DFmode, 0);
2533 dest2 = adjust_address (set_dest, DFmode, 8);
2539 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2540 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2545 [(set (match_operand:TF 0 "register_operand" "")
2546 (match_operand:TF 1 "memory_operand" ""))]
2548 && offsettable_memref_p (operands[1])
2550 || ! TARGET_HARD_QUAD
2551 || ! fp_register_operand (operands[0], TFmode)))"
2552 [(clobber (const_int 0))]
2554 rtx word0 = adjust_address (operands[1], DFmode, 0);
2555 rtx word1 = adjust_address (operands[1], DFmode, 8);
2556 rtx set_dest, dest1, dest2;
2558 set_dest = operands[0];
2560 dest1 = gen_df_reg (set_dest, 0);
2561 dest2 = gen_df_reg (set_dest, 1);
2563 /* Now output, ordering such that we don't clobber any registers
2564 mentioned in the address. */
2565 if (reg_overlap_mentioned_p (dest1, word1))
2568 emit_insn (gen_movdf (dest2, word1));
2569 emit_insn (gen_movdf (dest1, word0));
2573 emit_insn (gen_movdf (dest1, word0));
2574 emit_insn (gen_movdf (dest2, word1));
2580 [(set (match_operand:TF 0 "memory_operand" "")
2581 (match_operand:TF 1 "register_operand" ""))]
2583 && offsettable_memref_p (operands[0])
2585 || ! TARGET_HARD_QUAD
2586 || ! fp_register_operand (operands[1], TFmode)))"
2587 [(clobber (const_int 0))]
2589 rtx set_src = operands[1];
2591 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2592 gen_df_reg (set_src, 0)));
2593 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2594 gen_df_reg (set_src, 1)));
2599 ;; SPARC-V9 conditional move instructions
2601 ;; We can handle larger constants here for some flavors, but for now we keep
2602 ;; it simple and only allow those constants supported by all flavors.
2603 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2604 ;; 3 contains the constant if one is present, but we handle either for
2605 ;; generality (sparc.c puts a constant in operand 2).
2607 (define_expand "mov<I:mode>cc"
2608 [(set (match_operand:I 0 "register_operand" "")
2609 (if_then_else:I (match_operand 1 "comparison_operator" "")
2610 (match_operand:I 2 "arith10_operand" "")
2611 (match_operand:I 3 "arith10_operand" "")))]
2612 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2614 enum rtx_code code = GET_CODE (operands[1]);
2617 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2621 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2623 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2624 GET_CODE (operands[1]));
2626 if (XEXP (operands[1], 1) == const0_rtx
2627 && GET_CODE (XEXP (operands[1], 0)) == REG
2628 && GET_MODE (XEXP (operands[1], 0)) == DImode
2629 && v9_regcmp_p (code))
2630 cc_reg = XEXP (operands[1], 0);
2632 cc_reg = gen_compare_reg (operands[1]);
2634 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2637 (define_expand "mov<F:mode>cc"
2638 [(set (match_operand:F 0 "register_operand" "")
2639 (if_then_else:F (match_operand 1 "comparison_operator" "")
2640 (match_operand:F 2 "register_operand" "")
2641 (match_operand:F 3 "register_operand" "")))]
2642 "TARGET_V9 && TARGET_FPU"
2644 enum rtx_code code = GET_CODE (operands[1]);
2647 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2651 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2653 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2654 GET_CODE (operands[1]));
2656 if (XEXP (operands[1], 1) == const0_rtx
2657 && GET_CODE (XEXP (operands[1], 0)) == REG
2658 && GET_MODE (XEXP (operands[1], 0)) == DImode
2659 && v9_regcmp_p (code))
2660 cc_reg = XEXP (operands[1], 0);
2662 cc_reg = gen_compare_reg (operands[1]);
2664 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2667 ;; Conditional move define_insns
2669 (define_insn "*mov<I:mode>_cc_v9"
2670 [(set (match_operand:I 0 "register_operand" "=r,r")
2671 (if_then_else:I (match_operator 1 "comparison_operator"
2672 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2674 (match_operand:I 3 "arith11_operand" "rL,0")
2675 (match_operand:I 4 "arith11_operand" "0,rL")))]
2676 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2679 mov%c1\t%x2, %4, %0"
2680 [(set_attr "type" "cmove")])
2682 (define_insn "*mov<I:mode>_cc_reg_sp64"
2683 [(set (match_operand:I 0 "register_operand" "=r,r")
2684 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2685 [(match_operand:DI 2 "register_operand" "r,r")
2687 (match_operand:I 3 "arith10_operand" "rM,0")
2688 (match_operand:I 4 "arith10_operand" "0,rM")))]
2691 movr%D1\t%2, %r3, %0
2692 movr%d1\t%2, %r4, %0"
2693 [(set_attr "type" "cmove")])
2695 (define_insn "*movsf_cc_v9"
2696 [(set (match_operand:SF 0 "register_operand" "=f,f")
2697 (if_then_else:SF (match_operator 1 "comparison_operator"
2698 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2700 (match_operand:SF 3 "register_operand" "f,0")
2701 (match_operand:SF 4 "register_operand" "0,f")))]
2702 "TARGET_V9 && TARGET_FPU"
2704 fmovs%C1\t%x2, %3, %0
2705 fmovs%c1\t%x2, %4, %0"
2706 [(set_attr "type" "fpcmove")])
2708 (define_insn "*movsf_cc_reg_sp64"
2709 [(set (match_operand:SF 0 "register_operand" "=f,f")
2710 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2711 [(match_operand:DI 2 "register_operand" "r,r")
2713 (match_operand:SF 3 "register_operand" "f,0")
2714 (match_operand:SF 4 "register_operand" "0,f")))]
2715 "TARGET_ARCH64 && TARGET_FPU"
2717 fmovrs%D1\t%2, %3, %0
2718 fmovrs%d1\t%2, %4, %0"
2719 [(set_attr "type" "fpcrmove")])
2721 ;; Named because invoked by movtf_cc_v9
2722 (define_insn "movdf_cc_v9"
2723 [(set (match_operand:DF 0 "register_operand" "=e,e")
2724 (if_then_else:DF (match_operator 1 "comparison_operator"
2725 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2727 (match_operand:DF 3 "register_operand" "e,0")
2728 (match_operand:DF 4 "register_operand" "0,e")))]
2729 "TARGET_V9 && TARGET_FPU"
2731 fmovd%C1\t%x2, %3, %0
2732 fmovd%c1\t%x2, %4, %0"
2733 [(set_attr "type" "fpcmove")
2734 (set_attr "fptype" "double")])
2736 ;; Named because invoked by movtf_cc_reg_sp64
2737 (define_insn "movdf_cc_reg_sp64"
2738 [(set (match_operand:DF 0 "register_operand" "=e,e")
2739 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2740 [(match_operand:DI 2 "register_operand" "r,r")
2742 (match_operand:DF 3 "register_operand" "e,0")
2743 (match_operand:DF 4 "register_operand" "0,e")))]
2744 "TARGET_ARCH64 && TARGET_FPU"
2746 fmovrd%D1\t%2, %3, %0
2747 fmovrd%d1\t%2, %4, %0"
2748 [(set_attr "type" "fpcrmove")
2749 (set_attr "fptype" "double")])
2751 (define_insn "*movtf_cc_hq_v9"
2752 [(set (match_operand:TF 0 "register_operand" "=e,e")
2753 (if_then_else:TF (match_operator 1 "comparison_operator"
2754 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2756 (match_operand:TF 3 "register_operand" "e,0")
2757 (match_operand:TF 4 "register_operand" "0,e")))]
2758 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2760 fmovq%C1\t%x2, %3, %0
2761 fmovq%c1\t%x2, %4, %0"
2762 [(set_attr "type" "fpcmove")])
2764 (define_insn "*movtf_cc_reg_hq_sp64"
2765 [(set (match_operand:TF 0 "register_operand" "=e,e")
2766 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2767 [(match_operand:DI 2 "register_operand" "r,r")
2769 (match_operand:TF 3 "register_operand" "e,0")
2770 (match_operand:TF 4 "register_operand" "0,e")))]
2771 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2773 fmovrq%D1\t%2, %3, %0
2774 fmovrq%d1\t%2, %4, %0"
2775 [(set_attr "type" "fpcrmove")])
2777 (define_insn_and_split "*movtf_cc_v9"
2778 [(set (match_operand:TF 0 "register_operand" "=e,e")
2779 (if_then_else:TF (match_operator 1 "comparison_operator"
2780 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2782 (match_operand:TF 3 "register_operand" "e,0")
2783 (match_operand:TF 4 "register_operand" "0,e")))]
2784 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2786 "&& reload_completed"
2787 [(clobber (const_int 0))]
2789 rtx set_dest = operands[0];
2790 rtx set_srca = operands[3];
2791 rtx set_srcb = operands[4];
2792 int third = rtx_equal_p (set_dest, set_srca);
2794 rtx srca1, srca2, srcb1, srcb2;
2796 dest1 = gen_df_reg (set_dest, 0);
2797 dest2 = gen_df_reg (set_dest, 1);
2798 srca1 = gen_df_reg (set_srca, 0);
2799 srca2 = gen_df_reg (set_srca, 1);
2800 srcb1 = gen_df_reg (set_srcb, 0);
2801 srcb2 = gen_df_reg (set_srcb, 1);
2803 /* Now emit using the real source and destination we found, swapping
2804 the order if we detect overlap. */
2805 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2806 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2808 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2809 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2813 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2814 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2818 [(set_attr "length" "2")])
2820 (define_insn_and_split "*movtf_cc_reg_sp64"
2821 [(set (match_operand:TF 0 "register_operand" "=e,e")
2822 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2823 [(match_operand:DI 2 "register_operand" "r,r")
2825 (match_operand:TF 3 "register_operand" "e,0")
2826 (match_operand:TF 4 "register_operand" "0,e")))]
2827 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2829 "&& reload_completed"
2830 [(clobber (const_int 0))]
2832 rtx set_dest = operands[0];
2833 rtx set_srca = operands[3];
2834 rtx set_srcb = operands[4];
2835 int third = rtx_equal_p (set_dest, set_srca);
2837 rtx srca1, srca2, srcb1, srcb2;
2839 dest1 = gen_df_reg (set_dest, 0);
2840 dest2 = gen_df_reg (set_dest, 1);
2841 srca1 = gen_df_reg (set_srca, 0);
2842 srca2 = gen_df_reg (set_srca, 1);
2843 srcb1 = gen_df_reg (set_srcb, 0);
2844 srcb2 = gen_df_reg (set_srcb, 1);
2846 /* Now emit using the real source and destination we found, swapping
2847 the order if we detect overlap. */
2848 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2849 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2851 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2852 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2856 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2857 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2861 [(set_attr "length" "2")])
2864 ;; Zero-extension instructions
2866 ;; These patterns originally accepted general_operands, however, slightly
2867 ;; better code is generated by only accepting register_operands, and then
2868 ;; letting combine generate the ldu[hb] insns.
2870 (define_expand "zero_extendhisi2"
2871 [(set (match_operand:SI 0 "register_operand" "")
2872 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2875 rtx temp = gen_reg_rtx (SImode);
2876 rtx shift_16 = GEN_INT (16);
2877 int op1_subbyte = 0;
2879 if (GET_CODE (operand1) == SUBREG)
2881 op1_subbyte = SUBREG_BYTE (operand1);
2882 op1_subbyte /= GET_MODE_SIZE (SImode);
2883 op1_subbyte *= GET_MODE_SIZE (SImode);
2884 operand1 = XEXP (operand1, 0);
2887 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2889 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2893 (define_insn "*zero_extendhisi2_insn"
2894 [(set (match_operand:SI 0 "register_operand" "=r")
2895 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2898 [(set_attr "type" "load")
2899 (set_attr "us3load_type" "3cycle")])
2901 (define_expand "zero_extendqihi2"
2902 [(set (match_operand:HI 0 "register_operand" "")
2903 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2907 (define_insn "*zero_extendqihi2_insn"
2908 [(set (match_operand:HI 0 "register_operand" "=r,r")
2909 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2910 "GET_CODE (operands[1]) != CONST_INT"
2914 [(set_attr "type" "*,load")
2915 (set_attr "us3load_type" "*,3cycle")])
2917 (define_expand "zero_extendqisi2"
2918 [(set (match_operand:SI 0 "register_operand" "")
2919 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2923 (define_insn "*zero_extendqisi2_insn"
2924 [(set (match_operand:SI 0 "register_operand" "=r,r")
2925 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2926 "GET_CODE (operands[1]) != CONST_INT"
2930 [(set_attr "type" "*,load")
2931 (set_attr "us3load_type" "*,3cycle")])
2933 (define_expand "zero_extendqidi2"
2934 [(set (match_operand:DI 0 "register_operand" "")
2935 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2939 (define_insn "*zero_extendqidi2_insn"
2940 [(set (match_operand:DI 0 "register_operand" "=r,r")
2941 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2942 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2946 [(set_attr "type" "*,load")
2947 (set_attr "us3load_type" "*,3cycle")])
2949 (define_expand "zero_extendhidi2"
2950 [(set (match_operand:DI 0 "register_operand" "")
2951 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2954 rtx temp = gen_reg_rtx (DImode);
2955 rtx shift_48 = GEN_INT (48);
2956 int op1_subbyte = 0;
2958 if (GET_CODE (operand1) == SUBREG)
2960 op1_subbyte = SUBREG_BYTE (operand1);
2961 op1_subbyte /= GET_MODE_SIZE (DImode);
2962 op1_subbyte *= GET_MODE_SIZE (DImode);
2963 operand1 = XEXP (operand1, 0);
2966 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2968 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2972 (define_insn "*zero_extendhidi2_insn"
2973 [(set (match_operand:DI 0 "register_operand" "=r")
2974 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2977 [(set_attr "type" "load")
2978 (set_attr "us3load_type" "3cycle")])
2980 ;; ??? Write truncdisi pattern using sra?
2982 (define_expand "zero_extendsidi2"
2983 [(set (match_operand:DI 0 "register_operand" "")
2984 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2988 (define_insn "*zero_extendsidi2_insn_sp64"
2989 [(set (match_operand:DI 0 "register_operand" "=r,r")
2990 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2991 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2995 [(set_attr "type" "shift,load")])
2997 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2998 [(set (match_operand:DI 0 "register_operand" "=r")
2999 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3002 "&& reload_completed"
3003 [(set (match_dup 2) (match_dup 3))
3004 (set (match_dup 4) (match_dup 5))]
3008 dest1 = gen_highpart (SImode, operands[0]);
3009 dest2 = gen_lowpart (SImode, operands[0]);
3011 /* Swap the order in case of overlap. */
3012 if (REGNO (dest1) == REGNO (operands[1]))
3014 operands[2] = dest2;
3015 operands[3] = operands[1];
3016 operands[4] = dest1;
3017 operands[5] = const0_rtx;
3021 operands[2] = dest1;
3022 operands[3] = const0_rtx;
3023 operands[4] = dest2;
3024 operands[5] = operands[1];
3027 [(set_attr "length" "2")])
3029 ;; Simplify comparisons of extended values.
3031 (define_insn "*cmp_zero_extendqisi2"
3032 [(set (reg:CC CC_REG)
3033 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3036 "andcc\t%0, 0xff, %%g0"
3037 [(set_attr "type" "compare")])
3039 (define_insn "*cmp_zero_qi"
3040 [(set (reg:CC CC_REG)
3041 (compare:CC (match_operand:QI 0 "register_operand" "r")
3044 "andcc\t%0, 0xff, %%g0"
3045 [(set_attr "type" "compare")])
3047 (define_insn "*cmp_zero_extendqisi2_set"
3048 [(set (reg:CC CC_REG)
3049 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3051 (set (match_operand:SI 0 "register_operand" "=r")
3052 (zero_extend:SI (match_dup 1)))]
3054 "andcc\t%1, 0xff, %0"
3055 [(set_attr "type" "compare")])
3057 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3058 [(set (reg:CC CC_REG)
3059 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3062 (set (match_operand:SI 0 "register_operand" "=r")
3063 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3065 "andcc\t%1, 0xff, %0"
3066 [(set_attr "type" "compare")])
3068 (define_insn "*cmp_zero_extendqidi2"
3069 [(set (reg:CCX CC_REG)
3070 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3073 "andcc\t%0, 0xff, %%g0"
3074 [(set_attr "type" "compare")])
3076 (define_insn "*cmp_zero_qi_sp64"
3077 [(set (reg:CCX CC_REG)
3078 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3081 "andcc\t%0, 0xff, %%g0"
3082 [(set_attr "type" "compare")])
3084 (define_insn "*cmp_zero_extendqidi2_set"
3085 [(set (reg:CCX CC_REG)
3086 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3088 (set (match_operand:DI 0 "register_operand" "=r")
3089 (zero_extend:DI (match_dup 1)))]
3091 "andcc\t%1, 0xff, %0"
3092 [(set_attr "type" "compare")])
3094 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3095 [(set (reg:CCX CC_REG)
3096 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3099 (set (match_operand:DI 0 "register_operand" "=r")
3100 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3102 "andcc\t%1, 0xff, %0"
3103 [(set_attr "type" "compare")])
3105 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3107 (define_insn "*cmp_siqi_trunc"
3108 [(set (reg:CC CC_REG)
3109 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3112 "andcc\t%0, 0xff, %%g0"
3113 [(set_attr "type" "compare")])
3115 (define_insn "*cmp_siqi_trunc_set"
3116 [(set (reg:CC CC_REG)
3117 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3119 (set (match_operand:QI 0 "register_operand" "=r")
3120 (subreg:QI (match_dup 1) 3))]
3122 "andcc\t%1, 0xff, %0"
3123 [(set_attr "type" "compare")])
3125 (define_insn "*cmp_diqi_trunc"
3126 [(set (reg:CC CC_REG)
3127 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3130 "andcc\t%0, 0xff, %%g0"
3131 [(set_attr "type" "compare")])
3133 (define_insn "*cmp_diqi_trunc_set"
3134 [(set (reg:CC CC_REG)
3135 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3137 (set (match_operand:QI 0 "register_operand" "=r")
3138 (subreg:QI (match_dup 1) 7))]
3140 "andcc\t%1, 0xff, %0"
3141 [(set_attr "type" "compare")])
3144 ;; Sign-extension instructions
3146 ;; These patterns originally accepted general_operands, however, slightly
3147 ;; better code is generated by only accepting register_operands, and then
3148 ;; letting combine generate the lds[hb] insns.
3150 (define_expand "extendhisi2"
3151 [(set (match_operand:SI 0 "register_operand" "")
3152 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3155 rtx temp = gen_reg_rtx (SImode);
3156 rtx shift_16 = GEN_INT (16);
3157 int op1_subbyte = 0;
3159 if (GET_CODE (operand1) == SUBREG)
3161 op1_subbyte = SUBREG_BYTE (operand1);
3162 op1_subbyte /= GET_MODE_SIZE (SImode);
3163 op1_subbyte *= GET_MODE_SIZE (SImode);
3164 operand1 = XEXP (operand1, 0);
3167 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3169 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3173 (define_insn "*sign_extendhisi2_insn"
3174 [(set (match_operand:SI 0 "register_operand" "=r")
3175 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3178 [(set_attr "type" "sload")
3179 (set_attr "us3load_type" "3cycle")])
3181 (define_expand "extendqihi2"
3182 [(set (match_operand:HI 0 "register_operand" "")
3183 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3186 rtx temp = gen_reg_rtx (SImode);
3187 rtx shift_24 = GEN_INT (24);
3188 int op1_subbyte = 0;
3189 int op0_subbyte = 0;
3191 if (GET_CODE (operand1) == SUBREG)
3193 op1_subbyte = SUBREG_BYTE (operand1);
3194 op1_subbyte /= GET_MODE_SIZE (SImode);
3195 op1_subbyte *= GET_MODE_SIZE (SImode);
3196 operand1 = XEXP (operand1, 0);
3198 if (GET_CODE (operand0) == SUBREG)
3200 op0_subbyte = SUBREG_BYTE (operand0);
3201 op0_subbyte /= GET_MODE_SIZE (SImode);
3202 op0_subbyte *= GET_MODE_SIZE (SImode);
3203 operand0 = XEXP (operand0, 0);
3205 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3207 if (GET_MODE (operand0) != SImode)
3208 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3209 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3213 (define_insn "*sign_extendqihi2_insn"
3214 [(set (match_operand:HI 0 "register_operand" "=r")
3215 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3218 [(set_attr "type" "sload")
3219 (set_attr "us3load_type" "3cycle")])
3221 (define_expand "extendqisi2"
3222 [(set (match_operand:SI 0 "register_operand" "")
3223 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3226 rtx temp = gen_reg_rtx (SImode);
3227 rtx shift_24 = GEN_INT (24);
3228 int op1_subbyte = 0;
3230 if (GET_CODE (operand1) == SUBREG)
3232 op1_subbyte = SUBREG_BYTE (operand1);
3233 op1_subbyte /= GET_MODE_SIZE (SImode);
3234 op1_subbyte *= GET_MODE_SIZE (SImode);
3235 operand1 = XEXP (operand1, 0);
3238 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3240 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3244 (define_insn "*sign_extendqisi2_insn"
3245 [(set (match_operand:SI 0 "register_operand" "=r")
3246 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3249 [(set_attr "type" "sload")
3250 (set_attr "us3load_type" "3cycle")])
3252 (define_expand "extendqidi2"
3253 [(set (match_operand:DI 0 "register_operand" "")
3254 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3257 rtx temp = gen_reg_rtx (DImode);
3258 rtx shift_56 = GEN_INT (56);
3259 int op1_subbyte = 0;
3261 if (GET_CODE (operand1) == SUBREG)
3263 op1_subbyte = SUBREG_BYTE (operand1);
3264 op1_subbyte /= GET_MODE_SIZE (DImode);
3265 op1_subbyte *= GET_MODE_SIZE (DImode);
3266 operand1 = XEXP (operand1, 0);
3269 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3271 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3275 (define_insn "*sign_extendqidi2_insn"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3280 [(set_attr "type" "sload")
3281 (set_attr "us3load_type" "3cycle")])
3283 (define_expand "extendhidi2"
3284 [(set (match_operand:DI 0 "register_operand" "")
3285 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3288 rtx temp = gen_reg_rtx (DImode);
3289 rtx shift_48 = GEN_INT (48);
3290 int op1_subbyte = 0;
3292 if (GET_CODE (operand1) == SUBREG)
3294 op1_subbyte = SUBREG_BYTE (operand1);
3295 op1_subbyte /= GET_MODE_SIZE (DImode);
3296 op1_subbyte *= GET_MODE_SIZE (DImode);
3297 operand1 = XEXP (operand1, 0);
3300 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3302 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3306 (define_insn "*sign_extendhidi2_insn"
3307 [(set (match_operand:DI 0 "register_operand" "=r")
3308 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3311 [(set_attr "type" "sload")
3312 (set_attr "us3load_type" "3cycle")])
3314 (define_expand "extendsidi2"
3315 [(set (match_operand:DI 0 "register_operand" "")
3316 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3320 (define_insn "*sign_extendsidi2_insn"
3321 [(set (match_operand:DI 0 "register_operand" "=r,r")
3322 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3327 [(set_attr "type" "shift,sload")
3328 (set_attr "us3load_type" "*,3cycle")])
3331 ;; Special pattern for optimizing bit-field compares. This is needed
3332 ;; because combine uses this as a canonical form.
3334 (define_insn "*cmp_zero_extract"
3335 [(set (reg:CC CC_REG)
3337 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3338 (match_operand:SI 1 "small_int_operand" "I")
3339 (match_operand:SI 2 "small_int_operand" "I"))
3341 "INTVAL (operands[2]) > 19"
3343 int len = INTVAL (operands[1]);
3344 int pos = 32 - INTVAL (operands[2]) - len;
3345 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3346 operands[1] = GEN_INT (mask);
3347 return "andcc\t%0, %1, %%g0";
3349 [(set_attr "type" "compare")])
3351 (define_insn "*cmp_zero_extract_sp64"
3352 [(set (reg:CCX CC_REG)
3354 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3355 (match_operand:SI 1 "small_int_operand" "I")
3356 (match_operand:SI 2 "small_int_operand" "I"))
3358 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3360 int len = INTVAL (operands[1]);
3361 int pos = 64 - INTVAL (operands[2]) - len;
3362 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3363 operands[1] = GEN_INT (mask);
3364 return "andcc\t%0, %1, %%g0";
3366 [(set_attr "type" "compare")])
3369 ;; Conversions between float, double and long double.
3371 (define_insn "extendsfdf2"
3372 [(set (match_operand:DF 0 "register_operand" "=e")
3374 (match_operand:SF 1 "register_operand" "f")))]
3377 [(set_attr "type" "fp")
3378 (set_attr "fptype" "double")])
3380 (define_expand "extendsftf2"
3381 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3383 (match_operand:SF 1 "register_operand" "")))]
3384 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3385 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3387 (define_insn "*extendsftf2_hq"
3388 [(set (match_operand:TF 0 "register_operand" "=e")
3390 (match_operand:SF 1 "register_operand" "f")))]
3391 "TARGET_FPU && TARGET_HARD_QUAD"
3393 [(set_attr "type" "fp")])
3395 (define_expand "extenddftf2"
3396 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3398 (match_operand:DF 1 "register_operand" "")))]
3399 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3400 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3402 (define_insn "*extenddftf2_hq"
3403 [(set (match_operand:TF 0 "register_operand" "=e")
3405 (match_operand:DF 1 "register_operand" "e")))]
3406 "TARGET_FPU && TARGET_HARD_QUAD"
3408 [(set_attr "type" "fp")])
3410 (define_insn "truncdfsf2"
3411 [(set (match_operand:SF 0 "register_operand" "=f")
3413 (match_operand:DF 1 "register_operand" "e")))]
3416 [(set_attr "type" "fp")
3417 (set_attr "fptype" "double")])
3419 (define_expand "trunctfsf2"
3420 [(set (match_operand:SF 0 "register_operand" "")
3422 (match_operand:TF 1 "general_operand" "")))]
3423 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3424 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3426 (define_insn "*trunctfsf2_hq"
3427 [(set (match_operand:SF 0 "register_operand" "=f")
3429 (match_operand:TF 1 "register_operand" "e")))]
3430 "TARGET_FPU && TARGET_HARD_QUAD"
3432 [(set_attr "type" "fp")])
3434 (define_expand "trunctfdf2"
3435 [(set (match_operand:DF 0 "register_operand" "")
3437 (match_operand:TF 1 "general_operand" "")))]
3438 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3439 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3441 (define_insn "*trunctfdf2_hq"
3442 [(set (match_operand:DF 0 "register_operand" "=e")
3444 (match_operand:TF 1 "register_operand" "e")))]
3445 "TARGET_FPU && TARGET_HARD_QUAD"
3447 [(set_attr "type" "fp")])
3450 ;; Conversion between fixed point and floating point.
3452 (define_insn "floatsisf2"
3453 [(set (match_operand:SF 0 "register_operand" "=f")
3454 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3457 [(set_attr "type" "fp")
3458 (set_attr "fptype" "double")])
3460 (define_insn "floatsidf2"
3461 [(set (match_operand:DF 0 "register_operand" "=e")
3462 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3465 [(set_attr "type" "fp")
3466 (set_attr "fptype" "double")])
3468 (define_expand "floatsitf2"
3469 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3470 (float:TF (match_operand:SI 1 "register_operand" "")))]
3471 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3472 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3474 (define_insn "*floatsitf2_hq"
3475 [(set (match_operand:TF 0 "register_operand" "=e")
3476 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3477 "TARGET_FPU && TARGET_HARD_QUAD"
3479 [(set_attr "type" "fp")])
3481 (define_expand "floatunssitf2"
3482 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3483 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3484 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3485 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3487 ;; Now the same for 64 bit sources.
3489 (define_insn "floatdisf2"
3490 [(set (match_operand:SF 0 "register_operand" "=f")
3491 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3492 "TARGET_V9 && TARGET_FPU"
3494 [(set_attr "type" "fp")
3495 (set_attr "fptype" "double")])
3497 (define_expand "floatunsdisf2"
3498 [(use (match_operand:SF 0 "register_operand" ""))
3499 (use (match_operand:DI 1 "general_operand" ""))]
3500 "TARGET_ARCH64 && TARGET_FPU"
3501 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3503 (define_insn "floatdidf2"
3504 [(set (match_operand:DF 0 "register_operand" "=e")
3505 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3506 "TARGET_V9 && TARGET_FPU"
3508 [(set_attr "type" "fp")
3509 (set_attr "fptype" "double")])
3511 (define_expand "floatunsdidf2"
3512 [(use (match_operand:DF 0 "register_operand" ""))
3513 (use (match_operand:DI 1 "general_operand" ""))]
3514 "TARGET_ARCH64 && TARGET_FPU"
3515 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3517 (define_expand "floatditf2"
3518 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3519 (float:TF (match_operand:DI 1 "register_operand" "")))]
3520 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3521 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3523 (define_insn "*floatditf2_hq"
3524 [(set (match_operand:TF 0 "register_operand" "=e")
3525 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3526 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3528 [(set_attr "type" "fp")])
3530 (define_expand "floatunsditf2"
3531 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3532 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3533 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3534 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3536 ;; Convert a float to an actual integer.
3537 ;; Truncation is performed as part of the conversion.
3539 (define_insn "fix_truncsfsi2"
3540 [(set (match_operand:SI 0 "register_operand" "=f")
3541 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3544 [(set_attr "type" "fp")
3545 (set_attr "fptype" "double")])
3547 (define_insn "fix_truncdfsi2"
3548 [(set (match_operand:SI 0 "register_operand" "=f")
3549 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3552 [(set_attr "type" "fp")
3553 (set_attr "fptype" "double")])
3555 (define_expand "fix_trunctfsi2"
3556 [(set (match_operand:SI 0 "register_operand" "")
3557 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3558 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3559 "emit_tfmode_cvt (FIX, operands); DONE;")
3561 (define_insn "*fix_trunctfsi2_hq"
3562 [(set (match_operand:SI 0 "register_operand" "=f")
3563 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3564 "TARGET_FPU && TARGET_HARD_QUAD"
3566 [(set_attr "type" "fp")])
3568 (define_expand "fixuns_trunctfsi2"
3569 [(set (match_operand:SI 0 "register_operand" "")
3570 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3571 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3572 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3574 ;; Now the same, for V9 targets
3576 (define_insn "fix_truncsfdi2"
3577 [(set (match_operand:DI 0 "register_operand" "=e")
3578 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3579 "TARGET_V9 && TARGET_FPU"
3581 [(set_attr "type" "fp")
3582 (set_attr "fptype" "double")])
3584 (define_expand "fixuns_truncsfdi2"
3585 [(use (match_operand:DI 0 "register_operand" ""))
3586 (use (match_operand:SF 1 "general_operand" ""))]
3587 "TARGET_ARCH64 && TARGET_FPU"
3588 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3590 (define_insn "fix_truncdfdi2"
3591 [(set (match_operand:DI 0 "register_operand" "=e")
3592 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3593 "TARGET_V9 && TARGET_FPU"
3595 [(set_attr "type" "fp")
3596 (set_attr "fptype" "double")])
3598 (define_expand "fixuns_truncdfdi2"
3599 [(use (match_operand:DI 0 "register_operand" ""))
3600 (use (match_operand:DF 1 "general_operand" ""))]
3601 "TARGET_ARCH64 && TARGET_FPU"
3602 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3604 (define_expand "fix_trunctfdi2"
3605 [(set (match_operand:DI 0 "register_operand" "")
3606 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3607 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3608 "emit_tfmode_cvt (FIX, operands); DONE;")
3610 (define_insn "*fix_trunctfdi2_hq"
3611 [(set (match_operand:DI 0 "register_operand" "=e")
3612 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3613 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3615 [(set_attr "type" "fp")])
3617 (define_expand "fixuns_trunctfdi2"
3618 [(set (match_operand:DI 0 "register_operand" "")
3619 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3620 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3621 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3624 ;; Integer addition/subtraction instructions.
3626 (define_expand "adddi3"
3627 [(set (match_operand:DI 0 "register_operand" "")
3628 (plus:DI (match_operand:DI 1 "register_operand" "")
3629 (match_operand:DI 2 "arith_double_add_operand" "")))]
3632 if (! TARGET_ARCH64)
3634 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3635 gen_rtx_SET (VOIDmode, operands[0],
3636 gen_rtx_PLUS (DImode, operands[1],
3638 gen_rtx_CLOBBER (VOIDmode,
3639 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3644 (define_insn_and_split "*adddi3_insn_sp32"
3645 [(set (match_operand:DI 0 "register_operand" "=r")
3646 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3647 (match_operand:DI 2 "arith_double_operand" "rHI")))
3648 (clobber (reg:CC CC_REG))]
3651 "&& reload_completed"
3652 [(parallel [(set (reg:CC_NOOV CC_REG)
3653 (compare:CC_NOOV (plus:SI (match_dup 4)
3657 (plus:SI (match_dup 4) (match_dup 5)))])
3659 (plus:SI (plus:SI (match_dup 7)
3661 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3663 operands[3] = gen_lowpart (SImode, operands[0]);
3664 operands[4] = gen_lowpart (SImode, operands[1]);
3665 operands[5] = gen_lowpart (SImode, operands[2]);
3666 operands[6] = gen_highpart (SImode, operands[0]);
3667 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3668 #if HOST_BITS_PER_WIDE_INT == 32
3669 if (GET_CODE (operands[2]) == CONST_INT)
3671 if (INTVAL (operands[2]) < 0)
3672 operands[8] = constm1_rtx;
3674 operands[8] = const0_rtx;
3678 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3680 [(set_attr "length" "2")])
3682 ;; LTU here means "carry set"
3684 [(set (match_operand:SI 0 "register_operand" "=r")
3685 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3686 (match_operand:SI 2 "arith_operand" "rI"))
3687 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3690 [(set_attr "type" "ialuX")])
3692 (define_insn_and_split "*addx_extend_sp32"
3693 [(set (match_operand:DI 0 "register_operand" "=r")
3694 (zero_extend:DI (plus:SI (plus:SI
3695 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3696 (match_operand:SI 2 "arith_operand" "rI"))
3697 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3700 "&& reload_completed"
3701 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3702 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3703 (set (match_dup 4) (const_int 0))]
3704 "operands[3] = gen_lowpart (SImode, operands[0]);
3705 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3706 [(set_attr "length" "2")])
3708 (define_insn "*addx_extend_sp64"
3709 [(set (match_operand:DI 0 "register_operand" "=r")
3710 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3711 (match_operand:SI 2 "arith_operand" "rI"))
3712 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3715 [(set_attr "type" "ialuX")])
3717 (define_insn_and_split "*adddi3_extend_sp32"
3718 [(set (match_operand:DI 0 "register_operand" "=r")
3719 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3720 (match_operand:DI 2 "register_operand" "r")))
3721 (clobber (reg:CC CC_REG))]
3724 "&& reload_completed"
3725 [(parallel [(set (reg:CC_NOOV CC_REG)
3726 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3728 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3730 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3731 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3732 "operands[3] = gen_lowpart (SImode, operands[2]);
3733 operands[4] = gen_highpart (SImode, operands[2]);
3734 operands[5] = gen_lowpart (SImode, operands[0]);
3735 operands[6] = gen_highpart (SImode, operands[0]);"
3736 [(set_attr "length" "2")])
3738 (define_insn "*adddi3_sp64"
3739 [(set (match_operand:DI 0 "register_operand" "=r,r")
3740 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3741 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3747 (define_insn "addsi3"
3748 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3749 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3750 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3755 fpadd32s\t%1, %2, %0"
3756 [(set_attr "type" "*,*,fga")
3757 (set_attr "fptype" "*,*,single")])
3759 (define_insn "*cmp_cc_plus"
3760 [(set (reg:CC_NOOV CC_REG)
3761 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3762 (match_operand:SI 1 "arith_operand" "rI"))
3765 "addcc\t%0, %1, %%g0"
3766 [(set_attr "type" "compare")])
3768 (define_insn "*cmp_ccx_plus"
3769 [(set (reg:CCX_NOOV CC_REG)
3770 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3771 (match_operand:DI 1 "arith_operand" "rI"))
3774 "addcc\t%0, %1, %%g0"
3775 [(set_attr "type" "compare")])
3777 (define_insn "*cmp_cc_plus_set"
3778 [(set (reg:CC_NOOV CC_REG)
3779 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3780 (match_operand:SI 2 "arith_operand" "rI"))
3782 (set (match_operand:SI 0 "register_operand" "=r")
3783 (plus:SI (match_dup 1) (match_dup 2)))]
3786 [(set_attr "type" "compare")])
3788 (define_insn "*cmp_ccx_plus_set"
3789 [(set (reg:CCX_NOOV CC_REG)
3790 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3791 (match_operand:DI 2 "arith_operand" "rI"))
3793 (set (match_operand:DI 0 "register_operand" "=r")
3794 (plus:DI (match_dup 1) (match_dup 2)))]
3797 [(set_attr "type" "compare")])
3799 (define_expand "subdi3"
3800 [(set (match_operand:DI 0 "register_operand" "")
3801 (minus:DI (match_operand:DI 1 "register_operand" "")
3802 (match_operand:DI 2 "arith_double_add_operand" "")))]
3805 if (! TARGET_ARCH64)
3807 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3808 gen_rtx_SET (VOIDmode, operands[0],
3809 gen_rtx_MINUS (DImode, operands[1],
3811 gen_rtx_CLOBBER (VOIDmode,
3812 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3817 (define_insn_and_split "*subdi3_insn_sp32"
3818 [(set (match_operand:DI 0 "register_operand" "=r")
3819 (minus:DI (match_operand:DI 1 "register_operand" "r")
3820 (match_operand:DI 2 "arith_double_operand" "rHI")))
3821 (clobber (reg:CC CC_REG))]
3824 "&& reload_completed"
3825 [(parallel [(set (reg:CC_NOOV CC_REG)
3826 (compare:CC_NOOV (minus:SI (match_dup 4)
3830 (minus:SI (match_dup 4) (match_dup 5)))])
3832 (minus:SI (minus:SI (match_dup 7)
3834 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3836 operands[3] = gen_lowpart (SImode, operands[0]);
3837 operands[4] = gen_lowpart (SImode, operands[1]);
3838 operands[5] = gen_lowpart (SImode, operands[2]);
3839 operands[6] = gen_highpart (SImode, operands[0]);
3840 operands[7] = gen_highpart (SImode, operands[1]);
3841 #if HOST_BITS_PER_WIDE_INT == 32
3842 if (GET_CODE (operands[2]) == CONST_INT)
3844 if (INTVAL (operands[2]) < 0)
3845 operands[8] = constm1_rtx;
3847 operands[8] = const0_rtx;
3851 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3853 [(set_attr "length" "2")])
3855 ;; LTU here means "carry set"
3857 [(set (match_operand:SI 0 "register_operand" "=r")
3858 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3859 (match_operand:SI 2 "arith_operand" "rI"))
3860 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3863 [(set_attr "type" "ialuX")])
3865 (define_insn "*subx_extend_sp64"
3866 [(set (match_operand:DI 0 "register_operand" "=r")
3867 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3868 (match_operand:SI 2 "arith_operand" "rI"))
3869 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3872 [(set_attr "type" "ialuX")])
3874 (define_insn_and_split "*subx_extend"
3875 [(set (match_operand:DI 0 "register_operand" "=r")
3876 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3877 (match_operand:SI 2 "arith_operand" "rI"))
3878 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3881 "&& reload_completed"
3882 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3883 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3884 (set (match_dup 4) (const_int 0))]
3885 "operands[3] = gen_lowpart (SImode, operands[0]);
3886 operands[4] = gen_highpart (SImode, operands[0]);"
3887 [(set_attr "length" "2")])
3889 (define_insn_and_split "*subdi3_extend_sp32"
3890 [(set (match_operand:DI 0 "register_operand" "=r")
3891 (minus:DI (match_operand:DI 1 "register_operand" "r")
3892 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3893 (clobber (reg:CC CC_REG))]
3896 "&& reload_completed"
3897 [(parallel [(set (reg:CC_NOOV CC_REG)
3898 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3900 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3902 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3903 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3904 "operands[3] = gen_lowpart (SImode, operands[1]);
3905 operands[4] = gen_highpart (SImode, operands[1]);
3906 operands[5] = gen_lowpart (SImode, operands[0]);
3907 operands[6] = gen_highpart (SImode, operands[0]);"
3908 [(set_attr "length" "2")])
3910 (define_insn "*subdi3_sp64"
3911 [(set (match_operand:DI 0 "register_operand" "=r,r")
3912 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3913 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3919 (define_insn "subsi3"
3920 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3921 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3922 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3927 fpsub32s\t%1, %2, %0"
3928 [(set_attr "type" "*,*,fga")
3929 (set_attr "fptype" "*,*,single")])
3931 (define_insn "*cmp_minus_cc"
3932 [(set (reg:CC_NOOV CC_REG)
3933 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3934 (match_operand:SI 1 "arith_operand" "rI"))
3937 "subcc\t%r0, %1, %%g0"
3938 [(set_attr "type" "compare")])
3940 (define_insn "*cmp_minus_ccx"
3941 [(set (reg:CCX_NOOV CC_REG)
3942 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3943 (match_operand:DI 1 "arith_operand" "rI"))
3946 "subcc\t%0, %1, %%g0"
3947 [(set_attr "type" "compare")])
3949 (define_insn "cmp_minus_cc_set"
3950 [(set (reg:CC_NOOV CC_REG)
3951 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3952 (match_operand:SI 2 "arith_operand" "rI"))
3954 (set (match_operand:SI 0 "register_operand" "=r")
3955 (minus:SI (match_dup 1) (match_dup 2)))]
3957 "subcc\t%r1, %2, %0"
3958 [(set_attr "type" "compare")])
3960 (define_insn "*cmp_minus_ccx_set"
3961 [(set (reg:CCX_NOOV CC_REG)
3962 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3963 (match_operand:DI 2 "arith_operand" "rI"))
3965 (set (match_operand:DI 0 "register_operand" "=r")
3966 (minus:DI (match_dup 1) (match_dup 2)))]
3969 [(set_attr "type" "compare")])
3972 ;; Integer multiply/divide instructions.
3974 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3975 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3977 (define_insn "mulsi3"
3978 [(set (match_operand:SI 0 "register_operand" "=r")
3979 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3980 (match_operand:SI 2 "arith_operand" "rI")))]
3983 [(set_attr "type" "imul")])
3985 (define_expand "muldi3"
3986 [(set (match_operand:DI 0 "register_operand" "")
3987 (mult:DI (match_operand:DI 1 "arith_operand" "")
3988 (match_operand:DI 2 "arith_operand" "")))]
3989 "TARGET_ARCH64 || TARGET_V8PLUS"
3993 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3998 (define_insn "*muldi3_sp64"
3999 [(set (match_operand:DI 0 "register_operand" "=r")
4000 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4001 (match_operand:DI 2 "arith_operand" "rI")))]
4004 [(set_attr "type" "imul")])
4006 ;; V8plus wide multiply.
4008 (define_insn "muldi3_v8plus"
4009 [(set (match_operand:DI 0 "register_operand" "=r,h")
4010 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4011 (match_operand:DI 2 "arith_operand" "rI,rI")))
4012 (clobber (match_scratch:SI 3 "=&h,X"))
4013 (clobber (match_scratch:SI 4 "=&h,X"))]
4016 if (sparc_check_64 (operands[1], insn) <= 0)
4017 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4018 if (which_alternative == 1)
4019 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4020 if (GET_CODE (operands[2]) == CONST_INT)
4022 if (which_alternative == 1)
4023 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4025 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";
4027 else if (rtx_equal_p (operands[1], operands[2]))
4029 if (which_alternative == 1)
4030 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4032 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";
4034 if (sparc_check_64 (operands[2], insn) <= 0)
4035 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4036 if (which_alternative == 1)
4037 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";
4039 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";
4041 [(set_attr "type" "multi")
4042 (set_attr "length" "9,8")])
4044 (define_insn "*cmp_mul_set"
4045 [(set (reg:CC CC_REG)
4046 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4047 (match_operand:SI 2 "arith_operand" "rI"))
4049 (set (match_operand:SI 0 "register_operand" "=r")
4050 (mult:SI (match_dup 1) (match_dup 2)))]
4051 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4052 "smulcc\t%1, %2, %0"
4053 [(set_attr "type" "imul")])
4055 (define_expand "mulsidi3"
4056 [(set (match_operand:DI 0 "register_operand" "")
4057 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4058 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4061 if (CONSTANT_P (operands[2]))
4064 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4066 else if (TARGET_ARCH32)
4067 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4070 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4076 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4081 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4082 ;; registers can hold 64-bit values in the V8plus environment.
4084 (define_insn "mulsidi3_v8plus"
4085 [(set (match_operand:DI 0 "register_operand" "=h,r")
4086 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4087 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4088 (clobber (match_scratch:SI 3 "=X,&h"))]
4091 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4092 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4093 [(set_attr "type" "multi")
4094 (set_attr "length" "2,3")])
4097 (define_insn "const_mulsidi3_v8plus"
4098 [(set (match_operand:DI 0 "register_operand" "=h,r")
4099 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4100 (match_operand:DI 2 "small_int_operand" "I,I")))
4101 (clobber (match_scratch:SI 3 "=X,&h"))]
4104 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4105 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4106 [(set_attr "type" "multi")
4107 (set_attr "length" "2,3")])
4110 (define_insn "*mulsidi3_sp32"
4111 [(set (match_operand:DI 0 "register_operand" "=r")
4112 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4113 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4116 return TARGET_SPARCLET
4117 ? "smuld\t%1, %2, %L0"
4118 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4121 (if_then_else (eq_attr "isa" "sparclet")
4122 (const_string "imul") (const_string "multi")))
4123 (set (attr "length")
4124 (if_then_else (eq_attr "isa" "sparclet")
4125 (const_int 1) (const_int 2)))])
4127 (define_insn "*mulsidi3_sp64"
4128 [(set (match_operand:DI 0 "register_operand" "=r")
4129 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4130 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4131 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4133 [(set_attr "type" "imul")])
4135 ;; Extra pattern, because sign_extend of a constant isn't valid.
4138 (define_insn "const_mulsidi3_sp32"
4139 [(set (match_operand:DI 0 "register_operand" "=r")
4140 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4141 (match_operand:DI 2 "small_int_operand" "I")))]
4144 return TARGET_SPARCLET
4145 ? "smuld\t%1, %2, %L0"
4146 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4149 (if_then_else (eq_attr "isa" "sparclet")
4150 (const_string "imul") (const_string "multi")))
4151 (set (attr "length")
4152 (if_then_else (eq_attr "isa" "sparclet")
4153 (const_int 1) (const_int 2)))])
4155 (define_insn "const_mulsidi3_sp64"
4156 [(set (match_operand:DI 0 "register_operand" "=r")
4157 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4158 (match_operand:DI 2 "small_int_operand" "I")))]
4159 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4161 [(set_attr "type" "imul")])
4163 (define_expand "smulsi3_highpart"
4164 [(set (match_operand:SI 0 "register_operand" "")
4166 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4167 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4169 "TARGET_HARD_MUL && TARGET_ARCH32"
4171 if (CONSTANT_P (operands[2]))
4175 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4181 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4186 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4187 operands[2], GEN_INT (32)));
4193 (define_insn "smulsi3_highpart_v8plus"
4194 [(set (match_operand:SI 0 "register_operand" "=h,r")
4196 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4197 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4198 (match_operand:SI 3 "small_int_operand" "I,I"))))
4199 (clobber (match_scratch:SI 4 "=X,&h"))]
4202 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4203 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4204 [(set_attr "type" "multi")
4205 (set_attr "length" "2")])
4207 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4210 [(set (match_operand:SI 0 "register_operand" "=h,r")
4213 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4214 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4215 (match_operand:SI 3 "small_int_operand" "I,I"))
4217 (clobber (match_scratch:SI 4 "=X,&h"))]
4220 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4221 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4222 [(set_attr "type" "multi")
4223 (set_attr "length" "2")])
4226 (define_insn "const_smulsi3_highpart_v8plus"
4227 [(set (match_operand:SI 0 "register_operand" "=h,r")
4229 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4230 (match_operand:DI 2 "small_int_operand" "I,I"))
4231 (match_operand:SI 3 "small_int_operand" "I,I"))))
4232 (clobber (match_scratch:SI 4 "=X,&h"))]
4235 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4236 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4237 [(set_attr "type" "multi")
4238 (set_attr "length" "2")])
4241 (define_insn "*smulsi3_highpart_sp32"
4242 [(set (match_operand:SI 0 "register_operand" "=r")
4244 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4245 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4248 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4249 [(set_attr "type" "multi")
4250 (set_attr "length" "2")])
4253 (define_insn "const_smulsi3_highpart"
4254 [(set (match_operand:SI 0 "register_operand" "=r")
4256 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4257 (match_operand:DI 2 "small_int_operand" "i"))
4260 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4261 [(set_attr "type" "multi")
4262 (set_attr "length" "2")])
4264 (define_expand "umulsidi3"
4265 [(set (match_operand:DI 0 "register_operand" "")
4266 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4267 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4270 if (CONSTANT_P (operands[2]))
4273 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4275 else if (TARGET_ARCH32)
4276 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4279 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4285 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4291 (define_insn "umulsidi3_v8plus"
4292 [(set (match_operand:DI 0 "register_operand" "=h,r")
4293 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4294 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4295 (clobber (match_scratch:SI 3 "=X,&h"))]
4298 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4299 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4300 [(set_attr "type" "multi")
4301 (set_attr "length" "2,3")])
4304 (define_insn "*umulsidi3_sp32"
4305 [(set (match_operand:DI 0 "register_operand" "=r")
4306 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4307 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4310 return TARGET_SPARCLET
4311 ? "umuld\t%1, %2, %L0"
4312 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4315 (if_then_else (eq_attr "isa" "sparclet")
4316 (const_string "imul") (const_string "multi")))
4317 (set (attr "length")
4318 (if_then_else (eq_attr "isa" "sparclet")
4319 (const_int 1) (const_int 2)))])
4321 (define_insn "*umulsidi3_sp64"
4322 [(set (match_operand:DI 0 "register_operand" "=r")
4323 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4324 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4325 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4327 [(set_attr "type" "imul")])
4329 ;; Extra pattern, because sign_extend of a constant isn't valid.
4332 (define_insn "const_umulsidi3_sp32"
4333 [(set (match_operand:DI 0 "register_operand" "=r")
4334 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4335 (match_operand:DI 2 "uns_small_int_operand" "")))]
4338 return TARGET_SPARCLET
4339 ? "umuld\t%1, %s2, %L0"
4340 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4343 (if_then_else (eq_attr "isa" "sparclet")
4344 (const_string "imul") (const_string "multi")))
4345 (set (attr "length")
4346 (if_then_else (eq_attr "isa" "sparclet")
4347 (const_int 1) (const_int 2)))])
4349 (define_insn "const_umulsidi3_sp64"
4350 [(set (match_operand:DI 0 "register_operand" "=r")
4351 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4352 (match_operand:DI 2 "uns_small_int_operand" "")))]
4353 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4355 [(set_attr "type" "imul")])
4358 (define_insn "const_umulsidi3_v8plus"
4359 [(set (match_operand:DI 0 "register_operand" "=h,r")
4360 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4361 (match_operand:DI 2 "uns_small_int_operand" "")))
4362 (clobber (match_scratch:SI 3 "=X,h"))]
4365 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4366 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4367 [(set_attr "type" "multi")
4368 (set_attr "length" "2,3")])
4370 (define_expand "umulsi3_highpart"
4371 [(set (match_operand:SI 0 "register_operand" "")
4373 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4374 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4376 "TARGET_HARD_MUL && TARGET_ARCH32"
4378 if (CONSTANT_P (operands[2]))
4382 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4388 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4393 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4394 operands[2], GEN_INT (32)));
4400 (define_insn "umulsi3_highpart_v8plus"
4401 [(set (match_operand:SI 0 "register_operand" "=h,r")
4403 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4404 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4405 (match_operand:SI 3 "small_int_operand" "I,I"))))
4406 (clobber (match_scratch:SI 4 "=X,h"))]
4409 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4410 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4411 [(set_attr "type" "multi")
4412 (set_attr "length" "2")])
4415 (define_insn "const_umulsi3_highpart_v8plus"
4416 [(set (match_operand:SI 0 "register_operand" "=h,r")
4418 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4419 (match_operand:DI 2 "uns_small_int_operand" ""))
4420 (match_operand:SI 3 "small_int_operand" "I,I"))))
4421 (clobber (match_scratch:SI 4 "=X,h"))]
4424 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4425 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4426 [(set_attr "type" "multi")
4427 (set_attr "length" "2")])
4430 (define_insn "*umulsi3_highpart_sp32"
4431 [(set (match_operand:SI 0 "register_operand" "=r")
4433 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4434 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4437 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4438 [(set_attr "type" "multi")
4439 (set_attr "length" "2")])
4442 (define_insn "const_umulsi3_highpart"
4443 [(set (match_operand:SI 0 "register_operand" "=r")
4445 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4446 (match_operand:DI 2 "uns_small_int_operand" ""))
4449 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4450 [(set_attr "type" "multi")
4451 (set_attr "length" "2")])
4453 (define_expand "divsi3"
4454 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4455 (div:SI (match_operand:SI 1 "register_operand" "")
4456 (match_operand:SI 2 "input_operand" "")))
4457 (clobber (match_scratch:SI 3 ""))])]
4458 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4462 operands[3] = gen_reg_rtx(SImode);
4463 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4464 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4470 ;; The V8 architecture specifies that there must be at least 3 instructions
4471 ;; between a write to the Y register and a use of it for correct results.
4472 ;; We try to fill one of them with a simple constant or a memory load.
4474 (define_insn "divsi3_sp32"
4475 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4476 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4477 (match_operand:SI 2 "input_operand" "rI,K,m")))
4478 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4479 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4481 output_asm_insn ("sra\t%1, 31, %3", operands);
4482 output_asm_insn ("wr\t%3, 0, %%y", operands);
4484 switch (which_alternative)
4488 return "sdiv\t%1, %2, %0";
4490 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4493 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4495 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4498 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4500 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4505 [(set_attr "type" "multi")
4506 (set (attr "length")
4507 (if_then_else (eq_attr "isa" "v9")
4508 (const_int 4) (const_int 6)))])
4510 (define_insn "divsi3_sp64"
4511 [(set (match_operand:SI 0 "register_operand" "=r")
4512 (div:SI (match_operand:SI 1 "register_operand" "r")
4513 (match_operand:SI 2 "input_operand" "rI")))
4514 (use (match_operand:SI 3 "register_operand" "r"))]
4515 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4516 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4517 [(set_attr "type" "multi")
4518 (set_attr "length" "2")])
4520 (define_insn "divdi3"
4521 [(set (match_operand:DI 0 "register_operand" "=r")
4522 (div:DI (match_operand:DI 1 "register_operand" "r")
4523 (match_operand:DI 2 "arith_operand" "rI")))]
4526 [(set_attr "type" "idiv")])
4528 (define_insn "*cmp_sdiv_cc_set"
4529 [(set (reg:CC CC_REG)
4530 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4531 (match_operand:SI 2 "arith_operand" "rI"))
4533 (set (match_operand:SI 0 "register_operand" "=r")
4534 (div:SI (match_dup 1) (match_dup 2)))
4535 (clobber (match_scratch:SI 3 "=&r"))]
4536 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4538 output_asm_insn ("sra\t%1, 31, %3", operands);
4539 output_asm_insn ("wr\t%3, 0, %%y", operands);
4542 return "sdivcc\t%1, %2, %0";
4544 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4546 [(set_attr "type" "multi")
4547 (set (attr "length")
4548 (if_then_else (eq_attr "isa" "v9")
4549 (const_int 3) (const_int 6)))])
4552 (define_expand "udivsi3"
4553 [(set (match_operand:SI 0 "register_operand" "")
4554 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4555 (match_operand:SI 2 "input_operand" "")))]
4556 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4559 ;; The V8 architecture specifies that there must be at least 3 instructions
4560 ;; between a write to the Y register and a use of it for correct results.
4561 ;; We try to fill one of them with a simple constant or a memory load.
4563 (define_insn "udivsi3_sp32"
4564 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4565 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4566 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4567 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4569 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4571 switch (which_alternative)
4575 return "udiv\t%1, %2, %0";
4577 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4580 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4582 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4585 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4587 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4590 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4592 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4597 [(set_attr "type" "multi")
4598 (set (attr "length")
4599 (if_then_else (eq_attr "isa" "v9")
4600 (const_int 3) (const_int 5)))])
4602 (define_insn "udivsi3_sp64"
4603 [(set (match_operand:SI 0 "register_operand" "=r")
4604 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4605 (match_operand:SI 2 "input_operand" "rI")))]
4606 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4607 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4608 [(set_attr "type" "multi")
4609 (set_attr "length" "2")])
4611 (define_insn "udivdi3"
4612 [(set (match_operand:DI 0 "register_operand" "=r")
4613 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4614 (match_operand:DI 2 "arith_operand" "rI")))]
4617 [(set_attr "type" "idiv")])
4619 (define_insn "*cmp_udiv_cc_set"
4620 [(set (reg:CC CC_REG)
4621 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4622 (match_operand:SI 2 "arith_operand" "rI"))
4624 (set (match_operand:SI 0 "register_operand" "=r")
4625 (udiv:SI (match_dup 1) (match_dup 2)))]
4626 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4628 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4631 return "udivcc\t%1, %2, %0";
4633 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4635 [(set_attr "type" "multi")
4636 (set (attr "length")
4637 (if_then_else (eq_attr "isa" "v9")
4638 (const_int 2) (const_int 5)))])
4640 ; sparclet multiply/accumulate insns
4642 (define_insn "*smacsi"
4643 [(set (match_operand:SI 0 "register_operand" "=r")
4644 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4645 (match_operand:SI 2 "arith_operand" "rI"))
4646 (match_operand:SI 3 "register_operand" "0")))]
4649 [(set_attr "type" "imul")])
4651 (define_insn "*smacdi"
4652 [(set (match_operand:DI 0 "register_operand" "=r")
4653 (plus:DI (mult:DI (sign_extend:DI
4654 (match_operand:SI 1 "register_operand" "%r"))
4656 (match_operand:SI 2 "register_operand" "r")))
4657 (match_operand:DI 3 "register_operand" "0")))]
4659 "smacd\t%1, %2, %L0"
4660 [(set_attr "type" "imul")])
4662 (define_insn "*umacdi"
4663 [(set (match_operand:DI 0 "register_operand" "=r")
4664 (plus:DI (mult:DI (zero_extend:DI
4665 (match_operand:SI 1 "register_operand" "%r"))
4667 (match_operand:SI 2 "register_operand" "r")))
4668 (match_operand:DI 3 "register_operand" "0")))]
4670 "umacd\t%1, %2, %L0"
4671 [(set_attr "type" "imul")])
4674 ;; Boolean instructions.
4676 ;; We define DImode `and' so with DImode `not' we can get
4677 ;; DImode `andn'. Other combinations are possible.
4679 (define_expand "and<V64I:mode>3"
4680 [(set (match_operand:V64I 0 "register_operand" "")
4681 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4682 (match_operand:V64I 2 "arith_double_operand" "")))]
4686 (define_insn "*and<V64I:mode>3_sp32"
4687 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4688 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4689 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4694 [(set_attr "type" "*,fga")
4695 (set_attr "length" "2,*")
4696 (set_attr "fptype" "*,double")])
4698 (define_insn "*and<V64I:mode>3_sp64"
4699 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4700 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4701 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4706 [(set_attr "type" "*,fga")
4707 (set_attr "fptype" "*,double")])
4709 (define_insn "and<V32I:mode>3"
4710 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4711 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4712 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4717 [(set_attr "type" "*,fga")
4718 (set_attr "fptype" "*,single")])
4721 [(set (match_operand:SI 0 "register_operand" "")
4722 (and:SI (match_operand:SI 1 "register_operand" "")
4723 (match_operand:SI 2 "const_compl_high_operand" "")))
4724 (clobber (match_operand:SI 3 "register_operand" ""))]
4726 [(set (match_dup 3) (match_dup 4))
4727 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4729 operands[4] = GEN_INT (~INTVAL (operands[2]));
4732 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4733 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4734 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4735 (match_operand:V64I 2 "register_operand" "r,b")))]
4739 fandnot1\t%1, %2, %0"
4740 "&& reload_completed
4741 && ((GET_CODE (operands[0]) == REG
4742 && REGNO (operands[0]) < 32)
4743 || (GET_CODE (operands[0]) == SUBREG
4744 && GET_CODE (SUBREG_REG (operands[0])) == REG
4745 && REGNO (SUBREG_REG (operands[0])) < 32))"
4746 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4747 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4748 "operands[3] = gen_highpart (SImode, operands[0]);
4749 operands[4] = gen_highpart (SImode, operands[1]);
4750 operands[5] = gen_highpart (SImode, operands[2]);
4751 operands[6] = gen_lowpart (SImode, operands[0]);
4752 operands[7] = gen_lowpart (SImode, operands[1]);
4753 operands[8] = gen_lowpart (SImode, operands[2]);"
4754 [(set_attr "type" "*,fga")
4755 (set_attr "length" "2,*")
4756 (set_attr "fptype" "*,double")])
4758 (define_insn "*and_not_<V64I:mode>_sp64"
4759 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4760 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4761 (match_operand:V64I 2 "register_operand" "r,b")))]
4765 fandnot1\t%1, %2, %0"
4766 [(set_attr "type" "*,fga")
4767 (set_attr "fptype" "*,double")])
4769 (define_insn "*and_not_<V32I:mode>"
4770 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4771 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4772 (match_operand:V32I 2 "register_operand" "r,d")))]
4776 fandnot1s\t%1, %2, %0"
4777 [(set_attr "type" "*,fga")
4778 (set_attr "fptype" "*,single")])
4780 (define_expand "ior<V64I:mode>3"
4781 [(set (match_operand:V64I 0 "register_operand" "")
4782 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4783 (match_operand:V64I 2 "arith_double_operand" "")))]
4787 (define_insn "*ior<V64I:mode>3_sp32"
4788 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4789 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4790 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4795 [(set_attr "type" "*,fga")
4796 (set_attr "length" "2,*")
4797 (set_attr "fptype" "*,double")])
4799 (define_insn "*ior<V64I:mode>3_sp64"
4800 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4801 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4802 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4807 [(set_attr "type" "*,fga")
4808 (set_attr "fptype" "*,double")])
4810 (define_insn "ior<V32I:mode>3"
4811 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4812 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4813 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4818 [(set_attr "type" "*,fga")
4819 (set_attr "fptype" "*,single")])
4822 [(set (match_operand:SI 0 "register_operand" "")
4823 (ior:SI (match_operand:SI 1 "register_operand" "")
4824 (match_operand:SI 2 "const_compl_high_operand" "")))
4825 (clobber (match_operand:SI 3 "register_operand" ""))]
4827 [(set (match_dup 3) (match_dup 4))
4828 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4830 operands[4] = GEN_INT (~INTVAL (operands[2]));
4833 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4834 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4835 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4836 (match_operand:V64I 2 "register_operand" "r,b")))]
4840 fornot1\t%1, %2, %0"
4841 "&& reload_completed
4842 && ((GET_CODE (operands[0]) == REG
4843 && REGNO (operands[0]) < 32)
4844 || (GET_CODE (operands[0]) == SUBREG
4845 && GET_CODE (SUBREG_REG (operands[0])) == REG
4846 && REGNO (SUBREG_REG (operands[0])) < 32))"
4847 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4848 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4849 "operands[3] = gen_highpart (SImode, operands[0]);
4850 operands[4] = gen_highpart (SImode, operands[1]);
4851 operands[5] = gen_highpart (SImode, operands[2]);
4852 operands[6] = gen_lowpart (SImode, operands[0]);
4853 operands[7] = gen_lowpart (SImode, operands[1]);
4854 operands[8] = gen_lowpart (SImode, operands[2]);"
4855 [(set_attr "type" "*,fga")
4856 (set_attr "length" "2,*")
4857 (set_attr "fptype" "*,double")])
4859 (define_insn "*or_not_<V64I:mode>_sp64"
4860 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4861 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4862 (match_operand:V64I 2 "register_operand" "r,b")))]
4866 fornot1\t%1, %2, %0"
4867 [(set_attr "type" "*,fga")
4868 (set_attr "fptype" "*,double")])
4870 (define_insn "*or_not_<V32I:mode>"
4871 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4872 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4873 (match_operand:V32I 2 "register_operand" "r,d")))]
4877 fornot1s\t%1, %2, %0"
4878 [(set_attr "type" "*,fga")
4879 (set_attr "fptype" "*,single")])
4881 (define_expand "xor<V64I:mode>3"
4882 [(set (match_operand:V64I 0 "register_operand" "")
4883 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4884 (match_operand:V64I 2 "arith_double_operand" "")))]
4888 (define_insn "*xor<V64I:mode>3_sp32"
4889 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4890 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4891 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4896 [(set_attr "type" "*,fga")
4897 (set_attr "length" "2,*")
4898 (set_attr "fptype" "*,double")])
4900 (define_insn "*xor<V64I:mode>3_sp64"
4901 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4902 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4903 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4908 [(set_attr "type" "*,fga")
4909 (set_attr "fptype" "*,double")])
4911 (define_insn "xor<V32I:mode>3"
4912 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4913 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4914 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4919 [(set_attr "type" "*,fga")
4920 (set_attr "fptype" "*,single")])
4923 [(set (match_operand:SI 0 "register_operand" "")
4924 (xor:SI (match_operand:SI 1 "register_operand" "")
4925 (match_operand:SI 2 "const_compl_high_operand" "")))
4926 (clobber (match_operand:SI 3 "register_operand" ""))]
4928 [(set (match_dup 3) (match_dup 4))
4929 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4931 operands[4] = GEN_INT (~INTVAL (operands[2]));
4935 [(set (match_operand:SI 0 "register_operand" "")
4936 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4937 (match_operand:SI 2 "const_compl_high_operand" ""))))
4938 (clobber (match_operand:SI 3 "register_operand" ""))]
4940 [(set (match_dup 3) (match_dup 4))
4941 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4943 operands[4] = GEN_INT (~INTVAL (operands[2]));
4946 ;; Split DImode logical operations requiring two instructions.
4948 [(set (match_operand:V64I 0 "register_operand" "")
4949 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4950 [(match_operand:V64I 2 "register_operand" "")
4951 (match_operand:V64I 3 "arith_double_operand" "")]))]
4954 && ((GET_CODE (operands[0]) == REG
4955 && REGNO (operands[0]) < 32)
4956 || (GET_CODE (operands[0]) == SUBREG
4957 && GET_CODE (SUBREG_REG (operands[0])) == REG
4958 && REGNO (SUBREG_REG (operands[0])) < 32))"
4959 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4960 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4962 operands[4] = gen_highpart (SImode, operands[0]);
4963 operands[5] = gen_lowpart (SImode, operands[0]);
4964 operands[6] = gen_highpart (SImode, operands[2]);
4965 operands[7] = gen_lowpart (SImode, operands[2]);
4966 #if HOST_BITS_PER_WIDE_INT == 32
4967 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4969 if (INTVAL (operands[3]) < 0)
4970 operands[8] = constm1_rtx;
4972 operands[8] = const0_rtx;
4976 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4977 operands[9] = gen_lowpart (SImode, operands[3]);
4980 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4981 ;; Combine now canonicalizes to the rightmost expression.
4982 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4983 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4984 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4985 (match_operand:V64I 2 "register_operand" "r,b"))))]
4990 "&& reload_completed
4991 && ((GET_CODE (operands[0]) == REG
4992 && REGNO (operands[0]) < 32)
4993 || (GET_CODE (operands[0]) == SUBREG
4994 && GET_CODE (SUBREG_REG (operands[0])) == REG
4995 && REGNO (SUBREG_REG (operands[0])) < 32))"
4996 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4997 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4998 "operands[3] = gen_highpart (SImode, operands[0]);
4999 operands[4] = gen_highpart (SImode, operands[1]);
5000 operands[5] = gen_highpart (SImode, operands[2]);
5001 operands[6] = gen_lowpart (SImode, operands[0]);
5002 operands[7] = gen_lowpart (SImode, operands[1]);
5003 operands[8] = gen_lowpart (SImode, operands[2]);"
5004 [(set_attr "type" "*,fga")
5005 (set_attr "length" "2,*")
5006 (set_attr "fptype" "*,double")])
5008 (define_insn "*xor_not_<V64I:mode>_sp64"
5009 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5010 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5011 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5016 [(set_attr "type" "*,fga")
5017 (set_attr "fptype" "*,double")])
5019 (define_insn "*xor_not_<V32I:mode>"
5020 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5021 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5022 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5027 [(set_attr "type" "*,fga")
5028 (set_attr "fptype" "*,single")])
5030 ;; These correspond to the above in the case where we also (or only)
5031 ;; want to set the condition code.
5033 (define_insn "*cmp_cc_arith_op"
5034 [(set (reg:CC CC_REG)
5036 (match_operator:SI 2 "cc_arith_operator"
5037 [(match_operand:SI 0 "arith_operand" "%r")
5038 (match_operand:SI 1 "arith_operand" "rI")])
5041 "%A2cc\t%0, %1, %%g0"
5042 [(set_attr "type" "compare")])
5044 (define_insn "*cmp_ccx_arith_op"
5045 [(set (reg:CCX CC_REG)
5047 (match_operator:DI 2 "cc_arith_operator"
5048 [(match_operand:DI 0 "arith_operand" "%r")
5049 (match_operand:DI 1 "arith_operand" "rI")])
5052 "%A2cc\t%0, %1, %%g0"
5053 [(set_attr "type" "compare")])
5055 (define_insn "*cmp_cc_arith_op_set"
5056 [(set (reg:CC CC_REG)
5058 (match_operator:SI 3 "cc_arith_operator"
5059 [(match_operand:SI 1 "arith_operand" "%r")
5060 (match_operand:SI 2 "arith_operand" "rI")])
5062 (set (match_operand:SI 0 "register_operand" "=r")
5063 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5064 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5066 [(set_attr "type" "compare")])
5068 (define_insn "*cmp_ccx_arith_op_set"
5069 [(set (reg:CCX CC_REG)
5071 (match_operator:DI 3 "cc_arith_operator"
5072 [(match_operand:DI 1 "arith_operand" "%r")
5073 (match_operand:DI 2 "arith_operand" "rI")])
5075 (set (match_operand:DI 0 "register_operand" "=r")
5076 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5077 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5079 [(set_attr "type" "compare")])
5081 (define_insn "*cmp_cc_xor_not"
5082 [(set (reg:CC CC_REG)
5084 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5085 (match_operand:SI 1 "arith_operand" "rI")))
5088 "xnorcc\t%r0, %1, %%g0"
5089 [(set_attr "type" "compare")])
5091 (define_insn "*cmp_ccx_xor_not"
5092 [(set (reg:CCX CC_REG)
5094 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5095 (match_operand:DI 1 "arith_operand" "rI")))
5098 "xnorcc\t%r0, %1, %%g0"
5099 [(set_attr "type" "compare")])
5101 (define_insn "*cmp_cc_xor_not_set"
5102 [(set (reg:CC CC_REG)
5104 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5105 (match_operand:SI 2 "arith_operand" "rI")))
5107 (set (match_operand:SI 0 "register_operand" "=r")
5108 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5110 "xnorcc\t%r1, %2, %0"
5111 [(set_attr "type" "compare")])
5113 (define_insn "*cmp_ccx_xor_not_set"
5114 [(set (reg:CCX CC_REG)
5116 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5117 (match_operand:DI 2 "arith_operand" "rI")))
5119 (set (match_operand:DI 0 "register_operand" "=r")
5120 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5122 "xnorcc\t%r1, %2, %0"
5123 [(set_attr "type" "compare")])
5125 (define_insn "*cmp_cc_arith_op_not"
5126 [(set (reg:CC CC_REG)
5128 (match_operator:SI 2 "cc_arith_not_operator"
5129 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5130 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5133 "%B2cc\t%r1, %0, %%g0"
5134 [(set_attr "type" "compare")])
5136 (define_insn "*cmp_ccx_arith_op_not"
5137 [(set (reg:CCX CC_REG)
5139 (match_operator:DI 2 "cc_arith_not_operator"
5140 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5141 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5144 "%B2cc\t%r1, %0, %%g0"
5145 [(set_attr "type" "compare")])
5147 (define_insn "*cmp_cc_arith_op_not_set"
5148 [(set (reg:CC CC_REG)
5150 (match_operator:SI 3 "cc_arith_not_operator"
5151 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5152 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5154 (set (match_operand:SI 0 "register_operand" "=r")
5155 (match_operator:SI 4 "cc_arith_not_operator"
5156 [(not:SI (match_dup 1)) (match_dup 2)]))]
5157 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5158 "%B3cc\t%r2, %1, %0"
5159 [(set_attr "type" "compare")])
5161 (define_insn "*cmp_ccx_arith_op_not_set"
5162 [(set (reg:CCX CC_REG)
5164 (match_operator:DI 3 "cc_arith_not_operator"
5165 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5166 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5168 (set (match_operand:DI 0 "register_operand" "=r")
5169 (match_operator:DI 4 "cc_arith_not_operator"
5170 [(not:DI (match_dup 1)) (match_dup 2)]))]
5171 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5172 "%B3cc\t%r2, %1, %0"
5173 [(set_attr "type" "compare")])
5175 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5176 ;; does not know how to make it work for constants.
5178 (define_expand "negdi2"
5179 [(set (match_operand:DI 0 "register_operand" "=r")
5180 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5183 if (! TARGET_ARCH64)
5185 emit_insn (gen_rtx_PARALLEL
5188 gen_rtx_SET (VOIDmode, operand0,
5189 gen_rtx_NEG (DImode, operand1)),
5190 gen_rtx_CLOBBER (VOIDmode,
5191 gen_rtx_REG (CCmode,
5197 (define_insn_and_split "*negdi2_sp32"
5198 [(set (match_operand:DI 0 "register_operand" "=r")
5199 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5200 (clobber (reg:CC CC_REG))]
5203 "&& reload_completed"
5204 [(parallel [(set (reg:CC_NOOV CC_REG)
5205 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5207 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5208 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5209 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5210 "operands[2] = gen_highpart (SImode, operands[0]);
5211 operands[3] = gen_highpart (SImode, operands[1]);
5212 operands[4] = gen_lowpart (SImode, operands[0]);
5213 operands[5] = gen_lowpart (SImode, operands[1]);"
5214 [(set_attr "length" "2")])
5216 (define_insn "*negdi2_sp64"
5217 [(set (match_operand:DI 0 "register_operand" "=r")
5218 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5220 "sub\t%%g0, %1, %0")
5222 (define_insn "negsi2"
5223 [(set (match_operand:SI 0 "register_operand" "=r")
5224 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5226 "sub\t%%g0, %1, %0")
5228 (define_insn "*cmp_cc_neg"
5229 [(set (reg:CC_NOOV CC_REG)
5230 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5233 "subcc\t%%g0, %0, %%g0"
5234 [(set_attr "type" "compare")])
5236 (define_insn "*cmp_ccx_neg"
5237 [(set (reg:CCX_NOOV CC_REG)
5238 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5241 "subcc\t%%g0, %0, %%g0"
5242 [(set_attr "type" "compare")])
5244 (define_insn "*cmp_cc_set_neg"
5245 [(set (reg:CC_NOOV CC_REG)
5246 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5248 (set (match_operand:SI 0 "register_operand" "=r")
5249 (neg:SI (match_dup 1)))]
5251 "subcc\t%%g0, %1, %0"
5252 [(set_attr "type" "compare")])
5254 (define_insn "*cmp_ccx_set_neg"
5255 [(set (reg:CCX_NOOV CC_REG)
5256 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5258 (set (match_operand:DI 0 "register_operand" "=r")
5259 (neg:DI (match_dup 1)))]
5261 "subcc\t%%g0, %1, %0"
5262 [(set_attr "type" "compare")])
5264 ;; We cannot use the "not" pseudo insn because the Sun assembler
5265 ;; does not know how to make it work for constants.
5266 (define_expand "one_cmpl<V64I:mode>2"
5267 [(set (match_operand:V64I 0 "register_operand" "")
5268 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5272 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5273 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5274 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5279 "&& reload_completed
5280 && ((GET_CODE (operands[0]) == REG
5281 && REGNO (operands[0]) < 32)
5282 || (GET_CODE (operands[0]) == SUBREG
5283 && GET_CODE (SUBREG_REG (operands[0])) == REG
5284 && REGNO (SUBREG_REG (operands[0])) < 32))"
5285 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5286 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5287 "operands[2] = gen_highpart (SImode, operands[0]);
5288 operands[3] = gen_highpart (SImode, operands[1]);
5289 operands[4] = gen_lowpart (SImode, operands[0]);
5290 operands[5] = gen_lowpart (SImode, operands[1]);"
5291 [(set_attr "type" "*,fga")
5292 (set_attr "length" "2,*")
5293 (set_attr "fptype" "*,double")])
5295 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5296 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5297 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5302 [(set_attr "type" "*,fga")
5303 (set_attr "fptype" "*,double")])
5305 (define_insn "one_cmpl<V32I:mode>2"
5306 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5307 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5312 [(set_attr "type" "*,fga")
5313 (set_attr "fptype" "*,single")])
5315 (define_insn "*cmp_cc_not"
5316 [(set (reg:CC CC_REG)
5317 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5320 "xnorcc\t%%g0, %0, %%g0"
5321 [(set_attr "type" "compare")])
5323 (define_insn "*cmp_ccx_not"
5324 [(set (reg:CCX CC_REG)
5325 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5328 "xnorcc\t%%g0, %0, %%g0"
5329 [(set_attr "type" "compare")])
5331 (define_insn "*cmp_cc_set_not"
5332 [(set (reg:CC CC_REG)
5333 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5335 (set (match_operand:SI 0 "register_operand" "=r")
5336 (not:SI (match_dup 1)))]
5338 "xnorcc\t%%g0, %1, %0"
5339 [(set_attr "type" "compare")])
5341 (define_insn "*cmp_ccx_set_not"
5342 [(set (reg:CCX CC_REG)
5343 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5345 (set (match_operand:DI 0 "register_operand" "=r")
5346 (not:DI (match_dup 1)))]
5348 "xnorcc\t%%g0, %1, %0"
5349 [(set_attr "type" "compare")])
5351 (define_insn "*cmp_cc_set"
5352 [(set (match_operand:SI 0 "register_operand" "=r")
5353 (match_operand:SI 1 "register_operand" "r"))
5354 (set (reg:CC CC_REG)
5355 (compare:CC (match_dup 1)
5359 [(set_attr "type" "compare")])
5361 (define_insn "*cmp_ccx_set64"
5362 [(set (match_operand:DI 0 "register_operand" "=r")
5363 (match_operand:DI 1 "register_operand" "r"))
5364 (set (reg:CCX CC_REG)
5365 (compare:CCX (match_dup 1)
5369 [(set_attr "type" "compare")])
5372 ;; Floating point arithmetic instructions.
5374 (define_expand "addtf3"
5375 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5376 (plus:TF (match_operand:TF 1 "general_operand" "")
5377 (match_operand:TF 2 "general_operand" "")))]
5378 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5379 "emit_tfmode_binop (PLUS, operands); DONE;")
5381 (define_insn "*addtf3_hq"
5382 [(set (match_operand:TF 0 "register_operand" "=e")
5383 (plus:TF (match_operand:TF 1 "register_operand" "e")
5384 (match_operand:TF 2 "register_operand" "e")))]
5385 "TARGET_FPU && TARGET_HARD_QUAD"
5387 [(set_attr "type" "fp")])
5389 (define_insn "adddf3"
5390 [(set (match_operand:DF 0 "register_operand" "=e")
5391 (plus:DF (match_operand:DF 1 "register_operand" "e")
5392 (match_operand:DF 2 "register_operand" "e")))]
5395 [(set_attr "type" "fp")
5396 (set_attr "fptype" "double")])
5398 (define_insn "addsf3"
5399 [(set (match_operand:SF 0 "register_operand" "=f")
5400 (plus:SF (match_operand:SF 1 "register_operand" "f")
5401 (match_operand:SF 2 "register_operand" "f")))]
5404 [(set_attr "type" "fp")])
5406 (define_expand "subtf3"
5407 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5408 (minus:TF (match_operand:TF 1 "general_operand" "")
5409 (match_operand:TF 2 "general_operand" "")))]
5410 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5411 "emit_tfmode_binop (MINUS, operands); DONE;")
5413 (define_insn "*subtf3_hq"
5414 [(set (match_operand:TF 0 "register_operand" "=e")
5415 (minus:TF (match_operand:TF 1 "register_operand" "e")
5416 (match_operand:TF 2 "register_operand" "e")))]
5417 "TARGET_FPU && TARGET_HARD_QUAD"
5419 [(set_attr "type" "fp")])
5421 (define_insn "subdf3"
5422 [(set (match_operand:DF 0 "register_operand" "=e")
5423 (minus:DF (match_operand:DF 1 "register_operand" "e")
5424 (match_operand:DF 2 "register_operand" "e")))]
5427 [(set_attr "type" "fp")
5428 (set_attr "fptype" "double")])
5430 (define_insn "subsf3"
5431 [(set (match_operand:SF 0 "register_operand" "=f")
5432 (minus:SF (match_operand:SF 1 "register_operand" "f")
5433 (match_operand:SF 2 "register_operand" "f")))]
5436 [(set_attr "type" "fp")])
5438 (define_expand "multf3"
5439 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5440 (mult:TF (match_operand:TF 1 "general_operand" "")
5441 (match_operand:TF 2 "general_operand" "")))]
5442 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5443 "emit_tfmode_binop (MULT, operands); DONE;")
5445 (define_insn "*multf3_hq"
5446 [(set (match_operand:TF 0 "register_operand" "=e")
5447 (mult:TF (match_operand:TF 1 "register_operand" "e")
5448 (match_operand:TF 2 "register_operand" "e")))]
5449 "TARGET_FPU && TARGET_HARD_QUAD"
5451 [(set_attr "type" "fpmul")])
5453 (define_insn "muldf3"
5454 [(set (match_operand:DF 0 "register_operand" "=e")
5455 (mult:DF (match_operand:DF 1 "register_operand" "e")
5456 (match_operand:DF 2 "register_operand" "e")))]
5459 [(set_attr "type" "fpmul")
5460 (set_attr "fptype" "double")])
5462 (define_insn "mulsf3"
5463 [(set (match_operand:SF 0 "register_operand" "=f")
5464 (mult:SF (match_operand:SF 1 "register_operand" "f")
5465 (match_operand:SF 2 "register_operand" "f")))]
5468 [(set_attr "type" "fpmul")])
5470 (define_insn "fmadf4"
5471 [(set (match_operand:DF 0 "register_operand" "=e")
5472 (fma:DF (match_operand:DF 1 "register_operand" "e")
5473 (match_operand:DF 2 "register_operand" "e")
5474 (match_operand:DF 3 "register_operand" "e")))]
5476 "fmaddd\t%1, %2, %3, %0"
5477 [(set_attr "type" "fpmul")])
5479 (define_insn "fmsdf4"
5480 [(set (match_operand:DF 0 "register_operand" "=e")
5481 (fma:DF (match_operand:DF 1 "register_operand" "e")
5482 (match_operand:DF 2 "register_operand" "e")
5483 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5485 "fmsubd\t%1, %2, %3, %0"
5486 [(set_attr "type" "fpmul")])
5488 (define_insn "*nfmadf4"
5489 [(set (match_operand:DF 0 "register_operand" "=e")
5490 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5491 (match_operand:DF 2 "register_operand" "e")
5492 (match_operand:DF 3 "register_operand" "e"))))]
5494 "fnmaddd\t%1, %2, %3, %0"
5495 [(set_attr "type" "fpmul")])
5497 (define_insn "*nfmsdf4"
5498 [(set (match_operand:DF 0 "register_operand" "=e")
5499 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5500 (match_operand:DF 2 "register_operand" "e")
5501 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5503 "fnmsubd\t%1, %2, %3, %0"
5504 [(set_attr "type" "fpmul")])
5506 (define_insn "fmasf4"
5507 [(set (match_operand:SF 0 "register_operand" "=f")
5508 (fma:SF (match_operand:SF 1 "register_operand" "f")
5509 (match_operand:SF 2 "register_operand" "f")
5510 (match_operand:SF 3 "register_operand" "f")))]
5512 "fmadds\t%1, %2, %3, %0"
5513 [(set_attr "type" "fpmul")])
5515 (define_insn "fmssf4"
5516 [(set (match_operand:SF 0 "register_operand" "=f")
5517 (fma:SF (match_operand:SF 1 "register_operand" "f")
5518 (match_operand:SF 2 "register_operand" "f")
5519 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5521 "fmsubs\t%1, %2, %3, %0"
5522 [(set_attr "type" "fpmul")])
5524 (define_insn "*nfmasf4"
5525 [(set (match_operand:SF 0 "register_operand" "=f")
5526 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5527 (match_operand:SF 2 "register_operand" "f")
5528 (match_operand:SF 3 "register_operand" "f"))))]
5530 "fnmadds\t%1, %2, %3, %0"
5531 [(set_attr "type" "fpmul")])
5533 (define_insn "*nfmssf4"
5534 [(set (match_operand:SF 0 "register_operand" "=f")
5535 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5536 (match_operand:SF 2 "register_operand" "f")
5537 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5539 "fnmsubs\t%1, %2, %3, %0"
5540 [(set_attr "type" "fpmul")])
5542 (define_insn "*muldf3_extend"
5543 [(set (match_operand:DF 0 "register_operand" "=e")
5544 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5545 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5546 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5547 "fsmuld\t%1, %2, %0"
5548 [(set_attr "type" "fpmul")
5549 (set_attr "fptype" "double")])
5551 (define_insn "*multf3_extend"
5552 [(set (match_operand:TF 0 "register_operand" "=e")
5553 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5554 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5555 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5556 "fdmulq\t%1, %2, %0"
5557 [(set_attr "type" "fpmul")])
5559 (define_expand "divtf3"
5560 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5561 (div:TF (match_operand:TF 1 "general_operand" "")
5562 (match_operand:TF 2 "general_operand" "")))]
5563 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5564 "emit_tfmode_binop (DIV, operands); DONE;")
5566 ;; don't have timing for quad-prec. divide.
5567 (define_insn "*divtf3_hq"
5568 [(set (match_operand:TF 0 "register_operand" "=e")
5569 (div:TF (match_operand:TF 1 "register_operand" "e")
5570 (match_operand:TF 2 "register_operand" "e")))]
5571 "TARGET_FPU && TARGET_HARD_QUAD"
5573 [(set_attr "type" "fpdivd")])
5575 (define_insn "divdf3"
5576 [(set (match_operand:DF 0 "register_operand" "=e")
5577 (div:DF (match_operand:DF 1 "register_operand" "e")
5578 (match_operand:DF 2 "register_operand" "e")))]
5581 [(set_attr "type" "fpdivd")
5582 (set_attr "fptype" "double")])
5584 (define_insn "divsf3"
5585 [(set (match_operand:SF 0 "register_operand" "=f")
5586 (div:SF (match_operand:SF 1 "register_operand" "f")
5587 (match_operand:SF 2 "register_operand" "f")))]
5590 [(set_attr "type" "fpdivs")])
5592 (define_expand "negtf2"
5593 [(set (match_operand:TF 0 "register_operand" "=e,e")
5594 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5598 (define_insn_and_split "*negtf2_notv9"
5599 [(set (match_operand:TF 0 "register_operand" "=e,e")
5600 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5601 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5607 "&& reload_completed
5608 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5609 [(set (match_dup 2) (neg:SF (match_dup 3)))
5610 (set (match_dup 4) (match_dup 5))
5611 (set (match_dup 6) (match_dup 7))]
5612 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5613 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5614 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5615 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5616 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5617 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5618 [(set_attr "type" "fpmove,*")
5619 (set_attr "length" "*,2")])
5621 (define_insn_and_split "*negtf2_v9"
5622 [(set (match_operand:TF 0 "register_operand" "=e,e")
5623 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5624 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5625 "TARGET_FPU && TARGET_V9"
5629 "&& reload_completed
5630 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5631 [(set (match_dup 2) (neg:DF (match_dup 3)))
5632 (set (match_dup 4) (match_dup 5))]
5633 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5634 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5635 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5636 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5637 [(set_attr "type" "fpmove,*")
5638 (set_attr "length" "*,2")
5639 (set_attr "fptype" "double")])
5641 (define_expand "negdf2"
5642 [(set (match_operand:DF 0 "register_operand" "")
5643 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5647 (define_insn_and_split "*negdf2_notv9"
5648 [(set (match_operand:DF 0 "register_operand" "=e,e")
5649 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5650 "TARGET_FPU && ! TARGET_V9"
5654 "&& reload_completed
5655 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5656 [(set (match_dup 2) (neg:SF (match_dup 3)))
5657 (set (match_dup 4) (match_dup 5))]
5658 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5659 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5660 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5661 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5662 [(set_attr "type" "fpmove,*")
5663 (set_attr "length" "*,2")])
5665 (define_insn "*negdf2_v9"
5666 [(set (match_operand:DF 0 "register_operand" "=e")
5667 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5668 "TARGET_FPU && TARGET_V9"
5670 [(set_attr "type" "fpmove")
5671 (set_attr "fptype" "double")])
5673 (define_insn "negsf2"
5674 [(set (match_operand:SF 0 "register_operand" "=f")
5675 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5678 [(set_attr "type" "fpmove")])
5680 (define_expand "abstf2"
5681 [(set (match_operand:TF 0 "register_operand" "")
5682 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5686 (define_insn_and_split "*abstf2_notv9"
5687 [(set (match_operand:TF 0 "register_operand" "=e,e")
5688 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5689 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5690 "TARGET_FPU && ! TARGET_V9"
5694 "&& reload_completed
5695 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5696 [(set (match_dup 2) (abs:SF (match_dup 3)))
5697 (set (match_dup 4) (match_dup 5))
5698 (set (match_dup 6) (match_dup 7))]
5699 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5700 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5701 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5702 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5703 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5704 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5705 [(set_attr "type" "fpmove,*")
5706 (set_attr "length" "*,2")])
5708 (define_insn "*abstf2_hq_v9"
5709 [(set (match_operand:TF 0 "register_operand" "=e,e")
5710 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5711 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5715 [(set_attr "type" "fpmove")
5716 (set_attr "fptype" "double,*")])
5718 (define_insn_and_split "*abstf2_v9"
5719 [(set (match_operand:TF 0 "register_operand" "=e,e")
5720 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5721 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5725 "&& reload_completed
5726 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5727 [(set (match_dup 2) (abs:DF (match_dup 3)))
5728 (set (match_dup 4) (match_dup 5))]
5729 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5730 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5731 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5732 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5733 [(set_attr "type" "fpmove,*")
5734 (set_attr "length" "*,2")
5735 (set_attr "fptype" "double,*")])
5737 (define_expand "absdf2"
5738 [(set (match_operand:DF 0 "register_operand" "")
5739 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5743 (define_insn_and_split "*absdf2_notv9"
5744 [(set (match_operand:DF 0 "register_operand" "=e,e")
5745 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5746 "TARGET_FPU && ! TARGET_V9"
5750 "&& reload_completed
5751 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5752 [(set (match_dup 2) (abs:SF (match_dup 3)))
5753 (set (match_dup 4) (match_dup 5))]
5754 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5755 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5756 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5757 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5758 [(set_attr "type" "fpmove,*")
5759 (set_attr "length" "*,2")])
5761 (define_insn "*absdf2_v9"
5762 [(set (match_operand:DF 0 "register_operand" "=e")
5763 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5764 "TARGET_FPU && TARGET_V9"
5766 [(set_attr "type" "fpmove")
5767 (set_attr "fptype" "double")])
5769 (define_insn "abssf2"
5770 [(set (match_operand:SF 0 "register_operand" "=f")
5771 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5774 [(set_attr "type" "fpmove")])
5776 (define_expand "sqrttf2"
5777 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5778 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5779 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5780 "emit_tfmode_unop (SQRT, operands); DONE;")
5782 (define_insn "*sqrttf2_hq"
5783 [(set (match_operand:TF 0 "register_operand" "=e")
5784 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5785 "TARGET_FPU && TARGET_HARD_QUAD"
5787 [(set_attr "type" "fpsqrtd")])
5789 (define_insn "sqrtdf2"
5790 [(set (match_operand:DF 0 "register_operand" "=e")
5791 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5794 [(set_attr "type" "fpsqrtd")
5795 (set_attr "fptype" "double")])
5797 (define_insn "sqrtsf2"
5798 [(set (match_operand:SF 0 "register_operand" "=f")
5799 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5802 [(set_attr "type" "fpsqrts")])
5805 ;; Arithmetic shift instructions.
5807 (define_insn "ashlsi3"
5808 [(set (match_operand:SI 0 "register_operand" "=r")
5809 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5810 (match_operand:SI 2 "arith_operand" "rI")))]
5813 if (GET_CODE (operands[2]) == CONST_INT)
5814 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5815 return "sll\t%1, %2, %0";
5817 [(set_attr "type" "shift")])
5819 (define_insn "*ashlsi3_extend"
5820 [(set (match_operand:DI 0 "register_operand" "=r")
5822 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5823 (match_operand:SI 2 "arith_operand" "rI"))))]
5826 if (GET_CODE (operands[2]) == CONST_INT)
5827 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5828 return "sll\t%1, %2, %0";
5830 [(set_attr "type" "shift")])
5832 (define_expand "ashldi3"
5833 [(set (match_operand:DI 0 "register_operand" "=r")
5834 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5835 (match_operand:SI 2 "arith_operand" "rI")))]
5836 "TARGET_ARCH64 || TARGET_V8PLUS"
5838 if (! TARGET_ARCH64)
5840 if (GET_CODE (operands[2]) == CONST_INT)
5842 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5847 (define_insn "*ashldi3_sp64"
5848 [(set (match_operand:DI 0 "register_operand" "=r")
5849 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5850 (match_operand:SI 2 "arith_operand" "rI")))]
5853 if (GET_CODE (operands[2]) == CONST_INT)
5854 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5855 return "sllx\t%1, %2, %0";
5857 [(set_attr "type" "shift")])
5860 (define_insn "ashldi3_v8plus"
5861 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5862 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5863 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5864 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5866 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5867 [(set_attr "type" "multi")
5868 (set_attr "length" "5,5,6")])
5870 ;; Optimize (1LL<<x)-1
5871 ;; XXX this also needs to be fixed to handle equal subregs
5872 ;; XXX first before we could re-enable it.
5874 ; [(set (match_operand:DI 0 "register_operand" "=h")
5875 ; (plus:DI (ashift:DI (const_int 1)
5876 ; (match_operand:SI 1 "arith_operand" "rI"))
5878 ; "0 && TARGET_V8PLUS"
5880 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5881 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5882 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5884 ; [(set_attr "type" "multi")
5885 ; (set_attr "length" "4")])
5887 (define_insn "*cmp_cc_ashift_1"
5888 [(set (reg:CC_NOOV CC_REG)
5889 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5893 "addcc\t%0, %0, %%g0"
5894 [(set_attr "type" "compare")])
5896 (define_insn "*cmp_cc_set_ashift_1"
5897 [(set (reg:CC_NOOV CC_REG)
5898 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5901 (set (match_operand:SI 0 "register_operand" "=r")
5902 (ashift:SI (match_dup 1) (const_int 1)))]
5905 [(set_attr "type" "compare")])
5907 (define_insn "ashrsi3"
5908 [(set (match_operand:SI 0 "register_operand" "=r")
5909 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5910 (match_operand:SI 2 "arith_operand" "rI")))]
5913 if (GET_CODE (operands[2]) == CONST_INT)
5914 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5915 return "sra\t%1, %2, %0";
5917 [(set_attr "type" "shift")])
5919 (define_insn "*ashrsi3_extend"
5920 [(set (match_operand:DI 0 "register_operand" "=r")
5921 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5922 (match_operand:SI 2 "arith_operand" "r"))))]
5925 [(set_attr "type" "shift")])
5927 ;; This handles the case as above, but with constant shift instead of
5928 ;; register. Combiner "simplifies" it for us a little bit though.
5929 (define_insn "*ashrsi3_extend2"
5930 [(set (match_operand:DI 0 "register_operand" "=r")
5931 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5933 (match_operand:SI 2 "small_int_operand" "I")))]
5934 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5936 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5937 return "sra\t%1, %2, %0";
5939 [(set_attr "type" "shift")])
5941 (define_expand "ashrdi3"
5942 [(set (match_operand:DI 0 "register_operand" "=r")
5943 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5944 (match_operand:SI 2 "arith_operand" "rI")))]
5945 "TARGET_ARCH64 || TARGET_V8PLUS"
5947 if (! TARGET_ARCH64)
5949 if (GET_CODE (operands[2]) == CONST_INT)
5950 FAIL; /* prefer generic code in this case */
5951 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5956 (define_insn "*ashrdi3_sp64"
5957 [(set (match_operand:DI 0 "register_operand" "=r")
5958 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5959 (match_operand:SI 2 "arith_operand" "rI")))]
5963 if (GET_CODE (operands[2]) == CONST_INT)
5964 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5965 return "srax\t%1, %2, %0";
5967 [(set_attr "type" "shift")])
5970 (define_insn "ashrdi3_v8plus"
5971 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5972 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5973 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5974 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5976 "* return output_v8plus_shift (operands, insn, \"srax\");"
5977 [(set_attr "type" "multi")
5978 (set_attr "length" "5,5,6")])
5980 (define_insn "lshrsi3"
5981 [(set (match_operand:SI 0 "register_operand" "=r")
5982 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5983 (match_operand:SI 2 "arith_operand" "rI")))]
5986 if (GET_CODE (operands[2]) == CONST_INT)
5987 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5988 return "srl\t%1, %2, %0";
5990 [(set_attr "type" "shift")])
5992 (define_insn "*lshrsi3_extend0"
5993 [(set (match_operand:DI 0 "register_operand" "=r")
5995 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5996 (match_operand:SI 2 "arith_operand" "rI"))))]
5999 if (GET_CODE (operands[2]) == CONST_INT)
6000 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6001 return "srl\t%1, %2, %0";
6003 [(set_attr "type" "shift")])
6005 ;; This handles the case where
6006 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6007 ;; but combiner "simplifies" it for us.
6008 (define_insn "*lshrsi3_extend1"
6009 [(set (match_operand:DI 0 "register_operand" "=r")
6010 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6011 (match_operand:SI 2 "arith_operand" "r")) 0)
6012 (match_operand 3 "const_int_operand" "")))]
6013 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6015 [(set_attr "type" "shift")])
6017 ;; This handles the case where
6018 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6019 ;; but combiner "simplifies" it for us.
6020 (define_insn "*lshrsi3_extend2"
6021 [(set (match_operand:DI 0 "register_operand" "=r")
6022 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6023 (match_operand 2 "small_int_operand" "I")
6025 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6027 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6028 return "srl\t%1, %2, %0";
6030 [(set_attr "type" "shift")])
6032 (define_expand "lshrdi3"
6033 [(set (match_operand:DI 0 "register_operand" "=r")
6034 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6035 (match_operand:SI 2 "arith_operand" "rI")))]
6036 "TARGET_ARCH64 || TARGET_V8PLUS"
6038 if (! TARGET_ARCH64)
6040 if (GET_CODE (operands[2]) == CONST_INT)
6042 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6047 (define_insn "*lshrdi3_sp64"
6048 [(set (match_operand:DI 0 "register_operand" "=r")
6049 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6050 (match_operand:SI 2 "arith_operand" "rI")))]
6053 if (GET_CODE (operands[2]) == CONST_INT)
6054 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6055 return "srlx\t%1, %2, %0";
6057 [(set_attr "type" "shift")])
6060 (define_insn "lshrdi3_v8plus"
6061 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6062 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6063 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6064 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6066 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6067 [(set_attr "type" "multi")
6068 (set_attr "length" "5,5,6")])
6071 [(set (match_operand:SI 0 "register_operand" "=r")
6072 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6074 (match_operand:SI 2 "small_int_operand" "I")))]
6075 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6077 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6078 return "srax\t%1, %2, %0";
6080 [(set_attr "type" "shift")])
6083 [(set (match_operand:SI 0 "register_operand" "=r")
6084 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6086 (match_operand:SI 2 "small_int_operand" "I")))]
6087 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6089 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6090 return "srlx\t%1, %2, %0";
6092 [(set_attr "type" "shift")])
6095 [(set (match_operand:SI 0 "register_operand" "=r")
6096 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6097 (match_operand:SI 2 "small_int_operand" "I")) 4)
6098 (match_operand:SI 3 "small_int_operand" "I")))]
6100 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6101 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6102 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6104 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6106 return "srax\t%1, %2, %0";
6108 [(set_attr "type" "shift")])
6111 [(set (match_operand:SI 0 "register_operand" "=r")
6112 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6113 (match_operand:SI 2 "small_int_operand" "I")) 4)
6114 (match_operand:SI 3 "small_int_operand" "I")))]
6116 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6117 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6118 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6120 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6122 return "srlx\t%1, %2, %0";
6124 [(set_attr "type" "shift")])
6127 ;; Unconditional and other jump instructions.
6130 [(set (pc) (label_ref (match_operand 0 "" "")))]
6132 "* return output_ubranch (operands[0], 0, insn);"
6133 [(set_attr "type" "uncond_branch")])
6135 (define_expand "tablejump"
6136 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6137 (use (label_ref (match_operand 1 "" "")))])]
6140 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6142 /* In pic mode, our address differences are against the base of the
6143 table. Add that base value back in; CSE ought to be able to combine
6144 the two address loads. */
6148 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6150 if (CASE_VECTOR_MODE != Pmode)
6151 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6152 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6153 operands[0] = memory_address (Pmode, tmp);
6157 (define_insn "*tablejump_sp32"
6158 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6159 (use (label_ref (match_operand 1 "" "")))]
6162 [(set_attr "type" "uncond_branch")])
6164 (define_insn "*tablejump_sp64"
6165 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6166 (use (label_ref (match_operand 1 "" "")))]
6169 [(set_attr "type" "uncond_branch")])
6172 ;; Jump to subroutine instructions.
6174 (define_expand "call"
6175 ;; Note that this expression is not used for generating RTL.
6176 ;; All the RTL is generated explicitly below.
6177 [(call (match_operand 0 "call_operand" "")
6178 (match_operand 3 "" "i"))]
6179 ;; operands[2] is next_arg_register
6180 ;; operands[3] is struct_value_size_rtx.
6185 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6187 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6189 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6191 /* This is really a PIC sequence. We want to represent
6192 it as a funny jump so its delay slots can be filled.
6194 ??? But if this really *is* a CALL, will not it clobber the
6195 call-clobbered registers? We lose this if it is a JUMP_INSN.
6196 Why cannot we have delay slots filled if it were a CALL? */
6198 /* We accept negative sizes for untyped calls. */
6199 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6204 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6206 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6212 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6213 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6217 fn_rtx = operands[0];
6219 /* We accept negative sizes for untyped calls. */
6220 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6221 sparc_emit_call_insn
6224 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6226 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6229 sparc_emit_call_insn
6232 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6233 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6241 ;; We can't use the same pattern for these two insns, because then registers
6242 ;; in the address may not be properly reloaded.
6244 (define_insn "*call_address_sp32"
6245 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6246 (match_operand 1 "" ""))
6247 (clobber (reg:SI O7_REG))]
6248 ;;- Do not use operand 1 for most machines.
6251 [(set_attr "type" "call")])
6253 (define_insn "*call_symbolic_sp32"
6254 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6255 (match_operand 1 "" ""))
6256 (clobber (reg:SI O7_REG))]
6257 ;;- Do not use operand 1 for most machines.
6260 [(set_attr "type" "call")])
6262 (define_insn "*call_address_sp64"
6263 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6264 (match_operand 1 "" ""))
6265 (clobber (reg:DI O7_REG))]
6266 ;;- Do not use operand 1 for most machines.
6269 [(set_attr "type" "call")])
6271 (define_insn "*call_symbolic_sp64"
6272 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6273 (match_operand 1 "" ""))
6274 (clobber (reg:DI O7_REG))]
6275 ;;- Do not use operand 1 for most machines.
6278 [(set_attr "type" "call")])
6280 ;; This is a call that wants a structure value.
6281 ;; There is no such critter for v9 (??? we may need one anyway).
6282 (define_insn "*call_address_struct_value_sp32"
6283 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6284 (match_operand 1 "" ""))
6285 (match_operand 2 "immediate_operand" "")
6286 (clobber (reg:SI O7_REG))]
6287 ;;- Do not use operand 1 for most machines.
6288 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6290 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6291 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6293 [(set_attr "type" "call_no_delay_slot")
6294 (set_attr "length" "3")])
6296 ;; This is a call that wants a structure value.
6297 ;; There is no such critter for v9 (??? we may need one anyway).
6298 (define_insn "*call_symbolic_struct_value_sp32"
6299 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6300 (match_operand 1 "" ""))
6301 (match_operand 2 "immediate_operand" "")
6302 (clobber (reg:SI O7_REG))]
6303 ;;- Do not use operand 1 for most machines.
6304 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6306 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6307 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6309 [(set_attr "type" "call_no_delay_slot")
6310 (set_attr "length" "3")])
6312 ;; This is a call that may want a structure value. This is used for
6314 (define_insn "*call_address_untyped_struct_value_sp32"
6315 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6316 (match_operand 1 "" ""))
6317 (match_operand 2 "immediate_operand" "")
6318 (clobber (reg:SI O7_REG))]
6319 ;;- Do not use operand 1 for most machines.
6320 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6321 "call\t%a0, %1\n\t nop\n\tnop"
6322 [(set_attr "type" "call_no_delay_slot")
6323 (set_attr "length" "3")])
6325 ;; This is a call that may want a structure value. This is used for
6327 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6328 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6329 (match_operand 1 "" ""))
6330 (match_operand 2 "immediate_operand" "")
6331 (clobber (reg:SI O7_REG))]
6332 ;;- Do not use operand 1 for most machines.
6333 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6334 "call\t%a0, %1\n\t nop\n\tnop"
6335 [(set_attr "type" "call_no_delay_slot")
6336 (set_attr "length" "3")])
6338 (define_expand "call_value"
6339 ;; Note that this expression is not used for generating RTL.
6340 ;; All the RTL is generated explicitly below.
6341 [(set (match_operand 0 "register_operand" "=rf")
6342 (call (match_operand 1 "" "")
6343 (match_operand 4 "" "")))]
6344 ;; operand 2 is stack_size_rtx
6345 ;; operand 3 is next_arg_register
6351 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6353 fn_rtx = operands[1];
6356 gen_rtx_SET (VOIDmode, operands[0],
6357 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6358 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6360 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6365 (define_insn "*call_value_address_sp32"
6366 [(set (match_operand 0 "" "=rf")
6367 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6368 (match_operand 2 "" "")))
6369 (clobber (reg:SI O7_REG))]
6370 ;;- Do not use operand 2 for most machines.
6373 [(set_attr "type" "call")])
6375 (define_insn "*call_value_symbolic_sp32"
6376 [(set (match_operand 0 "" "=rf")
6377 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6378 (match_operand 2 "" "")))
6379 (clobber (reg:SI O7_REG))]
6380 ;;- Do not use operand 2 for most machines.
6383 [(set_attr "type" "call")])
6385 (define_insn "*call_value_address_sp64"
6386 [(set (match_operand 0 "" "")
6387 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6388 (match_operand 2 "" "")))
6389 (clobber (reg:DI O7_REG))]
6390 ;;- Do not use operand 2 for most machines.
6393 [(set_attr "type" "call")])
6395 (define_insn "*call_value_symbolic_sp64"
6396 [(set (match_operand 0 "" "")
6397 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6398 (match_operand 2 "" "")))
6399 (clobber (reg:DI O7_REG))]
6400 ;;- Do not use operand 2 for most machines.
6403 [(set_attr "type" "call")])
6405 (define_expand "untyped_call"
6406 [(parallel [(call (match_operand 0 "" "")
6408 (match_operand:BLK 1 "memory_operand" "")
6409 (match_operand 2 "" "")])]
6412 rtx valreg1 = gen_rtx_REG (DImode, 8);
6413 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6414 rtx result = operands[1];
6416 /* Pass constm1 to indicate that it may expect a structure value, but
6417 we don't know what size it is. */
6418 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6420 /* Save the function value registers. */
6421 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6422 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6425 /* The optimizer does not know that the call sets the function value
6426 registers we stored in the result block. We avoid problems by
6427 claiming that all hard registers are used and clobbered at this
6429 emit_insn (gen_blockage ());
6434 ;; Tail call instructions.
6436 (define_expand "sibcall"
6437 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6442 (define_insn "*sibcall_symbolic_sp32"
6443 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6444 (match_operand 1 "" ""))
6447 "* return output_sibcall(insn, operands[0]);"
6448 [(set_attr "type" "sibcall")])
6450 (define_insn "*sibcall_symbolic_sp64"
6451 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6452 (match_operand 1 "" ""))
6455 "* return output_sibcall(insn, operands[0]);"
6456 [(set_attr "type" "sibcall")])
6458 (define_expand "sibcall_value"
6459 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6460 (call (match_operand 1 "" "") (const_int 0)))
6465 (define_insn "*sibcall_value_symbolic_sp32"
6466 [(set (match_operand 0 "" "=rf")
6467 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6468 (match_operand 2 "" "")))
6471 "* return output_sibcall(insn, operands[1]);"
6472 [(set_attr "type" "sibcall")])
6474 (define_insn "*sibcall_value_symbolic_sp64"
6475 [(set (match_operand 0 "" "")
6476 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6477 (match_operand 2 "" "")))
6480 "* return output_sibcall(insn, operands[1]);"
6481 [(set_attr "type" "sibcall")])
6484 ;; Special instructions.
6486 (define_expand "prologue"
6491 sparc_flat_expand_prologue ();
6493 sparc_expand_prologue ();
6497 ;; The "register window save" insn is modelled as follows. The dwarf2
6498 ;; information is manually added in emit_window_save.
6500 (define_insn "window_save"
6502 [(match_operand 0 "arith_operand" "rI")]
6505 "save\t%%sp, %0, %%sp"
6506 [(set_attr "type" "savew")])
6508 (define_expand "epilogue"
6513 sparc_flat_expand_epilogue (false);
6515 sparc_expand_epilogue (false);
6518 (define_expand "sibcall_epilogue"
6523 sparc_flat_expand_epilogue (false);
6525 sparc_expand_epilogue (false);
6529 (define_expand "eh_return"
6530 [(use (match_operand 0 "general_operand" ""))]
6533 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6534 emit_jump_insn (gen_eh_return_internal ());
6539 (define_insn_and_split "eh_return_internal"
6543 "epilogue_completed"
6547 sparc_flat_expand_epilogue (true);
6549 sparc_expand_epilogue (true);
6552 (define_expand "return"
6554 "sparc_can_use_return_insn_p ()"
6557 (define_insn "*return_internal"
6560 "* return output_return (insn);"
6561 [(set_attr "type" "return")
6562 (set (attr "length")
6563 (cond [(eq_attr "calls_eh_return" "true")
6564 (if_then_else (eq_attr "delayed_branch" "true")
6565 (if_then_else (ior (eq_attr "isa" "v9")
6566 (eq_attr "flat" "true"))
6569 (if_then_else (eq_attr "flat" "true")
6572 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6573 (if_then_else (eq_attr "empty_delay_slot" "true")
6576 (eq_attr "empty_delay_slot" "true")
6577 (if_then_else (eq_attr "delayed_branch" "true")
6582 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6583 ;; all of memory. This blocks insns from being moved across this point.
6585 (define_insn "blockage"
6586 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6589 [(set_attr "length" "0")])
6591 (define_expand "probe_stack"
6592 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6596 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6599 (define_insn "probe_stack_range<P:mode>"
6600 [(set (match_operand:P 0 "register_operand" "=r")
6601 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6602 (match_operand:P 2 "register_operand" "r")]
6603 UNSPECV_PROBE_STACK_RANGE))]
6605 "* return output_probe_stack_range (operands[0], operands[2]);"
6606 [(set_attr "type" "multi")])
6608 ;; Prepare to return any type including a structure value.
6610 (define_expand "untyped_return"
6611 [(match_operand:BLK 0 "memory_operand" "")
6612 (match_operand 1 "" "")]
6615 rtx valreg1 = gen_rtx_REG (DImode, 24);
6616 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6617 rtx result = operands[0];
6619 if (! TARGET_ARCH64)
6621 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6622 rtx value = gen_reg_rtx (SImode);
6624 /* Fetch the instruction where we will return to and see if it's an unimp
6625 instruction (the most significant 10 bits will be zero). If so,
6626 update the return address to skip the unimp instruction. */
6627 emit_move_insn (value,
6628 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6629 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6630 emit_insn (gen_update_return (rtnreg, value));
6633 /* Reload the function value registers. */
6634 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6635 emit_move_insn (valreg2,
6636 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6638 /* Put USE insns before the return. */
6642 /* Construct the return. */
6643 expand_naked_return ();
6648 ;; Adjust the return address conditionally. If the value of op1 is equal
6649 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6650 ;; This is technically *half* the check required by the 32-bit SPARC
6651 ;; psABI. This check only ensures that an "unimp" insn was written by
6652 ;; the caller, but doesn't check to see if the expected size matches
6653 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6654 ;; only used by the above code "untyped_return".
6656 (define_insn "update_return"
6657 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6658 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6661 if (flag_delayed_branch)
6662 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6664 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6666 [(set (attr "type") (const_string "multi"))
6667 (set (attr "length")
6668 (if_then_else (eq_attr "delayed_branch" "true")
6677 (define_expand "indirect_jump"
6678 [(set (pc) (match_operand 0 "address_operand" "p"))]
6682 (define_insn "*branch_sp32"
6683 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6686 [(set_attr "type" "uncond_branch")])
6688 (define_insn "*branch_sp64"
6689 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6692 [(set_attr "type" "uncond_branch")])
6694 (define_expand "save_stack_nonlocal"
6695 [(set (match_operand 0 "memory_operand" "")
6696 (match_operand 1 "register_operand" ""))
6697 (set (match_dup 2) (match_dup 3))]
6700 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6701 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6702 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6705 (define_expand "restore_stack_nonlocal"
6706 [(set (match_operand 0 "register_operand" "")
6707 (match_operand 1 "memory_operand" ""))]
6710 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6713 (define_expand "nonlocal_goto"
6714 [(match_operand 0 "general_operand" "")
6715 (match_operand 1 "general_operand" "")
6716 (match_operand 2 "memory_operand" "")
6717 (match_operand 3 "memory_operand" "")]
6720 rtx r_label = copy_to_reg (operands[1]);
6721 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6722 rtx r_fp = operands[3];
6723 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6725 /* We need to flush all the register windows so that their contents will
6726 be re-synchronized by the restore insn of the target function. */
6728 emit_insn (gen_flush_register_windows ());
6730 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6731 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6733 /* Restore frame pointer for containing function. */
6734 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6735 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6737 /* USE of hard_frame_pointer_rtx added for consistency;
6738 not clear if really needed. */
6739 emit_use (hard_frame_pointer_rtx);
6740 emit_use (stack_pointer_rtx);
6742 /* We need to smuggle the load of %i7 as it is a fixed register. */
6743 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6748 (define_insn "nonlocal_goto_internal"
6749 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6750 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6751 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6753 if (flag_delayed_branch)
6756 return "jmp\t%0\n\t ldx\t%1, %%i7";
6758 return "jmp\t%0\n\t ld\t%1, %%i7";
6763 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6765 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6768 [(set (attr "type") (const_string "multi"))
6769 (set (attr "length")
6770 (if_then_else (eq_attr "delayed_branch" "true")
6774 (define_expand "builtin_setjmp_receiver"
6775 [(label_ref (match_operand 0 "" ""))]
6778 load_got_register ();
6782 ;; Special insn to flush register windows.
6784 (define_insn "flush_register_windows"
6785 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6787 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6788 [(set_attr "type" "flushw")])
6790 ;; Special pattern for the FLUSH instruction.
6792 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6793 ; of the define_insn otherwise missing a mode. We make "flush", aka
6794 ; gen_flush, the default one since sparc_initialize_trampoline uses
6795 ; it on SImode mem values.
6797 (define_insn "flush"
6798 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6800 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6801 [(set_attr "type" "iflush")])
6803 (define_insn "flushdi"
6804 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6806 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6807 [(set_attr "type" "iflush")])
6810 ;; Find first set instructions.
6812 ;; The scan instruction searches from the most significant bit while ffs
6813 ;; searches from the least significant bit. The bit index and treatment of
6814 ;; zero also differ. It takes at least 7 instructions to get the proper
6815 ;; result. Here is an obvious 8 instruction sequence.
6818 (define_insn "ffssi2"
6819 [(set (match_operand:SI 0 "register_operand" "=&r")
6820 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6821 (clobber (match_scratch:SI 2 "=&r"))]
6822 "TARGET_SPARCLITE || TARGET_SPARCLET"
6824 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";
6826 [(set_attr "type" "multi")
6827 (set_attr "length" "8")])
6829 ;; ??? This should be a define expand, so that the extra instruction have
6830 ;; a chance of being optimized away.
6832 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6833 ;; does, but no one uses that and we don't have a switch for it.
6835 ;(define_insn "ffsdi2"
6836 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6837 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6838 ; (clobber (match_scratch:DI 2 "=&r"))]
6840 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6841 ; [(set_attr "type" "multi")
6842 ; (set_attr "length" "4")])
6846 ;; Peepholes go at the end.
6848 ;; Optimize consecutive loads or stores into ldd and std when possible.
6849 ;; The conditions in which we do this are very restricted and are
6850 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6853 [(set (match_operand:SI 0 "memory_operand" "")
6855 (set (match_operand:SI 1 "memory_operand" "")
6858 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6861 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6864 [(set (match_operand:SI 0 "memory_operand" "")
6866 (set (match_operand:SI 1 "memory_operand" "")
6869 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6872 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6875 [(set (match_operand:SI 0 "register_operand" "")
6876 (match_operand:SI 1 "memory_operand" ""))
6877 (set (match_operand:SI 2 "register_operand" "")
6878 (match_operand:SI 3 "memory_operand" ""))]
6879 "registers_ok_for_ldd_peep (operands[0], operands[2])
6880 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6883 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6884 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6887 [(set (match_operand:SI 0 "memory_operand" "")
6888 (match_operand:SI 1 "register_operand" ""))
6889 (set (match_operand:SI 2 "memory_operand" "")
6890 (match_operand:SI 3 "register_operand" ""))]
6891 "registers_ok_for_ldd_peep (operands[1], operands[3])
6892 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6895 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6896 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6899 [(set (match_operand:SF 0 "register_operand" "")
6900 (match_operand:SF 1 "memory_operand" ""))
6901 (set (match_operand:SF 2 "register_operand" "")
6902 (match_operand:SF 3 "memory_operand" ""))]
6903 "registers_ok_for_ldd_peep (operands[0], operands[2])
6904 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6907 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6908 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6911 [(set (match_operand:SF 0 "memory_operand" "")
6912 (match_operand:SF 1 "register_operand" ""))
6913 (set (match_operand:SF 2 "memory_operand" "")
6914 (match_operand:SF 3 "register_operand" ""))]
6915 "registers_ok_for_ldd_peep (operands[1], operands[3])
6916 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6919 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6920 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6923 [(set (match_operand:SI 0 "register_operand" "")
6924 (match_operand:SI 1 "memory_operand" ""))
6925 (set (match_operand:SI 2 "register_operand" "")
6926 (match_operand:SI 3 "memory_operand" ""))]
6927 "registers_ok_for_ldd_peep (operands[2], operands[0])
6928 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6931 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6932 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6935 [(set (match_operand:SI 0 "memory_operand" "")
6936 (match_operand:SI 1 "register_operand" ""))
6937 (set (match_operand:SI 2 "memory_operand" "")
6938 (match_operand:SI 3 "register_operand" ""))]
6939 "registers_ok_for_ldd_peep (operands[3], operands[1])
6940 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6943 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6944 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6948 [(set (match_operand:SF 0 "register_operand" "")
6949 (match_operand:SF 1 "memory_operand" ""))
6950 (set (match_operand:SF 2 "register_operand" "")
6951 (match_operand:SF 3 "memory_operand" ""))]
6952 "registers_ok_for_ldd_peep (operands[2], operands[0])
6953 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6956 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6957 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6960 [(set (match_operand:SF 0 "memory_operand" "")
6961 (match_operand:SF 1 "register_operand" ""))
6962 (set (match_operand:SF 2 "memory_operand" "")
6963 (match_operand:SF 3 "register_operand" ""))]
6964 "registers_ok_for_ldd_peep (operands[3], operands[1])
6965 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6968 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6969 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6971 ;; Optimize the case of following a reg-reg move with a test
6972 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6973 ;; This can result from a float to fix conversion.
6976 [(set (match_operand:SI 0 "register_operand" "")
6977 (match_operand:SI 1 "register_operand" ""))
6978 (set (reg:CC CC_REG)
6979 (compare:CC (match_operand:SI 2 "register_operand" "")
6981 "(rtx_equal_p (operands[2], operands[0])
6982 || rtx_equal_p (operands[2], operands[1]))
6983 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6984 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6985 [(parallel [(set (match_dup 0) (match_dup 1))
6986 (set (reg:CC CC_REG)
6987 (compare:CC (match_dup 1) (const_int 0)))])]
6991 [(set (match_operand:DI 0 "register_operand" "")
6992 (match_operand:DI 1 "register_operand" ""))
6993 (set (reg:CCX CC_REG)
6994 (compare:CCX (match_operand:DI 2 "register_operand" "")
6997 && (rtx_equal_p (operands[2], operands[0])
6998 || rtx_equal_p (operands[2], operands[1]))
6999 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7000 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7001 [(parallel [(set (match_dup 0) (match_dup 1))
7002 (set (reg:CCX CC_REG)
7003 (compare:CCX (match_dup 1) (const_int 0)))])]
7007 ;; Prefetch instructions.
7009 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7010 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7011 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7013 (define_expand "prefetch"
7014 [(match_operand 0 "address_operand" "")
7015 (match_operand 1 "const_int_operand" "")
7016 (match_operand 2 "const_int_operand" "")]
7020 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7022 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7026 (define_insn "prefetch_64"
7027 [(prefetch (match_operand:DI 0 "address_operand" "p")
7028 (match_operand:DI 1 "const_int_operand" "n")
7029 (match_operand:DI 2 "const_int_operand" "n"))]
7032 static const char * const prefetch_instr[2][2] = {
7034 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7035 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7038 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7039 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7042 int read_or_write = INTVAL (operands[1]);
7043 int locality = INTVAL (operands[2]);
7045 gcc_assert (read_or_write == 0 || read_or_write == 1);
7046 gcc_assert (locality >= 0 && locality < 4);
7047 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7049 [(set_attr "type" "load")])
7051 (define_insn "prefetch_32"
7052 [(prefetch (match_operand:SI 0 "address_operand" "p")
7053 (match_operand:SI 1 "const_int_operand" "n")
7054 (match_operand:SI 2 "const_int_operand" "n"))]
7057 static const char * const prefetch_instr[2][2] = {
7059 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7060 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7063 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7064 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7067 int read_or_write = INTVAL (operands[1]);
7068 int locality = INTVAL (operands[2]);
7070 gcc_assert (read_or_write == 0 || read_or_write == 1);
7071 gcc_assert (locality >= 0 && locality < 4);
7072 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7074 [(set_attr "type" "load")])
7077 ;; Trap instructions.
7080 [(trap_if (const_int 1) (const_int 5))]
7083 [(set_attr "type" "trap")])
7085 (define_expand "ctrapsi4"
7086 [(trap_if (match_operator 0 "noov_compare_operator"
7087 [(match_operand:SI 1 "compare_operand" "")
7088 (match_operand:SI 2 "arith_operand" "")])
7089 (match_operand 3 ""))]
7091 "operands[1] = gen_compare_reg (operands[0]);
7092 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7094 operands[2] = const0_rtx;")
7096 (define_expand "ctrapdi4"
7097 [(trap_if (match_operator 0 "noov_compare_operator"
7098 [(match_operand:DI 1 "compare_operand" "")
7099 (match_operand:DI 2 "arith_operand" "")])
7100 (match_operand 3 ""))]
7102 "operands[1] = gen_compare_reg (operands[0]);
7103 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7105 operands[2] = const0_rtx;")
7109 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7110 (match_operand:SI 1 "arith_operand" "rM"))]
7114 return "t%C0\t%%icc, %1";
7118 [(set_attr "type" "trap")])
7121 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7122 (match_operand:SI 1 "arith_operand" "rM"))]
7125 [(set_attr "type" "trap")])
7128 ;; TLS support instructions.
7130 (define_insn "tgd_hi22"
7131 [(set (match_operand:SI 0 "register_operand" "=r")
7132 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7135 "sethi\\t%%tgd_hi22(%a1), %0")
7137 (define_insn "tgd_lo10"
7138 [(set (match_operand:SI 0 "register_operand" "=r")
7139 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7140 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7143 "add\\t%1, %%tgd_lo10(%a2), %0")
7145 (define_insn "tgd_add32"
7146 [(set (match_operand:SI 0 "register_operand" "=r")
7147 (plus:SI (match_operand:SI 1 "register_operand" "r")
7148 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7149 (match_operand 3 "tgd_symbolic_operand" "")]
7151 "TARGET_TLS && TARGET_ARCH32"
7152 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7154 (define_insn "tgd_add64"
7155 [(set (match_operand:DI 0 "register_operand" "=r")
7156 (plus:DI (match_operand:DI 1 "register_operand" "r")
7157 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7158 (match_operand 3 "tgd_symbolic_operand" "")]
7160 "TARGET_TLS && TARGET_ARCH64"
7161 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7163 (define_insn "tgd_call32"
7164 [(set (match_operand 0 "register_operand" "=r")
7165 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7166 (match_operand 2 "tgd_symbolic_operand" "")]
7168 (match_operand 3 "" "")))
7169 (clobber (reg:SI O7_REG))]
7170 "TARGET_TLS && TARGET_ARCH32"
7171 "call\t%a1, %%tgd_call(%a2)%#"
7172 [(set_attr "type" "call")])
7174 (define_insn "tgd_call64"
7175 [(set (match_operand 0 "register_operand" "=r")
7176 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7177 (match_operand 2 "tgd_symbolic_operand" "")]
7179 (match_operand 3 "" "")))
7180 (clobber (reg:DI O7_REG))]
7181 "TARGET_TLS && TARGET_ARCH64"
7182 "call\t%a1, %%tgd_call(%a2)%#"
7183 [(set_attr "type" "call")])
7185 (define_insn "tldm_hi22"
7186 [(set (match_operand:SI 0 "register_operand" "=r")
7187 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7189 "sethi\\t%%tldm_hi22(%&), %0")
7191 (define_insn "tldm_lo10"
7192 [(set (match_operand:SI 0 "register_operand" "=r")
7193 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7194 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7196 "add\\t%1, %%tldm_lo10(%&), %0")
7198 (define_insn "tldm_add32"
7199 [(set (match_operand:SI 0 "register_operand" "=r")
7200 (plus:SI (match_operand:SI 1 "register_operand" "r")
7201 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7203 "TARGET_TLS && TARGET_ARCH32"
7204 "add\\t%1, %2, %0, %%tldm_add(%&)")
7206 (define_insn "tldm_add64"
7207 [(set (match_operand:DI 0 "register_operand" "=r")
7208 (plus:DI (match_operand:DI 1 "register_operand" "r")
7209 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7211 "TARGET_TLS && TARGET_ARCH64"
7212 "add\\t%1, %2, %0, %%tldm_add(%&)")
7214 (define_insn "tldm_call32"
7215 [(set (match_operand 0 "register_operand" "=r")
7216 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7218 (match_operand 2 "" "")))
7219 (clobber (reg:SI O7_REG))]
7220 "TARGET_TLS && TARGET_ARCH32"
7221 "call\t%a1, %%tldm_call(%&)%#"
7222 [(set_attr "type" "call")])
7224 (define_insn "tldm_call64"
7225 [(set (match_operand 0 "register_operand" "=r")
7226 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7228 (match_operand 2 "" "")))
7229 (clobber (reg:DI O7_REG))]
7230 "TARGET_TLS && TARGET_ARCH64"
7231 "call\t%a1, %%tldm_call(%&)%#"
7232 [(set_attr "type" "call")])
7234 (define_insn "tldo_hix22"
7235 [(set (match_operand:SI 0 "register_operand" "=r")
7236 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7239 "sethi\\t%%tldo_hix22(%a1), %0")
7241 (define_insn "tldo_lox10"
7242 [(set (match_operand:SI 0 "register_operand" "=r")
7243 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7244 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7247 "xor\\t%1, %%tldo_lox10(%a2), %0")
7249 (define_insn "tldo_add32"
7250 [(set (match_operand:SI 0 "register_operand" "=r")
7251 (plus:SI (match_operand:SI 1 "register_operand" "r")
7252 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7253 (match_operand 3 "tld_symbolic_operand" "")]
7255 "TARGET_TLS && TARGET_ARCH32"
7256 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7258 (define_insn "tldo_add64"
7259 [(set (match_operand:DI 0 "register_operand" "=r")
7260 (plus:DI (match_operand:DI 1 "register_operand" "r")
7261 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7262 (match_operand 3 "tld_symbolic_operand" "")]
7264 "TARGET_TLS && TARGET_ARCH64"
7265 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7267 (define_insn "tie_hi22"
7268 [(set (match_operand:SI 0 "register_operand" "=r")
7269 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7272 "sethi\\t%%tie_hi22(%a1), %0")
7274 (define_insn "tie_lo10"
7275 [(set (match_operand:SI 0 "register_operand" "=r")
7276 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7277 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7280 "add\\t%1, %%tie_lo10(%a2), %0")
7282 (define_insn "tie_ld32"
7283 [(set (match_operand:SI 0 "register_operand" "=r")
7284 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7285 (match_operand:SI 2 "register_operand" "r")
7286 (match_operand 3 "tie_symbolic_operand" "")]
7288 "TARGET_TLS && TARGET_ARCH32"
7289 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7290 [(set_attr "type" "load")])
7292 (define_insn "tie_ld64"
7293 [(set (match_operand:DI 0 "register_operand" "=r")
7294 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7295 (match_operand:SI 2 "register_operand" "r")
7296 (match_operand 3 "tie_symbolic_operand" "")]
7298 "TARGET_TLS && TARGET_ARCH64"
7299 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7300 [(set_attr "type" "load")])
7302 (define_insn "tie_add32"
7303 [(set (match_operand:SI 0 "register_operand" "=r")
7304 (plus:SI (match_operand:SI 1 "register_operand" "r")
7305 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7306 (match_operand 3 "tie_symbolic_operand" "")]
7308 "TARGET_SUN_TLS && TARGET_ARCH32"
7309 "add\\t%1, %2, %0, %%tie_add(%a3)")
7311 (define_insn "tie_add64"
7312 [(set (match_operand:DI 0 "register_operand" "=r")
7313 (plus:DI (match_operand:DI 1 "register_operand" "r")
7314 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7315 (match_operand 3 "tie_symbolic_operand" "")]
7317 "TARGET_SUN_TLS && TARGET_ARCH64"
7318 "add\\t%1, %2, %0, %%tie_add(%a3)")
7320 (define_insn "tle_hix22_sp32"
7321 [(set (match_operand:SI 0 "register_operand" "=r")
7322 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7324 "TARGET_TLS && TARGET_ARCH32"
7325 "sethi\\t%%tle_hix22(%a1), %0")
7327 (define_insn "tle_lox10_sp32"
7328 [(set (match_operand:SI 0 "register_operand" "=r")
7329 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7330 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7332 "TARGET_TLS && TARGET_ARCH32"
7333 "xor\\t%1, %%tle_lox10(%a2), %0")
7335 (define_insn "tle_hix22_sp64"
7336 [(set (match_operand:DI 0 "register_operand" "=r")
7337 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7339 "TARGET_TLS && TARGET_ARCH64"
7340 "sethi\\t%%tle_hix22(%a1), %0")
7342 (define_insn "tle_lox10_sp64"
7343 [(set (match_operand:DI 0 "register_operand" "=r")
7344 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7345 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7347 "TARGET_TLS && TARGET_ARCH64"
7348 "xor\\t%1, %%tle_lox10(%a2), %0")
7350 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7351 (define_insn "*tldo_ldub_sp32"
7352 [(set (match_operand:QI 0 "register_operand" "=r")
7353 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7354 (match_operand 3 "tld_symbolic_operand" "")]
7356 (match_operand:SI 1 "register_operand" "r"))))]
7357 "TARGET_TLS && TARGET_ARCH32"
7358 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7359 [(set_attr "type" "load")
7360 (set_attr "us3load_type" "3cycle")])
7362 (define_insn "*tldo_ldub1_sp32"
7363 [(set (match_operand:HI 0 "register_operand" "=r")
7364 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7365 (match_operand 3 "tld_symbolic_operand" "")]
7367 (match_operand:SI 1 "register_operand" "r")))))]
7368 "TARGET_TLS && TARGET_ARCH32"
7369 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7370 [(set_attr "type" "load")
7371 (set_attr "us3load_type" "3cycle")])
7373 (define_insn "*tldo_ldub2_sp32"
7374 [(set (match_operand:SI 0 "register_operand" "=r")
7375 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7376 (match_operand 3 "tld_symbolic_operand" "")]
7378 (match_operand:SI 1 "register_operand" "r")))))]
7379 "TARGET_TLS && TARGET_ARCH32"
7380 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7381 [(set_attr "type" "load")
7382 (set_attr "us3load_type" "3cycle")])
7384 (define_insn "*tldo_ldsb1_sp32"
7385 [(set (match_operand:HI 0 "register_operand" "=r")
7386 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7387 (match_operand 3 "tld_symbolic_operand" "")]
7389 (match_operand:SI 1 "register_operand" "r")))))]
7390 "TARGET_TLS && TARGET_ARCH32"
7391 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7392 [(set_attr "type" "sload")
7393 (set_attr "us3load_type" "3cycle")])
7395 (define_insn "*tldo_ldsb2_sp32"
7396 [(set (match_operand:SI 0 "register_operand" "=r")
7397 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7398 (match_operand 3 "tld_symbolic_operand" "")]
7400 (match_operand:SI 1 "register_operand" "r")))))]
7401 "TARGET_TLS && TARGET_ARCH32"
7402 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7403 [(set_attr "type" "sload")
7404 (set_attr "us3load_type" "3cycle")])
7406 (define_insn "*tldo_ldub_sp64"
7407 [(set (match_operand:QI 0 "register_operand" "=r")
7408 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7409 (match_operand 3 "tld_symbolic_operand" "")]
7411 (match_operand:DI 1 "register_operand" "r"))))]
7412 "TARGET_TLS && TARGET_ARCH64"
7413 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7414 [(set_attr "type" "load")
7415 (set_attr "us3load_type" "3cycle")])
7417 (define_insn "*tldo_ldub1_sp64"
7418 [(set (match_operand:HI 0 "register_operand" "=r")
7419 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7420 (match_operand 3 "tld_symbolic_operand" "")]
7422 (match_operand:DI 1 "register_operand" "r")))))]
7423 "TARGET_TLS && TARGET_ARCH64"
7424 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7425 [(set_attr "type" "load")
7426 (set_attr "us3load_type" "3cycle")])
7428 (define_insn "*tldo_ldub2_sp64"
7429 [(set (match_operand:SI 0 "register_operand" "=r")
7430 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7431 (match_operand 3 "tld_symbolic_operand" "")]
7433 (match_operand:DI 1 "register_operand" "r")))))]
7434 "TARGET_TLS && TARGET_ARCH64"
7435 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7436 [(set_attr "type" "load")
7437 (set_attr "us3load_type" "3cycle")])
7439 (define_insn "*tldo_ldub3_sp64"
7440 [(set (match_operand:DI 0 "register_operand" "=r")
7441 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7442 (match_operand 3 "tld_symbolic_operand" "")]
7444 (match_operand:DI 1 "register_operand" "r")))))]
7445 "TARGET_TLS && TARGET_ARCH64"
7446 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7447 [(set_attr "type" "load")
7448 (set_attr "us3load_type" "3cycle")])
7450 (define_insn "*tldo_ldsb1_sp64"
7451 [(set (match_operand:HI 0 "register_operand" "=r")
7452 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7453 (match_operand 3 "tld_symbolic_operand" "")]
7455 (match_operand:DI 1 "register_operand" "r")))))]
7456 "TARGET_TLS && TARGET_ARCH64"
7457 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7458 [(set_attr "type" "sload")
7459 (set_attr "us3load_type" "3cycle")])
7461 (define_insn "*tldo_ldsb2_sp64"
7462 [(set (match_operand:SI 0 "register_operand" "=r")
7463 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7464 (match_operand 3 "tld_symbolic_operand" "")]
7466 (match_operand:DI 1 "register_operand" "r")))))]
7467 "TARGET_TLS && TARGET_ARCH64"
7468 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7469 [(set_attr "type" "sload")
7470 (set_attr "us3load_type" "3cycle")])
7472 (define_insn "*tldo_ldsb3_sp64"
7473 [(set (match_operand:DI 0 "register_operand" "=r")
7474 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7475 (match_operand 3 "tld_symbolic_operand" "")]
7477 (match_operand:DI 1 "register_operand" "r")))))]
7478 "TARGET_TLS && TARGET_ARCH64"
7479 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7480 [(set_attr "type" "sload")
7481 (set_attr "us3load_type" "3cycle")])
7483 (define_insn "*tldo_lduh_sp32"
7484 [(set (match_operand:HI 0 "register_operand" "=r")
7485 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7486 (match_operand 3 "tld_symbolic_operand" "")]
7488 (match_operand:SI 1 "register_operand" "r"))))]
7489 "TARGET_TLS && TARGET_ARCH32"
7490 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7491 [(set_attr "type" "load")
7492 (set_attr "us3load_type" "3cycle")])
7494 (define_insn "*tldo_lduh1_sp32"
7495 [(set (match_operand:SI 0 "register_operand" "=r")
7496 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7497 (match_operand 3 "tld_symbolic_operand" "")]
7499 (match_operand:SI 1 "register_operand" "r")))))]
7500 "TARGET_TLS && TARGET_ARCH32"
7501 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7502 [(set_attr "type" "load")
7503 (set_attr "us3load_type" "3cycle")])
7505 (define_insn "*tldo_ldsh1_sp32"
7506 [(set (match_operand:SI 0 "register_operand" "=r")
7507 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7508 (match_operand 3 "tld_symbolic_operand" "")]
7510 (match_operand:SI 1 "register_operand" "r")))))]
7511 "TARGET_TLS && TARGET_ARCH32"
7512 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7513 [(set_attr "type" "sload")
7514 (set_attr "us3load_type" "3cycle")])
7516 (define_insn "*tldo_lduh_sp64"
7517 [(set (match_operand:HI 0 "register_operand" "=r")
7518 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7519 (match_operand 3 "tld_symbolic_operand" "")]
7521 (match_operand:DI 1 "register_operand" "r"))))]
7522 "TARGET_TLS && TARGET_ARCH64"
7523 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7524 [(set_attr "type" "load")
7525 (set_attr "us3load_type" "3cycle")])
7527 (define_insn "*tldo_lduh1_sp64"
7528 [(set (match_operand:SI 0 "register_operand" "=r")
7529 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7530 (match_operand 3 "tld_symbolic_operand" "")]
7532 (match_operand:DI 1 "register_operand" "r")))))]
7533 "TARGET_TLS && TARGET_ARCH64"
7534 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7535 [(set_attr "type" "load")
7536 (set_attr "us3load_type" "3cycle")])
7538 (define_insn "*tldo_lduh2_sp64"
7539 [(set (match_operand:DI 0 "register_operand" "=r")
7540 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7541 (match_operand 3 "tld_symbolic_operand" "")]
7543 (match_operand:DI 1 "register_operand" "r")))))]
7544 "TARGET_TLS && TARGET_ARCH64"
7545 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7546 [(set_attr "type" "load")
7547 (set_attr "us3load_type" "3cycle")])
7549 (define_insn "*tldo_ldsh1_sp64"
7550 [(set (match_operand:SI 0 "register_operand" "=r")
7551 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7552 (match_operand 3 "tld_symbolic_operand" "")]
7554 (match_operand:DI 1 "register_operand" "r")))))]
7555 "TARGET_TLS && TARGET_ARCH64"
7556 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7557 [(set_attr "type" "sload")
7558 (set_attr "us3load_type" "3cycle")])
7560 (define_insn "*tldo_ldsh2_sp64"
7561 [(set (match_operand:DI 0 "register_operand" "=r")
7562 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7563 (match_operand 3 "tld_symbolic_operand" "")]
7565 (match_operand:DI 1 "register_operand" "r")))))]
7566 "TARGET_TLS && TARGET_ARCH64"
7567 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7568 [(set_attr "type" "sload")
7569 (set_attr "us3load_type" "3cycle")])
7571 (define_insn "*tldo_lduw_sp32"
7572 [(set (match_operand:SI 0 "register_operand" "=r")
7573 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7574 (match_operand 3 "tld_symbolic_operand" "")]
7576 (match_operand:SI 1 "register_operand" "r"))))]
7577 "TARGET_TLS && TARGET_ARCH32"
7578 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7579 [(set_attr "type" "load")])
7581 (define_insn "*tldo_lduw_sp64"
7582 [(set (match_operand:SI 0 "register_operand" "=r")
7583 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7584 (match_operand 3 "tld_symbolic_operand" "")]
7586 (match_operand:DI 1 "register_operand" "r"))))]
7587 "TARGET_TLS && TARGET_ARCH64"
7588 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7589 [(set_attr "type" "load")])
7591 (define_insn "*tldo_lduw1_sp64"
7592 [(set (match_operand:DI 0 "register_operand" "=r")
7593 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7594 (match_operand 3 "tld_symbolic_operand" "")]
7596 (match_operand:DI 1 "register_operand" "r")))))]
7597 "TARGET_TLS && TARGET_ARCH64"
7598 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7599 [(set_attr "type" "load")])
7601 (define_insn "*tldo_ldsw1_sp64"
7602 [(set (match_operand:DI 0 "register_operand" "=r")
7603 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7604 (match_operand 3 "tld_symbolic_operand" "")]
7606 (match_operand:DI 1 "register_operand" "r")))))]
7607 "TARGET_TLS && TARGET_ARCH64"
7608 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7609 [(set_attr "type" "sload")
7610 (set_attr "us3load_type" "3cycle")])
7612 (define_insn "*tldo_ldx_sp64"
7613 [(set (match_operand:DI 0 "register_operand" "=r")
7614 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7615 (match_operand 3 "tld_symbolic_operand" "")]
7617 (match_operand:DI 1 "register_operand" "r"))))]
7618 "TARGET_TLS && TARGET_ARCH64"
7619 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7620 [(set_attr "type" "load")])
7622 (define_insn "*tldo_stb_sp32"
7623 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7624 (match_operand 3 "tld_symbolic_operand" "")]
7626 (match_operand:SI 1 "register_operand" "r")))
7627 (match_operand:QI 0 "register_operand" "=r"))]
7628 "TARGET_TLS && TARGET_ARCH32"
7629 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7630 [(set_attr "type" "store")])
7632 (define_insn "*tldo_stb_sp64"
7633 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7634 (match_operand 3 "tld_symbolic_operand" "")]
7636 (match_operand:DI 1 "register_operand" "r")))
7637 (match_operand:QI 0 "register_operand" "=r"))]
7638 "TARGET_TLS && TARGET_ARCH64"
7639 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7640 [(set_attr "type" "store")])
7642 (define_insn "*tldo_sth_sp32"
7643 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644 (match_operand 3 "tld_symbolic_operand" "")]
7646 (match_operand:SI 1 "register_operand" "r")))
7647 (match_operand:HI 0 "register_operand" "=r"))]
7648 "TARGET_TLS && TARGET_ARCH32"
7649 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7650 [(set_attr "type" "store")])
7652 (define_insn "*tldo_sth_sp64"
7653 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7654 (match_operand 3 "tld_symbolic_operand" "")]
7656 (match_operand:DI 1 "register_operand" "r")))
7657 (match_operand:HI 0 "register_operand" "=r"))]
7658 "TARGET_TLS && TARGET_ARCH64"
7659 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7660 [(set_attr "type" "store")])
7662 (define_insn "*tldo_stw_sp32"
7663 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7664 (match_operand 3 "tld_symbolic_operand" "")]
7666 (match_operand:SI 1 "register_operand" "r")))
7667 (match_operand:SI 0 "register_operand" "=r"))]
7668 "TARGET_TLS && TARGET_ARCH32"
7669 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7670 [(set_attr "type" "store")])
7672 (define_insn "*tldo_stw_sp64"
7673 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7674 (match_operand 3 "tld_symbolic_operand" "")]
7676 (match_operand:DI 1 "register_operand" "r")))
7677 (match_operand:SI 0 "register_operand" "=r"))]
7678 "TARGET_TLS && TARGET_ARCH64"
7679 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7680 [(set_attr "type" "store")])
7682 (define_insn "*tldo_stx_sp64"
7683 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7684 (match_operand 3 "tld_symbolic_operand" "")]
7686 (match_operand:DI 1 "register_operand" "r")))
7687 (match_operand:DI 0 "register_operand" "=r"))]
7688 "TARGET_TLS && TARGET_ARCH64"
7689 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7690 [(set_attr "type" "store")])
7693 ;; Stack protector instructions.
7695 (define_expand "stack_protect_set"
7696 [(match_operand 0 "memory_operand" "")
7697 (match_operand 1 "memory_operand" "")]
7700 #ifdef TARGET_THREAD_SSP_OFFSET
7701 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7702 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7703 operands[1] = gen_rtx_MEM (Pmode, addr);
7706 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7708 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7712 (define_insn "stack_protect_setsi"
7713 [(set (match_operand:SI 0 "memory_operand" "=m")
7714 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7715 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7717 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7718 [(set_attr "type" "multi")
7719 (set_attr "length" "3")])
7721 (define_insn "stack_protect_setdi"
7722 [(set (match_operand:DI 0 "memory_operand" "=m")
7723 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7724 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7726 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7727 [(set_attr "type" "multi")
7728 (set_attr "length" "3")])
7730 (define_expand "stack_protect_test"
7731 [(match_operand 0 "memory_operand" "")
7732 (match_operand 1 "memory_operand" "")
7733 (match_operand 2 "" "")]
7737 #ifdef TARGET_THREAD_SSP_OFFSET
7738 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7739 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7740 operands[1] = gen_rtx_MEM (Pmode, addr);
7744 result = gen_reg_rtx (Pmode);
7745 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7746 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7747 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7751 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7752 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7753 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7754 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7759 (define_insn "stack_protect_testsi"
7760 [(set (reg:CC CC_REG)
7761 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7762 (match_operand:SI 1 "memory_operand" "m")]
7764 (set (match_scratch:SI 3 "=r") (const_int 0))
7765 (clobber (match_scratch:SI 2 "=&r"))]
7767 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7768 [(set_attr "type" "multi")
7769 (set_attr "length" "4")])
7771 (define_insn "stack_protect_testdi"
7772 [(set (match_operand:DI 0 "register_operand" "=&r")
7773 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7774 (match_operand:DI 2 "memory_operand" "m")]
7776 (set (match_scratch:DI 3 "=r") (const_int 0))]
7778 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7779 [(set_attr "type" "multi")
7780 (set_attr "length" "4")])
7783 ;; Vector instructions.
7785 (define_insn "addv2si3"
7786 [(set (match_operand:V2SI 0 "register_operand" "=e")
7787 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7788 (match_operand:V2SI 2 "register_operand" "e")))]
7790 "fpadd32\t%1, %2, %0"
7791 [(set_attr "type" "fga")
7792 (set_attr "fptype" "double")])
7794 (define_insn "addv4hi3"
7795 [(set (match_operand:V4HI 0 "register_operand" "=e")
7796 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7797 (match_operand:V4HI 2 "register_operand" "e")))]
7799 "fpadd16\t%1, %2, %0"
7800 [(set_attr "type" "fga")
7801 (set_attr "fptype" "double")])
7803 ;; fpadd32s is emitted by the addsi3 pattern.
7805 (define_insn "addv2hi3"
7806 [(set (match_operand:V2HI 0 "register_operand" "=f")
7807 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7808 (match_operand:V2HI 2 "register_operand" "f")))]
7810 "fpadd16s\t%1, %2, %0"
7811 [(set_attr "type" "fga")
7812 (set_attr "fptype" "single")])
7814 (define_insn "subv2si3"
7815 [(set (match_operand:V2SI 0 "register_operand" "=e")
7816 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7817 (match_operand:V2SI 2 "register_operand" "e")))]
7819 "fpsub32\t%1, %2, %0"
7820 [(set_attr "type" "fga")
7821 (set_attr "fptype" "double")])
7823 (define_insn "subv4hi3"
7824 [(set (match_operand:V4HI 0 "register_operand" "=e")
7825 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7826 (match_operand:V4HI 2 "register_operand" "e")))]
7828 "fpsub16\t%1, %2, %0"
7829 [(set_attr "type" "fga")
7830 (set_attr "fptype" "double")])
7832 ;; fpsub32s is emitted by the subsi3 pattern.
7834 (define_insn "subv2hi3"
7835 [(set (match_operand:V2HI 0 "register_operand" "=f")
7836 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7837 (match_operand:V2HI 2 "register_operand" "f")))]
7839 "fpsub16s\t%1, %2, %0"
7840 [(set_attr "type" "fga")
7841 (set_attr "fptype" "single")])
7843 ;; All other logical instructions have integer equivalents so they
7844 ;; are defined together.
7846 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7848 (define_insn "*nand<V64:mode>_vis"
7849 [(set (match_operand:V64 0 "register_operand" "=e")
7850 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7851 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7854 [(set_attr "type" "fga")
7855 (set_attr "fptype" "double")])
7857 (define_insn "*nand<V32:mode>_vis"
7858 [(set (match_operand:V32 0 "register_operand" "=f")
7859 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7860 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7862 "fnands\t%1, %2, %0"
7863 [(set_attr "type" "fga")
7864 (set_attr "fptype" "single")])
7866 ;; Hard to generate VIS instructions. We have builtins for these.
7868 (define_insn "fpack16_vis"
7869 [(set (match_operand:V4QI 0 "register_operand" "=f")
7870 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7872 (use (reg:DI GSR_REG))]
7875 [(set_attr "type" "fga")
7876 (set_attr "fptype" "double")])
7878 (define_insn "fpackfix_vis"
7879 [(set (match_operand:V2HI 0 "register_operand" "=f")
7880 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7882 (use (reg:DI GSR_REG))]
7885 [(set_attr "type" "fga")
7886 (set_attr "fptype" "double")])
7888 (define_insn "fpack32_vis"
7889 [(set (match_operand:V8QI 0 "register_operand" "=e")
7890 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7891 (match_operand:V8QI 2 "register_operand" "e")]
7893 (use (reg:DI GSR_REG))]
7895 "fpack32\t%1, %2, %0"
7896 [(set_attr "type" "fga")
7897 (set_attr "fptype" "double")])
7899 (define_insn "fexpand_vis"
7900 [(set (match_operand:V4HI 0 "register_operand" "=e")
7901 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7905 [(set_attr "type" "fga")
7906 (set_attr "fptype" "double")])
7908 ;; It may be possible to describe this operation as (1 indexed):
7909 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7910 ;; 1,5,10,14,19,23,28,32)
7911 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7912 ;; because vec_merge expects all the operands to be of the same type.
7913 (define_insn "fpmerge_vis"
7914 [(set (match_operand:V8QI 0 "register_operand" "=e")
7915 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7916 (match_operand:V4QI 2 "register_operand" "f")]
7919 "fpmerge\t%1, %2, %0"
7920 [(set_attr "type" "fga")
7921 (set_attr "fptype" "double")])
7923 ;; Partitioned multiply instructions
7924 (define_insn "fmul8x16_vis"
7925 [(set (match_operand:V4HI 0 "register_operand" "=e")
7926 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7927 (match_operand:V4HI 2 "register_operand" "e")))]
7929 "fmul8x16\t%1, %2, %0"
7930 [(set_attr "type" "fpmul")
7931 (set_attr "fptype" "double")])
7933 ;; Only one of the following two insns can be a multiply.
7934 (define_insn "fmul8x16au_vis"
7935 [(set (match_operand:V4HI 0 "register_operand" "=e")
7936 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7937 (match_operand:V2HI 2 "register_operand" "f")))]
7939 "fmul8x16au\t%1, %2, %0"
7940 [(set_attr "type" "fpmul")
7941 (set_attr "fptype" "double")])
7943 (define_insn "fmul8x16al_vis"
7944 [(set (match_operand:V4HI 0 "register_operand" "=e")
7945 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7946 (match_operand:V2HI 2 "register_operand" "f")]
7949 "fmul8x16al\t%1, %2, %0"
7950 [(set_attr "type" "fpmul")
7951 (set_attr "fptype" "double")])
7953 ;; Only one of the following two insns can be a multiply.
7954 (define_insn "fmul8sux16_vis"
7955 [(set (match_operand:V4HI 0 "register_operand" "=e")
7956 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7957 (match_operand:V4HI 2 "register_operand" "e")))]
7959 "fmul8sux16\t%1, %2, %0"
7960 [(set_attr "type" "fpmul")
7961 (set_attr "fptype" "double")])
7963 (define_insn "fmul8ulx16_vis"
7964 [(set (match_operand:V4HI 0 "register_operand" "=e")
7965 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7966 (match_operand:V4HI 2 "register_operand" "e")]
7969 "fmul8ulx16\t%1, %2, %0"
7970 [(set_attr "type" "fpmul")
7971 (set_attr "fptype" "double")])
7973 ;; Only one of the following two insns can be a multiply.
7974 (define_insn "fmuld8sux16_vis"
7975 [(set (match_operand:V2SI 0 "register_operand" "=e")
7976 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7977 (match_operand:V2HI 2 "register_operand" "f")))]
7979 "fmuld8sux16\t%1, %2, %0"
7980 [(set_attr "type" "fpmul")
7981 (set_attr "fptype" "double")])
7983 (define_insn "fmuld8ulx16_vis"
7984 [(set (match_operand:V2SI 0 "register_operand" "=e")
7985 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7986 (match_operand:V2HI 2 "register_operand" "f")]
7989 "fmuld8ulx16\t%1, %2, %0"
7990 [(set_attr "type" "fpmul")
7991 (set_attr "fptype" "double")])
7993 (define_expand "wrgsr_vis"
7994 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7997 if (! TARGET_ARCH64)
7999 emit_insn (gen_wrgsr_v8plus (operands[0]));
8004 (define_insn "*wrgsr_sp64"
8005 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8006 "TARGET_VIS && TARGET_ARCH64"
8007 "wr\t%%g0, %0, %%gsr"
8008 [(set_attr "type" "gsr")])
8010 (define_insn "wrgsr_v8plus"
8011 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8012 (clobber (match_scratch:SI 1 "=X,&h"))]
8013 "TARGET_VIS && ! TARGET_ARCH64"
8015 if (GET_CODE (operands[0]) == CONST_INT
8016 || sparc_check_64 (operands[0], insn))
8017 return "wr\t%%g0, %0, %%gsr";
8019 output_asm_insn("srl\t%L0, 0, %L0", operands);
8020 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8022 [(set_attr "type" "multi")])
8024 (define_expand "rdgsr_vis"
8025 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8028 if (! TARGET_ARCH64)
8030 emit_insn (gen_rdgsr_v8plus (operands[0]));
8035 (define_insn "*rdgsr_sp64"
8036 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8037 "TARGET_VIS && TARGET_ARCH64"
8039 [(set_attr "type" "gsr")])
8041 (define_insn "rdgsr_v8plus"
8042 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8043 (clobber (match_scratch:SI 1 "=&h"))]
8044 "TARGET_VIS && ! TARGET_ARCH64"
8046 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8048 [(set_attr "type" "multi")])
8050 ;; Using faligndata only makes sense after an alignaddr since the choice of
8051 ;; bytes to take out of each operand is dependent on the results of the last
8053 (define_insn "faligndata<V64I:mode>_vis"
8054 [(set (match_operand:V64I 0 "register_operand" "=e")
8055 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8056 (match_operand:V64I 2 "register_operand" "e")]
8058 (use (reg:SI GSR_REG))]
8060 "faligndata\t%1, %2, %0"
8061 [(set_attr "type" "fga")
8062 (set_attr "fptype" "double")])
8064 (define_insn "alignaddrsi_vis"
8065 [(set (match_operand:SI 0 "register_operand" "=r")
8066 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8067 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8068 (set (reg:SI GSR_REG)
8069 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8070 (and:SI (plus:SI (match_dup 1) (match_dup 2))
8073 "alignaddr\t%r1, %r2, %0")
8075 (define_insn "alignaddrdi_vis"
8076 [(set (match_operand:DI 0 "register_operand" "=r")
8077 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8078 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8079 (set (reg:SI GSR_REG)
8080 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8081 (and:SI (truncate:SI (plus:DI (match_dup 1) (match_dup 2)))
8084 "alignaddr\t%r1, %r2, %0")
8086 (define_insn "alignaddrlsi_vis"
8087 [(set (match_operand:SI 0 "register_operand" "=r")
8088 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8089 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8090 (set (reg:SI GSR_REG)
8091 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8092 (xor:SI (and:SI (plus:SI (match_dup 1) (match_dup 2))
8096 "alignaddrl\t%r1, %r2, %0")
8098 (define_insn "alignaddrldi_vis"
8099 [(set (match_operand:DI 0 "register_operand" "=r")
8100 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8101 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8102 (set (reg:SI GSR_REG)
8103 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8104 (xor:SI (and:SI (truncate:SI (plus:DI (match_dup 1)
8109 "alignaddrl\t%r1, %r2, %0")
8111 (define_insn "pdist_vis"
8112 [(set (match_operand:DI 0 "register_operand" "=e")
8113 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8114 (match_operand:V8QI 2 "register_operand" "e")
8115 (match_operand:DI 3 "register_operand" "0")]
8119 [(set_attr "type" "fga")
8120 (set_attr "fptype" "double")])
8122 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8123 ;; with the same operands.
8124 (define_insn "edge8<P:mode>_vis"
8125 [(set (reg:CC_NOOV CC_REG)
8126 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8127 (match_operand:P 2 "register_operand" "rJ"))
8129 (set (match_operand:P 0 "register_operand" "=r")
8130 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8132 "edge8\t%r1, %r2, %0"
8133 [(set_attr "type" "edge")])
8135 (define_insn "edge8l<P:mode>_vis"
8136 [(set (reg:CC_NOOV CC_REG)
8137 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8138 (match_operand:P 2 "register_operand" "rJ"))
8140 (set (match_operand:P 0 "register_operand" "=r")
8141 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8143 "edge8l\t%r1, %r2, %0"
8144 [(set_attr "type" "edge")])
8146 (define_insn "edge16<P:mode>_vis"
8147 [(set (reg:CC_NOOV CC_REG)
8148 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8149 (match_operand:P 2 "register_operand" "rJ"))
8151 (set (match_operand:P 0 "register_operand" "=r")
8152 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8154 "edge16\t%r1, %r2, %0"
8155 [(set_attr "type" "edge")])
8157 (define_insn "edge16l<P:mode>_vis"
8158 [(set (reg:CC_NOOV CC_REG)
8159 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8160 (match_operand:P 2 "register_operand" "rJ"))
8162 (set (match_operand:P 0 "register_operand" "=r")
8163 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8165 "edge16l\t%r1, %r2, %0"
8166 [(set_attr "type" "edge")])
8168 (define_insn "edge32<P:mode>_vis"
8169 [(set (reg:CC_NOOV CC_REG)
8170 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8171 (match_operand:P 2 "register_operand" "rJ"))
8173 (set (match_operand:P 0 "register_operand" "=r")
8174 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8176 "edge32\t%r1, %r2, %0"
8177 [(set_attr "type" "edge")])
8179 (define_insn "edge32l<P:mode>_vis"
8180 [(set (reg:CC_NOOV CC_REG)
8181 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8182 (match_operand:P 2 "register_operand" "rJ"))
8184 (set (match_operand:P 0 "register_operand" "=r")
8185 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8187 "edge32l\t%r1, %r2, %0"
8188 [(set_attr "type" "edge")])
8190 (define_code_iterator gcond [le ne gt eq])
8191 (define_mode_iterator GCM [V4HI V2SI])
8192 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8194 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8195 [(set (match_operand:P 0 "register_operand" "=r")
8196 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8197 (match_operand:GCM 2 "register_operand" "e"))]
8200 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8201 [(set_attr "type" "fpmul")
8202 (set_attr "fptype" "double")])
8204 (define_insn "array8<P:mode>_vis"
8205 [(set (match_operand:P 0 "register_operand" "=r")
8206 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8207 (match_operand:P 2 "register_operand" "rJ")]
8210 "array8\t%r1, %r2, %0"
8211 [(set_attr "type" "array")])
8213 (define_insn "array16<P:mode>_vis"
8214 [(set (match_operand:P 0 "register_operand" "=r")
8215 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8216 (match_operand:P 2 "register_operand" "rJ")]
8219 "array16\t%r1, %r2, %0"
8220 [(set_attr "type" "array")])
8222 (define_insn "array32<P:mode>_vis"
8223 [(set (match_operand:P 0 "register_operand" "=r")
8224 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8225 (match_operand:P 2 "register_operand" "rJ")]
8228 "array32\t%r1, %r2, %0"
8229 [(set_attr "type" "array")])
8231 (define_insn "bmask<P:mode>_vis"
8232 [(set (match_operand:P 0 "register_operand" "=r")
8233 (plus:P (match_operand:P 1 "register_operand" "rJ")
8234 (match_operand:P 2 "register_operand" "rJ")))
8235 (clobber (reg:SI GSR_REG))]
8237 "bmask\t%r1, %r2, %0"
8238 [(set_attr "type" "array")])
8240 (define_insn "bshuffle<V64I:mode>_vis"
8241 [(set (match_operand:V64I 0 "register_operand" "=e")
8242 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8243 (match_operand:V64I 2 "register_operand" "e")]
8245 (use (reg:SI GSR_REG))]
8247 "bshuffle\t%1, %2, %0"
8248 [(set_attr "type" "fga")
8249 (set_attr "fptype" "double")])
8251 ;; VIS 2.0 adds edge variants which do not set the condition codes
8252 (define_insn "edge8n<P:mode>_vis"
8253 [(set (match_operand:P 0 "register_operand" "=r")
8254 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8255 (match_operand:P 2 "register_operand" "rJ")]
8258 "edge8n\t%r1, %r2, %0"
8259 [(set_attr "type" "edgen")])
8261 (define_insn "edge8ln<P:mode>_vis"
8262 [(set (match_operand:P 0 "register_operand" "=r")
8263 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8264 (match_operand:P 2 "register_operand" "rJ")]
8267 "edge8ln\t%r1, %r2, %0"
8268 [(set_attr "type" "edgen")])
8270 (define_insn "edge16n<P:mode>_vis"
8271 [(set (match_operand:P 0 "register_operand" "=r")
8272 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8273 (match_operand:P 2 "register_operand" "rJ")]
8276 "edge16n\t%r1, %r2, %0"
8277 [(set_attr "type" "edgen")])
8279 (define_insn "edge16ln<P:mode>_vis"
8280 [(set (match_operand:P 0 "register_operand" "=r")
8281 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8282 (match_operand:P 2 "register_operand" "rJ")]
8285 "edge16ln\t%r1, %r2, %0"
8286 [(set_attr "type" "edgen")])
8288 (define_insn "edge32n<P:mode>_vis"
8289 [(set (match_operand:P 0 "register_operand" "=r")
8290 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8291 (match_operand:P 2 "register_operand" "rJ")]
8294 "edge32n\t%r1, %r2, %0"
8295 [(set_attr "type" "edgen")])
8297 (define_insn "edge32ln<P:mode>_vis"
8298 [(set (match_operand:P 0 "register_operand" "=r")
8299 (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8300 (match_operand:P 2 "register_operand" "rJ")]
8303 "edge32ln\t%r1, %r2, %0"
8304 [(set_attr "type" "edge")])
8306 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8307 (define_insn "cmask8<P:mode>_vis"
8308 [(set (reg:DI GSR_REG)
8309 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8315 (define_insn "cmask16<P:mode>_vis"
8316 [(set (reg:DI GSR_REG)
8317 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8323 (define_insn "cmask32<P:mode>_vis"
8324 [(set (reg:DI GSR_REG)
8325 (unspec:DI [(match_operand:P 0 "register_operand" "r")
8331 (define_insn "fchksm16_vis"
8332 [(set (match_operand:V4HI 0 "register_operand" "=e")
8333 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8334 (match_operand:V4HI 2 "register_operand" "e")]
8337 "fchksm16\t%1, %2, %0")
8339 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8340 (define_code_attr vis3_shift_insn
8341 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8343 (define_insn "<vis3_shift_insn><vbits>_vis"
8344 [(set (match_operand:V64N8 0 "register_operand" "=<vconstr>")
8345 (vis3_shift:V64N8 (match_operand:V64N8 1 "register_operand" "<vconstr>")
8346 (match_operand:V64N8 2 "register_operand" "<vconstr>")))]
8348 "<vis3_shift_insn><vbits>\t%1, %2, %0")
8350 (define_insn "pdistn<mode>_vis"
8351 [(set (match_operand:P 0 "register_operand" "=r")
8352 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8353 (match_operand:V8QI 2 "register_operand" "e")]
8356 "pdistn\t%1, %2, %0")
8358 (define_insn "fmean16_vis"
8359 [(set (match_operand:V4HI 0 "register_operand" "=e")
8365 (match_operand:V4HI 1 "register_operand" "e"))
8367 (match_operand:V4HI 2 "register_operand" "e")))
8368 (const_vector:V4SI [(const_int 1) (const_int 1)
8369 (const_int 1) (const_int 1)]))
8372 "fmean16\t%1, %2, %0")
8374 (define_insn "fpadd64_vis"
8375 [(set (match_operand:DI 0 "register_operand" "=e")
8376 (plus:DI (match_operand:DI 1 "register_operand" "e")
8377 (match_operand:DI 2 "register_operand" "e")))]
8379 "fpadd64\t%1, %2, %0")
8381 (define_insn "fpsub64_vis"
8382 [(set (match_operand:DI 0 "register_operand" "=e")
8383 (minus:DI (match_operand:DI 1 "register_operand" "e")
8384 (match_operand:DI 2 "register_operand" "e")))]
8386 "fpsub64\t%1, %2, %0")
8388 (define_mode_iterator VASS [V4HI V2SI V2HI SI])
8389 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8390 (define_code_attr vis3_addsub_ss_insn
8391 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8393 (define_insn "<vis3_addsub_ss_insn><vbits>_vis"
8394 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8395 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8396 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8398 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8400 (define_insn "fucmp<code>8<P:mode>_vis"
8401 [(set (match_operand:P 0 "register_operand" "=r")
8402 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8403 (match_operand:V8QI 2 "register_operand" "e"))]
8406 "fucmp<code>8\t%1, %2, %0")