1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987-2015 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 (define_c_enum "unspec" [
97 (define_c_enum "unspecv" [
99 UNSPECV_PROBE_STACK_RANGE
204 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
205 (define_mode_iterator I [QI HI SI DI])
206 (define_mode_iterator F [SF DF TF])
208 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
209 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
210 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
211 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
212 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
214 ;; Attribute for cpu type.
215 ;; These must match the values of the enum processor_type in sparc-opts.h.
238 (const (symbol_ref "sparc_cpu_attr")))
240 ;; Attribute for the instruction set.
241 ;; At present we only need to distinguish v9/!v9, but for clarity we
242 ;; test TARGET_V8 too.
243 (define_attr "isa" "v7,v8,v9,sparclet"
245 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
246 (symbol_ref "TARGET_V8") (const_string "v8")
247 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
248 (const_string "v7"))))
250 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
252 (define_attr "enabled" ""
253 (cond [(eq_attr "cpu_feature" "none") (const_int 1)
254 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
255 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
256 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
257 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
258 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
265 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
266 cbcond,uncond_cbcond,
274 fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
277 multi,savew,flushw,iflush,trap"
278 (const_string "ialu"))
280 ;; True if branch/call has empty delay slot and will emit a nop in it
281 (define_attr "empty_delay_slot" "false,true"
282 (symbol_ref "(empty_delay_slot (insn)
283 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
285 ;; True if we are making use of compare-and-branch instructions.
286 ;; True if we should emit a nop after a cbcond instruction
287 (define_attr "emit_cbcond_nop" "false,true"
288 (symbol_ref "(emit_cbcond_nop (insn)
289 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
291 (define_attr "branch_type" "none,icc,fcc,reg"
292 (const_string "none"))
294 (define_attr "pic" "false,true"
295 (symbol_ref "(flag_pic != 0
296 ? PIC_TRUE : PIC_FALSE)"))
298 (define_attr "calls_alloca" "false,true"
299 (symbol_ref "(cfun->calls_alloca != 0
300 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
302 (define_attr "calls_eh_return" "false,true"
303 (symbol_ref "(crtl->calls_eh_return != 0
304 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
306 (define_attr "leaf_function" "false,true"
307 (symbol_ref "(crtl->uses_only_leaf_regs != 0
308 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
310 (define_attr "delayed_branch" "false,true"
311 (symbol_ref "(flag_delayed_branch != 0
312 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
314 (define_attr "flat" "false,true"
315 (symbol_ref "(TARGET_FLAT != 0
316 ? FLAT_TRUE : FLAT_FALSE)"))
318 (define_attr "fix_ut699" "false,true"
319 (symbol_ref "(sparc_fix_ut699 != 0
320 ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
322 ;; Length (in # of insns).
323 ;; Beware that setting a length greater or equal to 3 for conditional branches
324 ;; has a side-effect (see output_cbranch and output_v9branch).
325 (define_attr "length" ""
326 (cond [(eq_attr "type" "uncond_branch,call")
327 (if_then_else (eq_attr "empty_delay_slot" "true")
330 (eq_attr "type" "sibcall")
331 (if_then_else (eq_attr "leaf_function" "true")
332 (if_then_else (eq_attr "empty_delay_slot" "true")
335 (if_then_else (eq_attr "empty_delay_slot" "true")
338 (eq_attr "branch_type" "icc")
339 (if_then_else (match_operand 0 "noov_compare64_operator" "")
340 (if_then_else (lt (pc) (match_dup 1))
341 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
342 (if_then_else (eq_attr "empty_delay_slot" "true")
345 (if_then_else (eq_attr "empty_delay_slot" "true")
348 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
349 (if_then_else (eq_attr "empty_delay_slot" "true")
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" "fcc")
359 (if_then_else (match_operand 0 "fcc0_register_operand" "")
360 (if_then_else (eq_attr "empty_delay_slot" "true")
361 (if_then_else (not (match_test "TARGET_V9"))
364 (if_then_else (not (match_test "TARGET_V9"))
367 (if_then_else (lt (pc) (match_dup 2))
368 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
369 (if_then_else (eq_attr "empty_delay_slot" "true")
372 (if_then_else (eq_attr "empty_delay_slot" "true")
375 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
376 (if_then_else (eq_attr "empty_delay_slot" "true")
379 (if_then_else (eq_attr "empty_delay_slot" "true")
382 (eq_attr "branch_type" "reg")
383 (if_then_else (lt (pc) (match_dup 2))
384 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
385 (if_then_else (eq_attr "empty_delay_slot" "true")
388 (if_then_else (eq_attr "empty_delay_slot" "true")
391 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
392 (if_then_else (eq_attr "empty_delay_slot" "true")
395 (if_then_else (eq_attr "empty_delay_slot" "true")
398 (eq_attr "type" "cbcond")
399 (if_then_else (lt (pc) (match_dup 3))
400 (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
401 (if_then_else (eq_attr "emit_cbcond_nop" "true")
405 (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
406 (if_then_else (eq_attr "emit_cbcond_nop" "true")
410 (eq_attr "type" "uncond_cbcond")
411 (if_then_else (lt (pc) (match_dup 0))
412 (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
413 (if_then_else (eq_attr "emit_cbcond_nop" "true")
417 (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
418 (if_then_else (eq_attr "emit_cbcond_nop" "true")
425 (define_attr "fptype" "single,double"
426 (const_string "single"))
428 ;; FP precision specific to the UT699.
429 (define_attr "fptype_ut699" "none,single"
430 (const_string "none"))
432 ;; UltraSPARC-III integer load type.
433 (define_attr "us3load_type" "2cycle,3cycle"
434 (const_string "2cycle"))
436 (define_asm_attributes
437 [(set_attr "length" "2")
438 (set_attr "type" "multi")])
440 ;; Attributes for branch scheduling
441 (define_attr "in_call_delay" "false,true"
442 (symbol_ref "(eligible_for_call_delay (insn)
443 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
445 (define_attr "in_sibcall_delay" "false,true"
446 (symbol_ref "(eligible_for_sibcall_delay (insn)
447 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
449 (define_attr "in_return_delay" "false,true"
450 (symbol_ref "(eligible_for_return_delay (insn)
451 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
453 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
454 ;; branches. This would allow us to remove the nop always inserted before
455 ;; a floating point branch.
457 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
458 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
459 ;; This is because doing so will add several pipeline stalls to the path
460 ;; that the load/store did not come from. Unfortunately, there is no way
461 ;; to prevent fill_eager_delay_slots from using load/store without completely
462 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
463 ;; because it prevents us from moving back the final store of inner loops.
465 (define_attr "in_branch_delay" "false,true"
466 (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
467 (const_string "false")
468 (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
469 (const_string "false")
470 (and (eq_attr "fix_ut699" "true")
471 (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
472 (ior (eq_attr "fptype" "single")
473 (eq_attr "fptype_ut699" "single"))))
474 (const_string "false")
475 (eq_attr "length" "1")
476 (const_string "true")
477 ] (const_string "false")))
479 (define_delay (eq_attr "type" "call")
480 [(eq_attr "in_call_delay" "true") (nil) (nil)])
482 (define_delay (eq_attr "type" "sibcall")
483 [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
485 (define_delay (eq_attr "type" "return")
486 [(eq_attr "in_return_delay" "true") (nil) (nil)])
488 (define_delay (eq_attr "type" "branch")
489 [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
491 (define_delay (eq_attr "type" "uncond_branch")
492 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
495 ;; Include SPARC DFA schedulers
497 (include "cypress.md")
498 (include "supersparc.md")
499 (include "hypersparc.md")
501 (include "sparclet.md")
502 (include "ultra1_2.md")
503 (include "ultra3.md")
504 (include "niagara.md")
505 (include "niagara2.md")
506 (include "niagara4.md")
509 ;; Operand and operator predicates and constraints
511 (include "predicates.md")
512 (include "constraints.md")
515 ;; Compare instructions.
517 ;; These are just the DEFINE_INSNs to match the patterns and the
518 ;; DEFINE_SPLITs for some of the scc insns that actually require
519 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
521 ;; The compare DEFINE_INSNs.
523 (define_insn "*cmpsi_insn"
524 [(set (reg:CC CC_REG)
525 (compare:CC (match_operand:SI 0 "register_operand" "r")
526 (match_operand:SI 1 "arith_operand" "rI")))]
529 [(set_attr "type" "compare")])
531 (define_insn "*cmpdi_sp64"
532 [(set (reg:CCX CC_REG)
533 (compare:CCX (match_operand:DI 0 "register_operand" "r")
534 (match_operand:DI 1 "arith_operand" "rI")))]
537 [(set_attr "type" "compare")])
539 (define_insn "*cmpsf_fpe"
540 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
541 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
542 (match_operand:SF 2 "register_operand" "f")))]
546 return "fcmpes\t%0, %1, %2";
547 return "fcmpes\t%1, %2";
549 [(set_attr "type" "fpcmp")])
551 (define_insn "*cmpdf_fpe"
552 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
553 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
554 (match_operand:DF 2 "register_operand" "e")))]
558 return "fcmped\t%0, %1, %2";
559 return "fcmped\t%1, %2";
561 [(set_attr "type" "fpcmp")
562 (set_attr "fptype" "double")])
564 (define_insn "*cmptf_fpe"
565 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
566 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
567 (match_operand:TF 2 "register_operand" "e")))]
568 "TARGET_FPU && TARGET_HARD_QUAD"
571 return "fcmpeq\t%0, %1, %2";
572 return "fcmpeq\t%1, %2";
574 [(set_attr "type" "fpcmp")])
576 (define_insn "*cmpsf_fp"
577 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
578 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
579 (match_operand:SF 2 "register_operand" "f")))]
583 return "fcmps\t%0, %1, %2";
584 return "fcmps\t%1, %2";
586 [(set_attr "type" "fpcmp")])
588 (define_insn "*cmpdf_fp"
589 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
590 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
591 (match_operand:DF 2 "register_operand" "e")))]
595 return "fcmpd\t%0, %1, %2";
596 return "fcmpd\t%1, %2";
598 [(set_attr "type" "fpcmp")
599 (set_attr "fptype" "double")])
601 (define_insn "*cmptf_fp"
602 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
603 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
604 (match_operand:TF 2 "register_operand" "e")))]
605 "TARGET_FPU && TARGET_HARD_QUAD"
608 return "fcmpq\t%0, %1, %2";
609 return "fcmpq\t%1, %2";
611 [(set_attr "type" "fpcmp")])
613 ;; Next come the scc insns.
615 ;; Note that the boolean result (operand 0) takes on DImode
616 ;; (not SImode) when TARGET_ARCH64.
618 (define_expand "cstoresi4"
619 [(use (match_operator 1 "comparison_operator"
620 [(match_operand:SI 2 "compare_operand" "")
621 (match_operand:SI 3 "arith_operand" "")]))
622 (clobber (match_operand:SI 0 "cstore_result_operand"))]
625 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
626 operands[2] = force_reg (SImode, operands[2]);
627 if (emit_scc_insn (operands)) DONE; else FAIL;
630 (define_expand "cstoredi4"
631 [(use (match_operator 1 "comparison_operator"
632 [(match_operand:DI 2 "compare_operand" "")
633 (match_operand:DI 3 "arith_operand" "")]))
634 (clobber (match_operand:SI 0 "cstore_result_operand"))]
637 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
638 operands[2] = force_reg (DImode, operands[2]);
639 if (emit_scc_insn (operands)) DONE; else FAIL;
642 (define_expand "cstore<F:mode>4"
643 [(use (match_operator 1 "comparison_operator"
644 [(match_operand:F 2 "register_operand" "")
645 (match_operand:F 3 "register_operand" "")]))
646 (clobber (match_operand:SI 0 "cstore_result_operand"))]
648 { if (emit_scc_insn (operands)) DONE; else FAIL; })
652 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
653 ;; generate addcc/subcc instructions.
655 (define_expand "seqsi<P:mode>_special"
657 (xor:SI (match_operand:SI 1 "register_operand" "")
658 (match_operand:SI 2 "register_operand" "")))
659 (parallel [(set (match_operand:P 0 "register_operand" "")
660 (eq:P (match_dup 3) (const_int 0)))
661 (clobber (reg:CC CC_REG))])]
663 { operands[3] = gen_reg_rtx (SImode); })
665 (define_expand "seqdi_special"
667 (xor:DI (match_operand:DI 1 "register_operand" "")
668 (match_operand:DI 2 "register_operand" "")))
669 (set (match_operand:DI 0 "register_operand" "")
670 (eq:DI (match_dup 3) (const_int 0)))]
672 { operands[3] = gen_reg_rtx (DImode); })
674 (define_expand "snesi<P:mode>_special"
676 (xor:SI (match_operand:SI 1 "register_operand" "")
677 (match_operand:SI 2 "register_operand" "")))
678 (parallel [(set (match_operand:P 0 "register_operand" "")
679 (ne:P (match_dup 3) (const_int 0)))
680 (clobber (reg:CC CC_REG))])]
682 { operands[3] = gen_reg_rtx (SImode); })
684 (define_expand "snedi_special"
686 (xor:DI (match_operand:DI 1 "register_operand" "")
687 (match_operand:DI 2 "register_operand" "")))
688 (set (match_operand:DI 0 "register_operand" "")
689 (ne:DI (match_dup 3) (const_int 0)))]
690 "TARGET_ARCH64 && ! TARGET_VIS3"
691 { operands[3] = gen_reg_rtx (DImode); })
693 (define_expand "snedi_special_vis3"
695 (xor:DI (match_operand:DI 1 "register_operand" "")
696 (match_operand:DI 2 "register_operand" "")))
697 (parallel [(set (match_operand:DI 0 "register_operand" "")
698 (ne:DI (match_dup 3) (const_int 0)))
699 (clobber (reg:CCX CC_REG))])]
700 "TARGET_ARCH64 && TARGET_VIS3"
701 { operands[3] = gen_reg_rtx (DImode); })
704 ;; Now the DEFINE_INSNs for the scc cases.
706 ;; The SEQ and SNE patterns are special because they can be done
707 ;; without any branching and do not involve a COMPARE. We want
708 ;; them to always use the splits below so the results can be
711 (define_insn_and_split "*snesi<P:mode>_zero"
712 [(set (match_operand:P 0 "register_operand" "=r")
713 (ne:P (match_operand:SI 1 "register_operand" "r")
715 (clobber (reg:CC CC_REG))]
719 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
721 (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
723 [(set_attr "length" "2")])
725 (define_insn_and_split "*neg_snesisi_zero"
726 [(set (match_operand:SI 0 "register_operand" "=r")
727 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
729 (clobber (reg:CC CC_REG))]
733 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
735 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
737 [(set_attr "length" "2")])
739 (define_insn_and_split "*neg_snesidi_zero"
740 [(set (match_operand:DI 0 "register_operand" "=r")
741 (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
743 (clobber (reg:CC CC_REG))]
747 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
749 (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
752 [(set_attr "length" "2")])
754 (define_insn_and_split "*snedi_zero"
755 [(set (match_operand:DI 0 "register_operand" "=&r")
756 (ne:DI (match_operand:DI 1 "register_operand" "r")
758 "TARGET_ARCH64 && ! TARGET_VIS3"
760 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
761 [(set (match_dup 0) (const_int 0))
762 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
767 [(set_attr "length" "2")])
769 (define_insn_and_split "*snedi_zero_vis3"
770 [(set (match_operand:DI 0 "register_operand" "=r")
771 (ne:DI (match_operand:DI 1 "register_operand" "r")
773 (clobber (reg:CCX CC_REG))]
774 "TARGET_ARCH64 && TARGET_VIS3"
777 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
779 (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
781 [(set_attr "length" "2")])
783 (define_insn_and_split "*neg_snedi_zero"
784 [(set (match_operand:DI 0 "register_operand" "=&r")
785 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
789 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
790 [(set (match_dup 0) (const_int 0))
791 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
796 [(set_attr "length" "2")])
798 (define_insn_and_split "*snedi_zero_trunc"
799 [(set (match_operand:SI 0 "register_operand" "=&r")
800 (ne:SI (match_operand:DI 1 "register_operand" "r")
802 "TARGET_ARCH64 && ! TARGET_VIS3"
804 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
805 [(set (match_dup 0) (const_int 0))
806 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
811 [(set_attr "length" "2")])
813 (define_insn_and_split "*snedi_zero_trunc_vis3"
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (ne:SI (match_operand:DI 1 "register_operand" "r")
817 (clobber (reg:CCX CC_REG))]
818 "TARGET_ARCH64 && TARGET_VIS3"
821 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
823 (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
825 [(set_attr "length" "2")])
827 (define_insn_and_split "*seqsi<P:mode>_zero"
828 [(set (match_operand:P 0 "register_operand" "=r")
829 (eq:P (match_operand:SI 1 "register_operand" "r")
831 (clobber (reg:CC CC_REG))]
835 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
837 (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
839 [(set_attr "length" "2")])
841 (define_insn_and_split "*neg_seqsisi_zero"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
845 (clobber (reg:CC CC_REG))]
849 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
851 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
853 [(set_attr "length" "2")])
855 (define_insn_and_split "*neg_seqsidi_zero"
856 [(set (match_operand:DI 0 "register_operand" "=r")
857 (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
859 (clobber (reg:CC CC_REG))]
863 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
865 (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
868 [(set_attr "length" "2")])
870 (define_insn_and_split "*seqdi_zero"
871 [(set (match_operand:DI 0 "register_operand" "=&r")
872 (eq:DI (match_operand:DI 1 "register_operand" "r")
876 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
877 [(set (match_dup 0) (const_int 0))
878 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
883 [(set_attr "length" "2")])
885 (define_insn_and_split "*neg_seqdi_zero"
886 [(set (match_operand:DI 0 "register_operand" "=&r")
887 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
891 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
892 [(set (match_dup 0) (const_int 0))
893 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
898 [(set_attr "length" "2")])
900 (define_insn_and_split "*seqdi_zero_trunc"
901 [(set (match_operand:SI 0 "register_operand" "=&r")
902 (eq:SI (match_operand:DI 1 "register_operand" "r")
906 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
907 [(set (match_dup 0) (const_int 0))
908 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
913 [(set_attr "length" "2")])
915 ;; We can also do (x + (i == 0)) and related, so put them in.
916 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
919 (define_insn_and_split "*x_plus_i_ne_0"
920 [(set (match_operand:SI 0 "register_operand" "=r")
921 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
923 (match_operand:SI 2 "register_operand" "r")))
924 (clobber (reg:CC CC_REG))]
928 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
930 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
933 [(set_attr "length" "2")])
935 (define_insn_and_split "*x_minus_i_ne_0"
936 [(set (match_operand:SI 0 "register_operand" "=r")
937 (minus:SI (match_operand:SI 2 "register_operand" "r")
938 (ne:SI (match_operand:SI 1 "register_operand" "r")
940 (clobber (reg:CC CC_REG))]
944 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
946 (set (match_dup 0) (minus:SI (match_dup 2)
947 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
949 [(set_attr "length" "2")])
951 (define_insn_and_split "*x_plus_i_eq_0"
952 [(set (match_operand:SI 0 "register_operand" "=r")
953 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
955 (match_operand:SI 2 "register_operand" "r")))
956 (clobber (reg:CC CC_REG))]
960 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
962 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
965 [(set_attr "length" "2")])
967 (define_insn_and_split "*x_minus_i_eq_0"
968 [(set (match_operand:SI 0 "register_operand" "=r")
969 (minus:SI (match_operand:SI 2 "register_operand" "r")
970 (eq:SI (match_operand:SI 1 "register_operand" "r")
972 (clobber (reg:CC CC_REG))]
976 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
978 (set (match_dup 0) (minus:SI (match_dup 2)
979 (geu:SI (reg:CC CC_REG) (const_int 0))))]
981 [(set_attr "length" "2")])
983 ;; We can also do GEU and LTU directly, but these operate after a compare.
984 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
987 (define_insn "*sltu<P:mode>_insn"
988 [(set (match_operand:P 0 "register_operand" "=r")
989 (ltu:P (reg:CC CC_REG) (const_int 0)))]
992 [(set_attr "type" "ialuX")])
994 (define_insn "*sltu_insn_vis3"
995 [(set (match_operand:DI 0 "register_operand" "=r")
996 (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
997 "TARGET_ARCH64 && TARGET_VIS3"
998 "addxc\t%%g0, %%g0, %0"
999 [(set_attr "type" "ialuX")])
1001 (define_insn "*sltu_insn_vis3_trunc"
1002 [(set (match_operand:SI 0 "register_operand" "=r")
1003 (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1004 "TARGET_ARCH64 && TARGET_VIS3"
1005 "addxc\t%%g0, %%g0, %0"
1006 [(set_attr "type" "ialuX")])
1008 (define_insn "*neg_sltusi_insn"
1009 [(set (match_operand:SI 0 "register_operand" "=r")
1010 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1013 [(set_attr "type" "ialuX")])
1015 (define_insn "*neg_sltudi_insn"
1016 [(set (match_operand:DI 0 "register_operand" "=r")
1017 (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1020 [(set_attr "type" "ialuX")])
1022 (define_insn "*neg_sltu_minus_x"
1023 [(set (match_operand:SI 0 "register_operand" "=r")
1024 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1025 (match_operand:SI 1 "arith_operand" "rI")))]
1027 "subx\t%%g0, %1, %0"
1028 [(set_attr "type" "ialuX")])
1030 (define_insn "*neg_sltu_plus_x"
1031 [(set (match_operand:SI 0 "register_operand" "=r")
1032 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1033 (match_operand:SI 1 "arith_operand" "rI"))))]
1035 "subx\t%%g0, %1, %0"
1036 [(set_attr "type" "ialuX")])
1038 (define_insn "*sgeu<P:mode>_insn"
1039 [(set (match_operand:P 0 "register_operand" "=r")
1040 (geu:P (reg:CC CC_REG) (const_int 0)))]
1042 "subx\t%%g0, -1, %0"
1043 [(set_attr "type" "ialuX")])
1045 (define_insn "*neg_sgeusi_insn"
1046 [(set (match_operand:SI 0 "register_operand" "=r")
1047 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1049 "addx\t%%g0, -1, %0"
1050 [(set_attr "type" "ialuX")])
1052 (define_insn "*neg_sgeudi_insn"
1053 [(set (match_operand:DI 0 "register_operand" "=r")
1054 (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1056 "addx\t%%g0, -1, %0"
1057 [(set_attr "type" "ialuX")])
1059 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1060 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1063 (define_insn "*sltu_plus_x"
1064 [(set (match_operand:SI 0 "register_operand" "=r")
1065 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1066 (match_operand:SI 1 "arith_operand" "rI")))]
1068 "addx\t%%g0, %1, %0"
1069 [(set_attr "type" "ialuX")])
1071 (define_insn "*sltu_plus_x_plus_y"
1072 [(set (match_operand:SI 0 "register_operand" "=r")
1073 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1074 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1075 (match_operand:SI 2 "arith_operand" "rI"))))]
1078 [(set_attr "type" "ialuX")])
1080 (define_insn "*x_minus_sltu"
1081 [(set (match_operand:SI 0 "register_operand" "=r")
1082 (minus:SI (match_operand:SI 1 "register_operand" "r")
1083 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1086 [(set_attr "type" "ialuX")])
1088 ;; ??? Combine should canonicalize these next two to the same pattern.
1089 (define_insn "*x_minus_y_minus_sltu"
1090 [(set (match_operand:SI 0 "register_operand" "=r")
1091 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1092 (match_operand:SI 2 "arith_operand" "rI"))
1093 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1096 [(set_attr "type" "ialuX")])
1098 (define_insn "*x_minus_sltu_plus_y"
1099 [(set (match_operand:SI 0 "register_operand" "=r")
1100 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1101 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1102 (match_operand:SI 2 "arith_operand" "rI"))))]
1105 [(set_attr "type" "ialuX")])
1107 (define_insn "*sgeu_plus_x"
1108 [(set (match_operand:SI 0 "register_operand" "=r")
1109 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1110 (match_operand:SI 1 "register_operand" "r")))]
1113 [(set_attr "type" "ialuX")])
1115 (define_insn "*x_minus_sgeu"
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (minus:SI (match_operand:SI 1 "register_operand" "r")
1118 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1121 [(set_attr "type" "ialuX")])
1124 [(set (match_operand:SI 0 "register_operand" "")
1125 (match_operator:SI 2 "noov_compare_operator"
1126 [(match_operand 1 "icc_or_fcc_register_operand" "")
1129 && REGNO (operands[1]) == SPARC_ICC_REG
1130 && (GET_MODE (operands[1]) == CCXmode
1131 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1132 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1133 [(set (match_dup 0) (const_int 0))
1135 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1141 ;; These control RTL generation for conditional jump insns
1143 (define_expand "cbranchcc4"
1145 (if_then_else (match_operator 0 "comparison_operator"
1146 [(match_operand 1 "compare_operand" "")
1147 (match_operand 2 "const_zero_operand" "")])
1148 (label_ref (match_operand 3 "" ""))
1153 (define_expand "cbranchsi4"
1154 [(use (match_operator 0 "comparison_operator"
1155 [(match_operand:SI 1 "compare_operand" "")
1156 (match_operand:SI 2 "arith_operand" "")]))
1157 (use (match_operand 3 ""))]
1160 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1161 operands[1] = force_reg (SImode, operands[1]);
1162 emit_conditional_branch_insn (operands);
1166 (define_expand "cbranchdi4"
1167 [(use (match_operator 0 "comparison_operator"
1168 [(match_operand:DI 1 "compare_operand" "")
1169 (match_operand:DI 2 "arith_operand" "")]))
1170 (use (match_operand 3 ""))]
1173 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1174 operands[1] = force_reg (DImode, operands[1]);
1175 emit_conditional_branch_insn (operands);
1179 (define_expand "cbranch<F:mode>4"
1180 [(use (match_operator 0 "comparison_operator"
1181 [(match_operand:F 1 "register_operand" "")
1182 (match_operand:F 2 "register_operand" "")]))
1183 (use (match_operand 3 ""))]
1185 { emit_conditional_branch_insn (operands); DONE; })
1188 ;; Now match both normal and inverted jump.
1190 ;; XXX fpcmp nop braindamage
1191 (define_insn "*normal_branch"
1193 (if_then_else (match_operator 0 "noov_compare_operator"
1194 [(reg CC_REG) (const_int 0)])
1195 (label_ref (match_operand 1 "" ""))
1199 return output_cbranch (operands[0], operands[1], 1, 0,
1200 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1203 [(set_attr "type" "branch")
1204 (set_attr "branch_type" "icc")])
1206 ;; XXX fpcmp nop braindamage
1207 (define_insn "*inverted_branch"
1209 (if_then_else (match_operator 0 "noov_compare_operator"
1210 [(reg CC_REG) (const_int 0)])
1212 (label_ref (match_operand 1 "" ""))))]
1215 return output_cbranch (operands[0], operands[1], 1, 1,
1216 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1219 [(set_attr "type" "branch")
1220 (set_attr "branch_type" "icc")])
1222 ;; XXX fpcmp nop braindamage
1223 (define_insn "*normal_fp_branch"
1225 (if_then_else (match_operator 1 "comparison_operator"
1226 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1228 (label_ref (match_operand 2 "" ""))
1232 return output_cbranch (operands[1], operands[2], 2, 0,
1233 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1236 [(set_attr "type" "branch")
1237 (set_attr "branch_type" "fcc")])
1239 ;; XXX fpcmp nop braindamage
1240 (define_insn "*inverted_fp_branch"
1242 (if_then_else (match_operator 1 "comparison_operator"
1243 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1246 (label_ref (match_operand 2 "" ""))))]
1249 return output_cbranch (operands[1], operands[2], 2, 1,
1250 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1253 [(set_attr "type" "branch")
1254 (set_attr "branch_type" "fcc")])
1256 ;; XXX fpcmp nop braindamage
1257 (define_insn "*normal_fpe_branch"
1259 (if_then_else (match_operator 1 "comparison_operator"
1260 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1262 (label_ref (match_operand 2 "" ""))
1266 return output_cbranch (operands[1], operands[2], 2, 0,
1267 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1270 [(set_attr "type" "branch")
1271 (set_attr "branch_type" "fcc")])
1273 ;; XXX fpcmp nop braindamage
1274 (define_insn "*inverted_fpe_branch"
1276 (if_then_else (match_operator 1 "comparison_operator"
1277 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1280 (label_ref (match_operand 2 "" ""))))]
1283 return output_cbranch (operands[1], operands[2], 2, 1,
1284 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1287 [(set_attr "type" "branch")
1288 (set_attr "branch_type" "fcc")])
1290 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1291 ;; in the architecture.
1293 (define_insn "*cbcond_sp32"
1295 (if_then_else (match_operator 0 "noov_compare_operator"
1296 [(match_operand:SI 1 "register_operand" "r")
1297 (match_operand:SI 2 "arith5_operand" "rA")])
1298 (label_ref (match_operand 3 "" ""))
1302 return output_cbcond (operands[0], operands[3], insn);
1304 [(set_attr "type" "cbcond")])
1306 (define_insn "*cbcond_sp64"
1308 (if_then_else (match_operator 0 "noov_compare_operator"
1309 [(match_operand:DI 1 "register_operand" "r")
1310 (match_operand:DI 2 "arith5_operand" "rA")])
1311 (label_ref (match_operand 3 "" ""))
1313 "TARGET_ARCH64 && TARGET_CBCOND"
1315 return output_cbcond (operands[0], operands[3], insn);
1317 [(set_attr "type" "cbcond")])
1319 ;; There are no 32 bit brreg insns.
1322 (define_insn "*normal_int_branch_sp64"
1324 (if_then_else (match_operator 0 "v9_register_compare_operator"
1325 [(match_operand:DI 1 "register_operand" "r")
1327 (label_ref (match_operand 2 "" ""))
1331 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1332 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1335 [(set_attr "type" "branch")
1336 (set_attr "branch_type" "reg")])
1339 (define_insn "*inverted_int_branch_sp64"
1341 (if_then_else (match_operator 0 "v9_register_compare_operator"
1342 [(match_operand:DI 1 "register_operand" "r")
1345 (label_ref (match_operand 2 "" ""))))]
1348 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1349 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1352 [(set_attr "type" "branch")
1353 (set_attr "branch_type" "reg")])
1356 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1357 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1358 ;; that adds the PC value at the call point to register #(operand 3).
1360 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1361 ;; because the RDPC instruction is extremely expensive and incurs a complete
1362 ;; instruction pipeline flush.
1364 (define_insn "load_pcrel_sym<P:mode>"
1365 [(set (match_operand:P 0 "register_operand" "=r")
1366 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1367 (match_operand:P 2 "call_address_operand" "")
1368 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1369 (clobber (reg:P O7_REG))]
1370 "REGNO (operands[0]) == INTVAL (operands[3])"
1372 if (flag_delayed_branch)
1373 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1375 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1377 [(set (attr "type") (const_string "multi"))
1378 (set (attr "length")
1379 (if_then_else (eq_attr "delayed_branch" "true")
1384 ;; Integer move instructions
1386 (define_expand "movqi"
1387 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1388 (match_operand:QI 1 "general_operand" ""))]
1391 if (sparc_expand_move (QImode, operands))
1395 (define_insn "*movqi_insn"
1396 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1397 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1398 "(register_operand (operands[0], QImode)
1399 || register_or_zero_operand (operands[1], QImode))"
1404 [(set_attr "type" "*,load,store")
1405 (set_attr "us3load_type" "*,3cycle,*")])
1407 (define_expand "movhi"
1408 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1409 (match_operand:HI 1 "general_operand" ""))]
1412 if (sparc_expand_move (HImode, operands))
1416 (define_insn "*movhi_insn"
1417 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1418 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1419 "(register_operand (operands[0], HImode)
1420 || register_or_zero_operand (operands[1], HImode))"
1423 sethi\t%%hi(%a1), %0
1426 [(set_attr "type" "*,*,load,store")
1427 (set_attr "us3load_type" "*,*,3cycle,*")])
1429 ;; We always work with constants here.
1430 (define_insn "*movhi_lo_sum"
1431 [(set (match_operand:HI 0 "register_operand" "=r")
1432 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1433 (match_operand:HI 2 "small_int_operand" "I")))]
1437 (define_expand "movsi"
1438 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1439 (match_operand:SI 1 "general_operand" ""))]
1442 if (sparc_expand_move (SImode, operands))
1446 (define_insn "*movsi_insn"
1447 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1448 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1449 "register_operand (operands[0], SImode)
1450 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1453 sethi\t%%hi(%a1), %0
1463 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1464 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1466 (define_insn "*movsi_lo_sum"
1467 [(set (match_operand:SI 0 "register_operand" "=r")
1468 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1469 (match_operand:SI 2 "immediate_operand" "in")))]
1471 "or\t%1, %%lo(%a2), %0")
1473 (define_insn "*movsi_high"
1474 [(set (match_operand:SI 0 "register_operand" "=r")
1475 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1477 "sethi\t%%hi(%a1), %0")
1479 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1480 ;; so that CSE won't optimize the address computation away.
1481 (define_insn "movsi_lo_sum_pic"
1482 [(set (match_operand:SI 0 "register_operand" "=r")
1483 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1484 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1487 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1488 return "xor\t%1, %%gdop_lox10(%a2), %0";
1490 return "or\t%1, %%lo(%a2), %0";
1494 (define_insn "movsi_high_pic"
1495 [(set (match_operand:SI 0 "register_operand" "=r")
1496 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1497 "flag_pic && check_pic (1)"
1499 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1500 return "sethi\t%%gdop_hix22(%a1), %0";
1502 return "sethi\t%%hi(%a1), %0";
1506 (define_insn "movsi_pic_gotdata_op"
1507 [(set (match_operand:SI 0 "register_operand" "=r")
1508 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1509 (match_operand:SI 2 "register_operand" "r")
1510 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1511 "flag_pic && check_pic (1)"
1513 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1514 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1516 return "ld\t[%1 + %2], %0";
1519 [(set_attr "type" "load")])
1521 (define_expand "movsi_pic_label_ref"
1522 [(set (match_dup 3) (high:SI
1523 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1524 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1525 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1526 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1527 (set (match_operand:SI 0 "register_operand" "=r")
1528 (minus:SI (match_dup 5) (match_dup 4)))]
1531 crtl->uses_pic_offset_table = 1;
1532 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1533 if (!can_create_pseudo_p ())
1535 operands[3] = operands[0];
1536 operands[4] = operands[0];
1540 operands[3] = gen_reg_rtx (SImode);
1541 operands[4] = gen_reg_rtx (SImode);
1543 operands[5] = pic_offset_table_rtx;
1546 (define_insn "*movsi_high_pic_label_ref"
1547 [(set (match_operand:SI 0 "register_operand" "=r")
1549 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1550 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1552 "sethi\t%%hi(%a2-(%a1-.)), %0")
1554 (define_insn "*movsi_lo_sum_pic_label_ref"
1555 [(set (match_operand:SI 0 "register_operand" "=r")
1556 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1557 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1558 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1560 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1562 ;; Set up the PIC register for VxWorks.
1564 (define_expand "vxworks_load_got"
1566 (high:SI (match_dup 1)))
1568 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1570 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1571 "TARGET_VXWORKS_RTP"
1573 operands[0] = pic_offset_table_rtx;
1574 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1575 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1578 (define_expand "movdi"
1579 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1580 (match_operand:DI 1 "general_operand" ""))]
1583 if (sparc_expand_move (DImode, operands))
1587 ;; Be careful, fmovd does not exist when !v9.
1588 ;; We match MEM moves directly when we have correct even
1589 ;; numbered registers, but fall into splits otherwise.
1590 ;; The constraint ordering here is really important to
1591 ;; avoid insane problems in reload, especially for patterns
1594 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1595 ;; (const_int -5016)))
1599 (define_insn "*movdi_insn_sp32"
1600 [(set (match_operand:DI 0 "nonimmediate_operand"
1601 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1602 (match_operand:DI 1 "input_operand"
1603 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1605 && (register_operand (operands[0], DImode)
1606 || register_or_zero_operand (operands[1], DImode))"
1628 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1629 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1630 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1631 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1633 (define_insn "*movdi_insn_sp64"
1634 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1635 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1637 && (register_operand (operands[0], DImode)
1638 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1641 sethi\t%%hi(%a1), %0
1651 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1652 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1653 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1655 (define_expand "movdi_pic_label_ref"
1656 [(set (match_dup 3) (high:DI
1657 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1658 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1659 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1660 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1661 (set (match_operand:DI 0 "register_operand" "=r")
1662 (minus:DI (match_dup 5) (match_dup 4)))]
1663 "TARGET_ARCH64 && flag_pic"
1665 crtl->uses_pic_offset_table = 1;
1666 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1667 if (!can_create_pseudo_p ())
1669 operands[3] = operands[0];
1670 operands[4] = operands[0];
1674 operands[3] = gen_reg_rtx (DImode);
1675 operands[4] = gen_reg_rtx (DImode);
1677 operands[5] = pic_offset_table_rtx;
1680 (define_insn "*movdi_high_pic_label_ref"
1681 [(set (match_operand:DI 0 "register_operand" "=r")
1683 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1684 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1685 "TARGET_ARCH64 && flag_pic"
1686 "sethi\t%%hi(%a2-(%a1-.)), %0")
1688 (define_insn "*movdi_lo_sum_pic_label_ref"
1689 [(set (match_operand:DI 0 "register_operand" "=r")
1690 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1691 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1692 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1693 "TARGET_ARCH64 && flag_pic"
1694 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1696 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1697 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1699 (define_insn "movdi_lo_sum_pic"
1700 [(set (match_operand:DI 0 "register_operand" "=r")
1701 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1702 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1703 "TARGET_ARCH64 && flag_pic"
1705 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1706 return "xor\t%1, %%gdop_lox10(%a2), %0";
1708 return "or\t%1, %%lo(%a2), %0";
1712 (define_insn "movdi_high_pic"
1713 [(set (match_operand:DI 0 "register_operand" "=r")
1714 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1715 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1717 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1718 return "sethi\t%%gdop_hix22(%a1), %0";
1720 return "sethi\t%%hi(%a1), %0";
1724 (define_insn "movdi_pic_gotdata_op"
1725 [(set (match_operand:DI 0 "register_operand" "=r")
1726 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1727 (match_operand:DI 2 "register_operand" "r")
1728 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1729 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1731 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1732 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1734 return "ldx\t[%1 + %2], %0";
1737 [(set_attr "type" "load")])
1739 (define_insn "*sethi_di_medlow_embmedany_pic"
1740 [(set (match_operand:DI 0 "register_operand" "=r")
1741 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1742 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1743 "sethi\t%%hi(%a1), %0")
1745 (define_insn "*sethi_di_medlow"
1746 [(set (match_operand:DI 0 "register_operand" "=r")
1747 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1748 "TARGET_CM_MEDLOW && check_pic (1)"
1749 "sethi\t%%hi(%a1), %0")
1751 (define_insn "*losum_di_medlow"
1752 [(set (match_operand:DI 0 "register_operand" "=r")
1753 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1754 (match_operand:DI 2 "symbolic_operand" "")))]
1756 "or\t%1, %%lo(%a2), %0")
1758 (define_insn "seth44"
1759 [(set (match_operand:DI 0 "register_operand" "=r")
1760 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1762 "sethi\t%%h44(%a1), %0")
1764 (define_insn "setm44"
1765 [(set (match_operand:DI 0 "register_operand" "=r")
1766 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1767 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1769 "or\t%1, %%m44(%a2), %0")
1771 (define_insn "setl44"
1772 [(set (match_operand:DI 0 "register_operand" "=r")
1773 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1774 (match_operand:DI 2 "symbolic_operand" "")))]
1776 "or\t%1, %%l44(%a2), %0")
1778 (define_insn "sethh"
1779 [(set (match_operand:DI 0 "register_operand" "=r")
1780 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1782 "sethi\t%%hh(%a1), %0")
1784 (define_insn "setlm"
1785 [(set (match_operand:DI 0 "register_operand" "=r")
1786 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1788 "sethi\t%%lm(%a1), %0")
1790 (define_insn "sethm"
1791 [(set (match_operand:DI 0 "register_operand" "=r")
1792 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1793 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1795 "or\t%1, %%hm(%a2), %0")
1797 (define_insn "setlo"
1798 [(set (match_operand:DI 0 "register_operand" "=r")
1799 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1800 (match_operand:DI 2 "symbolic_operand" "")))]
1802 "or\t%1, %%lo(%a2), %0")
1804 (define_insn "embmedany_sethi"
1805 [(set (match_operand:DI 0 "register_operand" "=r")
1806 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1807 "TARGET_CM_EMBMEDANY && check_pic (1)"
1808 "sethi\t%%hi(%a1), %0")
1810 (define_insn "embmedany_losum"
1811 [(set (match_operand:DI 0 "register_operand" "=r")
1812 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1813 (match_operand:DI 2 "data_segment_operand" "")))]
1814 "TARGET_CM_EMBMEDANY"
1815 "add\t%1, %%lo(%a2), %0")
1817 (define_insn "embmedany_brsum"
1818 [(set (match_operand:DI 0 "register_operand" "=r")
1819 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1820 "TARGET_CM_EMBMEDANY"
1823 (define_insn "embmedany_textuhi"
1824 [(set (match_operand:DI 0 "register_operand" "=r")
1825 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1826 "TARGET_CM_EMBMEDANY && check_pic (1)"
1827 "sethi\t%%uhi(%a1), %0")
1829 (define_insn "embmedany_texthi"
1830 [(set (match_operand:DI 0 "register_operand" "=r")
1831 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1832 "TARGET_CM_EMBMEDANY && check_pic (1)"
1833 "sethi\t%%hi(%a1), %0")
1835 (define_insn "embmedany_textulo"
1836 [(set (match_operand:DI 0 "register_operand" "=r")
1837 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1838 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1839 "TARGET_CM_EMBMEDANY"
1840 "or\t%1, %%ulo(%a2), %0")
1842 (define_insn "embmedany_textlo"
1843 [(set (match_operand:DI 0 "register_operand" "=r")
1844 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1845 (match_operand:DI 2 "text_segment_operand" "")))]
1846 "TARGET_CM_EMBMEDANY"
1847 "or\t%1, %%lo(%a2), %0")
1849 ;; Now some patterns to help reload out a bit.
1850 (define_expand "reload_indi"
1851 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1852 (match_operand:DI 1 "immediate_operand" "")
1853 (match_operand:TI 2 "register_operand" "=&r")])]
1855 || TARGET_CM_EMBMEDANY)
1858 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1862 (define_expand "reload_outdi"
1863 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1864 (match_operand:DI 1 "immediate_operand" "")
1865 (match_operand:TI 2 "register_operand" "=&r")])]
1867 || TARGET_CM_EMBMEDANY)
1870 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1874 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1876 [(set (match_operand:DI 0 "register_operand" "")
1877 (match_operand:DI 1 "const_int_operand" ""))]
1879 && ((GET_CODE (operands[0]) == REG
1880 && SPARC_INT_REG_P (REGNO (operands[0])))
1881 || (GET_CODE (operands[0]) == SUBREG
1882 && GET_CODE (SUBREG_REG (operands[0])) == REG
1883 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1884 && reload_completed"
1885 [(clobber (const_int 0))]
1887 #if HOST_BITS_PER_WIDE_INT == 32
1888 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1889 (INTVAL (operands[1]) < 0) ?
1892 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1895 HOST_WIDE_INT low, high;
1897 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1898 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1899 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1901 /* Slick... but this trick loses if this subreg constant part
1902 can be done in one insn. */
1904 && ! SPARC_SETHI32_P (high)
1905 && ! SPARC_SIMM13_P (high))
1906 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1907 gen_highpart (SImode, operands[0])));
1909 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1915 [(set (match_operand:DI 0 "register_operand" "")
1916 (match_operand:DI 1 "const_double_operand" ""))]
1920 && ((GET_CODE (operands[0]) == REG
1921 && SPARC_INT_REG_P (REGNO (operands[0])))
1922 || (GET_CODE (operands[0]) == SUBREG
1923 && GET_CODE (SUBREG_REG (operands[0])) == REG
1924 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1925 [(clobber (const_int 0))]
1927 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1928 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1930 /* Slick... but this trick loses if this subreg constant part
1931 can be done in one insn. */
1932 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1933 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1934 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1936 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1937 gen_highpart (SImode, operands[0])));
1941 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1942 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1948 [(set (match_operand:DI 0 "register_operand" "")
1949 (match_operand:DI 1 "register_operand" ""))]
1953 && sparc_split_regreg_legitimate (operands[0],
1955 [(clobber (const_int 0))]
1957 rtx set_dest = operands[0];
1958 rtx set_src = operands[1];
1962 dest1 = gen_highpart (SImode, set_dest);
1963 dest2 = gen_lowpart (SImode, set_dest);
1964 src1 = gen_highpart (SImode, set_src);
1965 src2 = gen_lowpart (SImode, set_src);
1967 /* Now emit using the real source and destination we found, swapping
1968 the order if we detect overlap. */
1969 if (reg_overlap_mentioned_p (dest1, src2))
1971 emit_insn (gen_movsi (dest2, src2));
1972 emit_insn (gen_movsi (dest1, src1));
1976 emit_insn (gen_movsi (dest1, src1));
1977 emit_insn (gen_movsi (dest2, src2));
1982 ;; Now handle the cases of memory moves from/to non-even
1983 ;; DI mode register pairs.
1985 [(set (match_operand:DI 0 "register_operand" "")
1986 (match_operand:DI 1 "memory_operand" ""))]
1989 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1990 [(clobber (const_int 0))]
1992 rtx word0 = adjust_address (operands[1], SImode, 0);
1993 rtx word1 = adjust_address (operands[1], SImode, 4);
1994 rtx high_part = gen_highpart (SImode, operands[0]);
1995 rtx low_part = gen_lowpart (SImode, operands[0]);
1997 if (reg_overlap_mentioned_p (high_part, word1))
1999 emit_insn (gen_movsi (low_part, word1));
2000 emit_insn (gen_movsi (high_part, word0));
2004 emit_insn (gen_movsi (high_part, word0));
2005 emit_insn (gen_movsi (low_part, word1));
2011 [(set (match_operand:DI 0 "memory_operand" "")
2012 (match_operand:DI 1 "register_operand" ""))]
2015 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2016 [(clobber (const_int 0))]
2018 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2019 gen_highpart (SImode, operands[1])));
2020 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2021 gen_lowpart (SImode, operands[1])));
2026 [(set (match_operand:DI 0 "memory_operand" "")
2027 (match_operand:DI 1 "const_zero_operand" ""))]
2031 && ! mem_min_alignment (operands[0], 8)))
2032 && offsettable_memref_p (operands[0])"
2033 [(clobber (const_int 0))]
2035 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2036 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2040 (define_expand "movti"
2041 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2042 (match_operand:TI 1 "general_operand" ""))]
2045 if (sparc_expand_move (TImode, operands))
2049 ;; We need to prevent reload from splitting TImode moves, because it
2050 ;; might decide to overwrite a pointer with the value it points to.
2051 ;; In that case we have to do the loads in the appropriate order so
2052 ;; that the pointer is not destroyed too early.
2054 (define_insn "*movti_insn_sp64"
2055 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2056 (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))]
2058 && ! TARGET_HARD_QUAD
2059 && (register_operand (operands[0], TImode)
2060 || register_or_zero_operand (operands[1], TImode))"
2062 [(set_attr "length" "2,2,2,2,2")
2063 (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2065 (define_insn "*movti_insn_sp64_hq"
2066 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2067 (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))]
2070 && (register_operand (operands[0], TImode)
2071 || register_or_zero_operand (operands[1], TImode))"
2079 [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2080 (set_attr "length" "2,2,*,*,*,2")])
2082 ;; Now all the splits to handle multi-insn TI mode moves.
2084 [(set (match_operand:TI 0 "register_operand" "")
2085 (match_operand:TI 1 "register_operand" ""))]
2088 && ! TARGET_HARD_QUAD)
2089 || (! fp_register_operand (operands[0], TImode)
2090 && ! fp_register_operand (operands[1], TImode)))"
2091 [(clobber (const_int 0))]
2093 rtx set_dest = operands[0];
2094 rtx set_src = operands[1];
2098 dest1 = gen_highpart (DImode, set_dest);
2099 dest2 = gen_lowpart (DImode, set_dest);
2100 src1 = gen_highpart (DImode, set_src);
2101 src2 = gen_lowpart (DImode, set_src);
2103 /* Now emit using the real source and destination we found, swapping
2104 the order if we detect overlap. */
2105 if (reg_overlap_mentioned_p (dest1, src2))
2107 emit_insn (gen_movdi (dest2, src2));
2108 emit_insn (gen_movdi (dest1, src1));
2112 emit_insn (gen_movdi (dest1, src1));
2113 emit_insn (gen_movdi (dest2, src2));
2119 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120 (match_operand:TI 1 "const_zero_operand" ""))]
2122 [(clobber (const_int 0))]
2124 rtx set_dest = operands[0];
2127 switch (GET_CODE (set_dest))
2130 dest1 = gen_highpart (DImode, set_dest);
2131 dest2 = gen_lowpart (DImode, set_dest);
2134 dest1 = adjust_address (set_dest, DImode, 0);
2135 dest2 = adjust_address (set_dest, DImode, 8);
2141 emit_insn (gen_movdi (dest1, const0_rtx));
2142 emit_insn (gen_movdi (dest2, const0_rtx));
2147 [(set (match_operand:TI 0 "register_operand" "")
2148 (match_operand:TI 1 "memory_operand" ""))]
2150 && offsettable_memref_p (operands[1])
2151 && (! TARGET_HARD_QUAD
2152 || ! fp_register_operand (operands[0], TImode))"
2153 [(clobber (const_int 0))]
2155 rtx word0 = adjust_address (operands[1], DImode, 0);
2156 rtx word1 = adjust_address (operands[1], DImode, 8);
2157 rtx set_dest, dest1, dest2;
2159 set_dest = operands[0];
2161 dest1 = gen_highpart (DImode, set_dest);
2162 dest2 = gen_lowpart (DImode, set_dest);
2164 /* Now output, ordering such that we don't clobber any registers
2165 mentioned in the address. */
2166 if (reg_overlap_mentioned_p (dest1, word1))
2169 emit_insn (gen_movdi (dest2, word1));
2170 emit_insn (gen_movdi (dest1, word0));
2174 emit_insn (gen_movdi (dest1, word0));
2175 emit_insn (gen_movdi (dest2, word1));
2181 [(set (match_operand:TI 0 "memory_operand" "")
2182 (match_operand:TI 1 "register_operand" ""))]
2184 && offsettable_memref_p (operands[0])
2185 && (! TARGET_HARD_QUAD
2186 || ! fp_register_operand (operands[1], TImode))"
2187 [(clobber (const_int 0))]
2189 rtx set_src = operands[1];
2191 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2192 gen_highpart (DImode, set_src)));
2193 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2194 gen_lowpart (DImode, set_src)));
2199 ;; Floating point move instructions
2201 (define_expand "movsf"
2202 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2203 (match_operand:SF 1 "general_operand" ""))]
2206 if (sparc_expand_move (SFmode, operands))
2210 (define_insn "*movsf_insn"
2211 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2212 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2213 "(register_operand (operands[0], SFmode)
2214 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2216 if (GET_CODE (operands[1]) == CONST_DOUBLE
2217 && (which_alternative == 3
2218 || which_alternative == 4
2219 || which_alternative == 5))
2224 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2225 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2226 operands[1] = GEN_INT (i);
2229 switch (which_alternative)
2232 return "fzeros\t%0";
2236 return "fmovs\t%1, %0";
2238 return "mov\t%1, %0";
2240 return "sethi\t%%hi(%a1), %0";
2244 return "movstouw\t%1, %0";
2246 return "movwtos\t%1, %0";
2249 return "ld\t%1, %0";
2252 return "st\t%r1, %0";
2257 [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2258 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2260 ;; The following 3 patterns build SFmode constants in integer registers.
2262 (define_insn "*movsf_lo_sum"
2263 [(set (match_operand:SF 0 "register_operand" "=r")
2264 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2265 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2271 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2272 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2273 operands[2] = GEN_INT (i);
2274 return "or\t%1, %%lo(%a2), %0";
2277 (define_insn "*movsf_high"
2278 [(set (match_operand:SF 0 "register_operand" "=r")
2279 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2285 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2286 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2287 operands[1] = GEN_INT (i);
2288 return "sethi\t%%hi(%1), %0";
2292 [(set (match_operand:SF 0 "register_operand" "")
2293 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2294 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2295 [(set (match_dup 0) (high:SF (match_dup 1)))
2296 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2298 (define_expand "movdf"
2299 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2300 (match_operand:DF 1 "general_operand" ""))]
2303 if (sparc_expand_move (DFmode, operands))
2307 (define_insn "*movdf_insn_sp32"
2308 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2309 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2311 && (register_operand (operands[0], DFmode)
2312 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2329 [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2330 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2331 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2332 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2334 (define_insn "*movdf_insn_sp64"
2335 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2336 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2338 && (register_operand (operands[0], DFmode)
2339 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2352 [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2353 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2354 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2355 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2357 ;; This pattern builds DFmode constants in integer registers.
2359 [(set (match_operand:DF 0 "register_operand" "")
2360 (match_operand:DF 1 "const_double_operand" ""))]
2361 "REG_P (operands[0])
2362 && SPARC_INT_REG_P (REGNO (operands[0]))
2363 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2364 && reload_completed"
2365 [(clobber (const_int 0))]
2367 operands[0] = gen_raw_REG (DImode, REGNO (operands[0]));
2371 #if HOST_BITS_PER_WIDE_INT == 32
2374 machine_mode mode = GET_MODE (operands[1]);
2375 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2376 emit_insn (gen_movdi (operands[0], tem));
2381 machine_mode mode = GET_MODE (operands[1]);
2382 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2383 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2385 gcc_assert (GET_CODE (hi) == CONST_INT);
2386 gcc_assert (GET_CODE (lo) == CONST_INT);
2388 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2390 /* Slick... but this trick loses if this subreg constant part
2391 can be done in one insn. */
2393 && ! SPARC_SETHI32_P (INTVAL (hi))
2394 && ! SPARC_SIMM13_P (INTVAL (hi)))
2396 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2397 gen_highpart (SImode, operands[0])));
2401 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2407 ;; Ok, now the splits to handle all the multi insn and
2408 ;; mis-aligned memory address cases.
2409 ;; In these splits please take note that we must be
2410 ;; careful when V9 but not ARCH64 because the integer
2411 ;; register DFmode cases must be handled.
2413 [(set (match_operand:DF 0 "register_operand" "")
2414 (match_operand:DF 1 "register_operand" ""))]
2417 && sparc_split_regreg_legitimate (operands[0],
2419 && reload_completed"
2420 [(clobber (const_int 0))]
2422 rtx set_dest = operands[0];
2423 rtx set_src = operands[1];
2427 dest1 = gen_highpart (SFmode, set_dest);
2428 dest2 = gen_lowpart (SFmode, set_dest);
2429 src1 = gen_highpart (SFmode, set_src);
2430 src2 = gen_lowpart (SFmode, set_src);
2432 /* Now emit using the real source and destination we found, swapping
2433 the order if we detect overlap. */
2434 if (reg_overlap_mentioned_p (dest1, src2))
2436 emit_move_insn_1 (dest2, src2);
2437 emit_move_insn_1 (dest1, src1);
2441 emit_move_insn_1 (dest1, src1);
2442 emit_move_insn_1 (dest2, src2);
2448 [(set (match_operand:DF 0 "register_operand" "")
2449 (match_operand:DF 1 "memory_operand" ""))]
2452 && (((REGNO (operands[0]) % 2) != 0)
2453 || ! mem_min_alignment (operands[1], 8))
2454 && offsettable_memref_p (operands[1])"
2455 [(clobber (const_int 0))]
2459 word0 = adjust_address (operands[1], SFmode, 0);
2460 word1 = adjust_address (operands[1], SFmode, 4);
2462 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2464 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2465 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2469 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2470 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2476 [(set (match_operand:DF 0 "memory_operand" "")
2477 (match_operand:DF 1 "register_operand" ""))]
2480 && (((REGNO (operands[1]) % 2) != 0)
2481 || ! mem_min_alignment (operands[0], 8))
2482 && offsettable_memref_p (operands[0])"
2483 [(clobber (const_int 0))]
2487 word0 = adjust_address (operands[0], SFmode, 0);
2488 word1 = adjust_address (operands[0], SFmode, 4);
2490 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2491 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2496 [(set (match_operand:DF 0 "memory_operand" "")
2497 (match_operand:DF 1 "const_zero_operand" ""))]
2501 && ! mem_min_alignment (operands[0], 8)))
2502 && offsettable_memref_p (operands[0])"
2503 [(clobber (const_int 0))]
2507 dest1 = adjust_address (operands[0], SFmode, 0);
2508 dest2 = adjust_address (operands[0], SFmode, 4);
2510 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2511 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2516 [(set (match_operand:DF 0 "register_operand" "")
2517 (match_operand:DF 1 "const_zero_operand" ""))]
2520 && ((GET_CODE (operands[0]) == REG
2521 && SPARC_INT_REG_P (REGNO (operands[0])))
2522 || (GET_CODE (operands[0]) == SUBREG
2523 && GET_CODE (SUBREG_REG (operands[0])) == REG
2524 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2525 [(clobber (const_int 0))]
2527 rtx set_dest = operands[0];
2530 dest1 = gen_highpart (SFmode, set_dest);
2531 dest2 = gen_lowpart (SFmode, set_dest);
2532 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2533 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2537 (define_expand "movtf"
2538 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2539 (match_operand:TF 1 "general_operand" ""))]
2542 if (sparc_expand_move (TFmode, operands))
2546 (define_insn "*movtf_insn_sp32"
2547 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r")
2548 (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))]
2550 && (register_operand (operands[0], TFmode)
2551 || register_or_zero_operand (operands[1], TFmode))"
2553 [(set_attr "length" "4,4,4,4,4,4")
2554 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2556 (define_insn "*movtf_insn_sp64"
2557 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2558 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2560 && ! TARGET_HARD_QUAD
2561 && (register_operand (operands[0], TFmode)
2562 || register_or_zero_operand (operands[1], TFmode))"
2564 [(set_attr "length" "2,2,2,2,2")
2565 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2567 (define_insn "*movtf_insn_sp64_hq"
2568 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2569 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2572 && (register_operand (operands[0], TFmode)
2573 || register_or_zero_operand (operands[1], TFmode))"
2581 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2582 (set_attr "length" "2,*,*,*,2,2")])
2584 ;; Now all the splits to handle multi-insn TF mode moves.
2586 [(set (match_operand:TF 0 "register_operand" "")
2587 (match_operand:TF 1 "register_operand" ""))]
2591 && ! TARGET_HARD_QUAD)
2592 || (! fp_register_operand (operands[0], TFmode)
2593 && ! fp_register_operand (operands[1], TFmode)))"
2594 [(clobber (const_int 0))]
2596 rtx set_dest = operands[0];
2597 rtx set_src = operands[1];
2601 dest1 = gen_df_reg (set_dest, 0);
2602 dest2 = gen_df_reg (set_dest, 1);
2603 src1 = gen_df_reg (set_src, 0);
2604 src2 = gen_df_reg (set_src, 1);
2606 /* Now emit using the real source and destination we found, swapping
2607 the order if we detect overlap. */
2608 if (reg_overlap_mentioned_p (dest1, src2))
2610 emit_insn (gen_movdf (dest2, src2));
2611 emit_insn (gen_movdf (dest1, src1));
2615 emit_insn (gen_movdf (dest1, src1));
2616 emit_insn (gen_movdf (dest2, src2));
2622 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2623 (match_operand:TF 1 "const_zero_operand" ""))]
2625 [(clobber (const_int 0))]
2627 rtx set_dest = operands[0];
2630 switch (GET_CODE (set_dest))
2633 dest1 = gen_df_reg (set_dest, 0);
2634 dest2 = gen_df_reg (set_dest, 1);
2637 dest1 = adjust_address (set_dest, DFmode, 0);
2638 dest2 = adjust_address (set_dest, DFmode, 8);
2644 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2645 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2650 [(set (match_operand:TF 0 "register_operand" "")
2651 (match_operand:TF 1 "memory_operand" ""))]
2653 && offsettable_memref_p (operands[1])
2655 || ! TARGET_HARD_QUAD
2656 || ! fp_register_operand (operands[0], TFmode)))"
2657 [(clobber (const_int 0))]
2659 rtx word0 = adjust_address (operands[1], DFmode, 0);
2660 rtx word1 = adjust_address (operands[1], DFmode, 8);
2661 rtx set_dest, dest1, dest2;
2663 set_dest = operands[0];
2665 dest1 = gen_df_reg (set_dest, 0);
2666 dest2 = gen_df_reg (set_dest, 1);
2668 /* Now output, ordering such that we don't clobber any registers
2669 mentioned in the address. */
2670 if (reg_overlap_mentioned_p (dest1, word1))
2673 emit_insn (gen_movdf (dest2, word1));
2674 emit_insn (gen_movdf (dest1, word0));
2678 emit_insn (gen_movdf (dest1, word0));
2679 emit_insn (gen_movdf (dest2, word1));
2685 [(set (match_operand:TF 0 "memory_operand" "")
2686 (match_operand:TF 1 "register_operand" ""))]
2688 && offsettable_memref_p (operands[0])
2690 || ! TARGET_HARD_QUAD
2691 || ! fp_register_operand (operands[1], TFmode)))"
2692 [(clobber (const_int 0))]
2694 rtx set_src = operands[1];
2696 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2697 gen_df_reg (set_src, 0)));
2698 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2699 gen_df_reg (set_src, 1)));
2704 ;; SPARC-V9 conditional move instructions
2706 ;; We can handle larger constants here for some flavors, but for now we keep
2707 ;; it simple and only allow those constants supported by all flavors.
2708 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2709 ;; 3 contains the constant if one is present, but we handle either for
2710 ;; generality (sparc.c puts a constant in operand 2).
2712 ;; Our instruction patterns, on the other hand, canonicalize such that
2713 ;; operand 3 must be the set destination.
2715 (define_expand "mov<I:mode>cc"
2716 [(set (match_operand:I 0 "register_operand" "")
2717 (if_then_else:I (match_operand 1 "comparison_operator" "")
2718 (match_operand:I 2 "arith10_operand" "")
2719 (match_operand:I 3 "arith10_operand" "")))]
2720 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2722 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2727 (define_expand "mov<F:mode>cc"
2728 [(set (match_operand:F 0 "register_operand" "")
2729 (if_then_else:F (match_operand 1 "comparison_operator" "")
2730 (match_operand:F 2 "register_operand" "")
2731 (match_operand:F 3 "register_operand" "")))]
2732 "TARGET_V9 && TARGET_FPU"
2734 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2739 ;; Conditional move define_insns
2741 (define_insn "*mov<I:mode>_cc_v9"
2742 [(set (match_operand:I 0 "register_operand" "=r")
2743 (if_then_else:I (match_operator 1 "comparison_operator"
2744 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2746 (match_operand:I 3 "arith11_operand" "rL")
2747 (match_operand:I 4 "register_operand" "0")))]
2748 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2749 "mov%C1\t%x2, %3, %0"
2750 [(set_attr "type" "cmove")])
2752 (define_insn "*mov<I:mode>_cc_reg_sp64"
2753 [(set (match_operand:I 0 "register_operand" "=r")
2754 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2755 [(match_operand:DI 2 "register_operand" "r")
2757 (match_operand:I 3 "arith10_operand" "rM")
2758 (match_operand:I 4 "register_operand" "0")))]
2760 "movr%D1\t%2, %r3, %0"
2761 [(set_attr "type" "cmove")])
2763 (define_insn "*movsf_cc_v9"
2764 [(set (match_operand:SF 0 "register_operand" "=f")
2765 (if_then_else:SF (match_operator 1 "comparison_operator"
2766 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2768 (match_operand:SF 3 "register_operand" "f")
2769 (match_operand:SF 4 "register_operand" "0")))]
2770 "TARGET_V9 && TARGET_FPU"
2771 "fmovs%C1\t%x2, %3, %0"
2772 [(set_attr "type" "fpcmove")])
2774 (define_insn "*movsf_cc_reg_sp64"
2775 [(set (match_operand:SF 0 "register_operand" "=f")
2776 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2777 [(match_operand:DI 2 "register_operand" "r")
2779 (match_operand:SF 3 "register_operand" "f")
2780 (match_operand:SF 4 "register_operand" "0")))]
2781 "TARGET_ARCH64 && TARGET_FPU"
2782 "fmovrs%D1\t%2, %3, %0"
2783 [(set_attr "type" "fpcrmove")])
2785 ;; Named because invoked by movtf_cc_v9
2786 (define_insn "movdf_cc_v9"
2787 [(set (match_operand:DF 0 "register_operand" "=e")
2788 (if_then_else:DF (match_operator 1 "comparison_operator"
2789 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2791 (match_operand:DF 3 "register_operand" "e")
2792 (match_operand:DF 4 "register_operand" "0")))]
2793 "TARGET_V9 && TARGET_FPU"
2794 "fmovd%C1\t%x2, %3, %0"
2795 [(set_attr "type" "fpcmove")
2796 (set_attr "fptype" "double")])
2798 ;; Named because invoked by movtf_cc_reg_sp64
2799 (define_insn "movdf_cc_reg_sp64"
2800 [(set (match_operand:DF 0 "register_operand" "=e")
2801 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2802 [(match_operand:DI 2 "register_operand" "r")
2804 (match_operand:DF 3 "register_operand" "e")
2805 (match_operand:DF 4 "register_operand" "0")))]
2806 "TARGET_ARCH64 && TARGET_FPU"
2807 "fmovrd%D1\t%2, %3, %0"
2808 [(set_attr "type" "fpcrmove")
2809 (set_attr "fptype" "double")])
2811 (define_insn "*movtf_cc_hq_v9"
2812 [(set (match_operand:TF 0 "register_operand" "=e")
2813 (if_then_else:TF (match_operator 1 "comparison_operator"
2814 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2816 (match_operand:TF 3 "register_operand" "e")
2817 (match_operand:TF 4 "register_operand" "0")))]
2818 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2819 "fmovq%C1\t%x2, %3, %0"
2820 [(set_attr "type" "fpcmove")])
2822 (define_insn "*movtf_cc_reg_hq_sp64"
2823 [(set (match_operand:TF 0 "register_operand" "=e")
2824 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2825 [(match_operand:DI 2 "register_operand" "r")
2827 (match_operand:TF 3 "register_operand" "e")
2828 (match_operand:TF 4 "register_operand" "0")))]
2829 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2830 "fmovrq%D1\t%2, %3, %0"
2831 [(set_attr "type" "fpcrmove")])
2833 (define_insn_and_split "*movtf_cc_v9"
2834 [(set (match_operand:TF 0 "register_operand" "=e")
2835 (if_then_else:TF (match_operator 1 "comparison_operator"
2836 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2838 (match_operand:TF 3 "register_operand" "e")
2839 (match_operand:TF 4 "register_operand" "0")))]
2840 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2842 "&& reload_completed"
2843 [(clobber (const_int 0))]
2845 rtx set_dest = operands[0];
2846 rtx set_srca = operands[3];
2850 dest1 = gen_df_reg (set_dest, 0);
2851 dest2 = gen_df_reg (set_dest, 1);
2852 srca1 = gen_df_reg (set_srca, 0);
2853 srca2 = gen_df_reg (set_srca, 1);
2855 if (reg_overlap_mentioned_p (dest1, srca2))
2857 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2858 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2862 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2863 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2867 [(set_attr "length" "2")])
2869 (define_insn_and_split "*movtf_cc_reg_sp64"
2870 [(set (match_operand:TF 0 "register_operand" "=e")
2871 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2872 [(match_operand:DI 2 "register_operand" "r")
2874 (match_operand:TF 3 "register_operand" "e")
2875 (match_operand:TF 4 "register_operand" "0")))]
2876 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2878 "&& reload_completed"
2879 [(clobber (const_int 0))]
2881 rtx set_dest = operands[0];
2882 rtx set_srca = operands[3];
2886 dest1 = gen_df_reg (set_dest, 0);
2887 dest2 = gen_df_reg (set_dest, 1);
2888 srca1 = gen_df_reg (set_srca, 0);
2889 srca2 = gen_df_reg (set_srca, 1);
2891 if (reg_overlap_mentioned_p (dest1, srca2))
2893 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2894 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2898 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2899 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2903 [(set_attr "length" "2")])
2906 ;; Zero-extension instructions
2908 ;; These patterns originally accepted general_operands, however, slightly
2909 ;; better code is generated by only accepting register_operands, and then
2910 ;; letting combine generate the ldu[hb] insns.
2912 (define_expand "zero_extendhisi2"
2913 [(set (match_operand:SI 0 "register_operand" "")
2914 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2917 rtx temp = gen_reg_rtx (SImode);
2918 rtx shift_16 = GEN_INT (16);
2919 int op1_subbyte = 0;
2921 if (GET_CODE (operand1) == SUBREG)
2923 op1_subbyte = SUBREG_BYTE (operand1);
2924 op1_subbyte /= GET_MODE_SIZE (SImode);
2925 op1_subbyte *= GET_MODE_SIZE (SImode);
2926 operand1 = XEXP (operand1, 0);
2929 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2931 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2935 (define_insn "*zero_extendhisi2_insn"
2936 [(set (match_operand:SI 0 "register_operand" "=r")
2937 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2940 [(set_attr "type" "load")
2941 (set_attr "us3load_type" "3cycle")])
2943 (define_expand "zero_extendqihi2"
2944 [(set (match_operand:HI 0 "register_operand" "")
2945 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2949 (define_insn "*zero_extendqihi2_insn"
2950 [(set (match_operand:HI 0 "register_operand" "=r,r")
2951 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2952 "GET_CODE (operands[1]) != CONST_INT"
2956 [(set_attr "type" "*,load")
2957 (set_attr "us3load_type" "*,3cycle")])
2959 (define_expand "zero_extendqisi2"
2960 [(set (match_operand:SI 0 "register_operand" "")
2961 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2965 (define_insn "*zero_extendqisi2_insn"
2966 [(set (match_operand:SI 0 "register_operand" "=r,r")
2967 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2968 "GET_CODE (operands[1]) != CONST_INT"
2972 [(set_attr "type" "*,load")
2973 (set_attr "us3load_type" "*,3cycle")])
2975 (define_expand "zero_extendqidi2"
2976 [(set (match_operand:DI 0 "register_operand" "")
2977 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2981 (define_insn "*zero_extendqidi2_insn"
2982 [(set (match_operand:DI 0 "register_operand" "=r,r")
2983 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2984 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2988 [(set_attr "type" "*,load")
2989 (set_attr "us3load_type" "*,3cycle")])
2991 (define_expand "zero_extendhidi2"
2992 [(set (match_operand:DI 0 "register_operand" "")
2993 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2996 rtx temp = gen_reg_rtx (DImode);
2997 rtx shift_48 = GEN_INT (48);
2998 int op1_subbyte = 0;
3000 if (GET_CODE (operand1) == SUBREG)
3002 op1_subbyte = SUBREG_BYTE (operand1);
3003 op1_subbyte /= GET_MODE_SIZE (DImode);
3004 op1_subbyte *= GET_MODE_SIZE (DImode);
3005 operand1 = XEXP (operand1, 0);
3008 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3010 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3014 (define_insn "*zero_extendhidi2_insn"
3015 [(set (match_operand:DI 0 "register_operand" "=r")
3016 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3019 [(set_attr "type" "load")
3020 (set_attr "us3load_type" "3cycle")])
3022 ;; ??? Write truncdisi pattern using sra?
3024 (define_expand "zero_extendsidi2"
3025 [(set (match_operand:DI 0 "register_operand" "")
3026 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3030 (define_insn "*zero_extendsidi2_insn_sp64"
3031 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3032 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3034 && GET_CODE (operands[1]) != CONST_INT"
3039 [(set_attr "type" "shift,load,*")
3040 (set_attr "cpu_feature" "*,*,vis3")])
3042 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3043 [(set (match_operand:DI 0 "register_operand" "=r")
3044 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3047 "&& reload_completed"
3048 [(set (match_dup 2) (match_dup 1))
3049 (set (match_dup 3) (const_int 0))]
3050 "operands[2] = gen_lowpart (SImode, operands[0]);
3051 operands[3] = gen_highpart (SImode, operands[0]);"
3052 [(set_attr "length" "2")])
3054 ;; Simplify comparisons of extended values.
3056 (define_insn "*cmp_zero_extendqisi2"
3057 [(set (reg:CC CC_REG)
3058 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3061 "andcc\t%0, 0xff, %%g0"
3062 [(set_attr "type" "compare")])
3064 (define_insn "*cmp_zero_qi"
3065 [(set (reg:CC CC_REG)
3066 (compare:CC (match_operand:QI 0 "register_operand" "r")
3069 "andcc\t%0, 0xff, %%g0"
3070 [(set_attr "type" "compare")])
3072 (define_insn "*cmp_zero_extendqisi2_set"
3073 [(set (reg:CC CC_REG)
3074 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3076 (set (match_operand:SI 0 "register_operand" "=r")
3077 (zero_extend:SI (match_dup 1)))]
3079 "andcc\t%1, 0xff, %0"
3080 [(set_attr "type" "compare")])
3082 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3083 [(set (reg:CC CC_REG)
3084 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3087 (set (match_operand:SI 0 "register_operand" "=r")
3088 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3090 "andcc\t%1, 0xff, %0"
3091 [(set_attr "type" "compare")])
3093 (define_insn "*cmp_zero_extendqidi2"
3094 [(set (reg:CCX CC_REG)
3095 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3098 "andcc\t%0, 0xff, %%g0"
3099 [(set_attr "type" "compare")])
3101 (define_insn "*cmp_zero_qi_sp64"
3102 [(set (reg:CCX CC_REG)
3103 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3106 "andcc\t%0, 0xff, %%g0"
3107 [(set_attr "type" "compare")])
3109 (define_insn "*cmp_zero_extendqidi2_set"
3110 [(set (reg:CCX CC_REG)
3111 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3113 (set (match_operand:DI 0 "register_operand" "=r")
3114 (zero_extend:DI (match_dup 1)))]
3116 "andcc\t%1, 0xff, %0"
3117 [(set_attr "type" "compare")])
3119 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3120 [(set (reg:CCX CC_REG)
3121 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3124 (set (match_operand:DI 0 "register_operand" "=r")
3125 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3127 "andcc\t%1, 0xff, %0"
3128 [(set_attr "type" "compare")])
3130 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3132 (define_insn "*cmp_siqi_trunc"
3133 [(set (reg:CC CC_REG)
3134 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3137 "andcc\t%0, 0xff, %%g0"
3138 [(set_attr "type" "compare")])
3140 (define_insn "*cmp_siqi_trunc_set"
3141 [(set (reg:CC CC_REG)
3142 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3144 (set (match_operand:QI 0 "register_operand" "=r")
3145 (subreg:QI (match_dup 1) 3))]
3147 "andcc\t%1, 0xff, %0"
3148 [(set_attr "type" "compare")])
3150 (define_insn "*cmp_diqi_trunc"
3151 [(set (reg:CC CC_REG)
3152 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3155 "andcc\t%0, 0xff, %%g0"
3156 [(set_attr "type" "compare")])
3158 (define_insn "*cmp_diqi_trunc_set"
3159 [(set (reg:CC CC_REG)
3160 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3162 (set (match_operand:QI 0 "register_operand" "=r")
3163 (subreg:QI (match_dup 1) 7))]
3165 "andcc\t%1, 0xff, %0"
3166 [(set_attr "type" "compare")])
3169 ;; Sign-extension instructions
3171 ;; These patterns originally accepted general_operands, however, slightly
3172 ;; better code is generated by only accepting register_operands, and then
3173 ;; letting combine generate the lds[hb] insns.
3175 (define_expand "extendhisi2"
3176 [(set (match_operand:SI 0 "register_operand" "")
3177 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3180 rtx temp = gen_reg_rtx (SImode);
3181 rtx shift_16 = GEN_INT (16);
3182 int op1_subbyte = 0;
3184 if (GET_CODE (operand1) == SUBREG)
3186 op1_subbyte = SUBREG_BYTE (operand1);
3187 op1_subbyte /= GET_MODE_SIZE (SImode);
3188 op1_subbyte *= GET_MODE_SIZE (SImode);
3189 operand1 = XEXP (operand1, 0);
3192 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3194 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3198 (define_insn "*sign_extendhisi2_insn"
3199 [(set (match_operand:SI 0 "register_operand" "=r")
3200 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3203 [(set_attr "type" "sload")
3204 (set_attr "us3load_type" "3cycle")])
3206 (define_expand "extendqihi2"
3207 [(set (match_operand:HI 0 "register_operand" "")
3208 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3211 rtx temp = gen_reg_rtx (SImode);
3212 rtx shift_24 = GEN_INT (24);
3213 int op1_subbyte = 0;
3214 int op0_subbyte = 0;
3216 if (GET_CODE (operand1) == SUBREG)
3218 op1_subbyte = SUBREG_BYTE (operand1);
3219 op1_subbyte /= GET_MODE_SIZE (SImode);
3220 op1_subbyte *= GET_MODE_SIZE (SImode);
3221 operand1 = XEXP (operand1, 0);
3223 if (GET_CODE (operand0) == SUBREG)
3225 op0_subbyte = SUBREG_BYTE (operand0);
3226 op0_subbyte /= GET_MODE_SIZE (SImode);
3227 op0_subbyte *= GET_MODE_SIZE (SImode);
3228 operand0 = XEXP (operand0, 0);
3230 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3232 if (GET_MODE (operand0) != SImode)
3233 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3234 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3238 (define_insn "*sign_extendqihi2_insn"
3239 [(set (match_operand:HI 0 "register_operand" "=r")
3240 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3243 [(set_attr "type" "sload")
3244 (set_attr "us3load_type" "3cycle")])
3246 (define_expand "extendqisi2"
3247 [(set (match_operand:SI 0 "register_operand" "")
3248 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3251 rtx temp = gen_reg_rtx (SImode);
3252 rtx shift_24 = GEN_INT (24);
3253 int op1_subbyte = 0;
3255 if (GET_CODE (operand1) == SUBREG)
3257 op1_subbyte = SUBREG_BYTE (operand1);
3258 op1_subbyte /= GET_MODE_SIZE (SImode);
3259 op1_subbyte *= GET_MODE_SIZE (SImode);
3260 operand1 = XEXP (operand1, 0);
3263 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3265 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3269 (define_insn "*sign_extendqisi2_insn"
3270 [(set (match_operand:SI 0 "register_operand" "=r")
3271 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3274 [(set_attr "type" "sload")
3275 (set_attr "us3load_type" "3cycle")])
3277 (define_expand "extendqidi2"
3278 [(set (match_operand:DI 0 "register_operand" "")
3279 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3282 rtx temp = gen_reg_rtx (DImode);
3283 rtx shift_56 = GEN_INT (56);
3284 int op1_subbyte = 0;
3286 if (GET_CODE (operand1) == SUBREG)
3288 op1_subbyte = SUBREG_BYTE (operand1);
3289 op1_subbyte /= GET_MODE_SIZE (DImode);
3290 op1_subbyte *= GET_MODE_SIZE (DImode);
3291 operand1 = XEXP (operand1, 0);
3294 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3296 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3300 (define_insn "*sign_extendqidi2_insn"
3301 [(set (match_operand:DI 0 "register_operand" "=r")
3302 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3305 [(set_attr "type" "sload")
3306 (set_attr "us3load_type" "3cycle")])
3308 (define_expand "extendhidi2"
3309 [(set (match_operand:DI 0 "register_operand" "")
3310 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3313 rtx temp = gen_reg_rtx (DImode);
3314 rtx shift_48 = GEN_INT (48);
3315 int op1_subbyte = 0;
3317 if (GET_CODE (operand1) == SUBREG)
3319 op1_subbyte = SUBREG_BYTE (operand1);
3320 op1_subbyte /= GET_MODE_SIZE (DImode);
3321 op1_subbyte *= GET_MODE_SIZE (DImode);
3322 operand1 = XEXP (operand1, 0);
3325 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3327 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3331 (define_insn "*sign_extendhidi2_insn"
3332 [(set (match_operand:DI 0 "register_operand" "=r")
3333 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3336 [(set_attr "type" "sload")
3337 (set_attr "us3load_type" "3cycle")])
3339 (define_expand "extendsidi2"
3340 [(set (match_operand:DI 0 "register_operand" "")
3341 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3345 (define_insn "*sign_extendsidi2_insn"
3346 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3347 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3353 [(set_attr "type" "shift,sload,*")
3354 (set_attr "us3load_type" "*,3cycle,*")
3355 (set_attr "cpu_feature" "*,*,vis3")])
3358 ;; Special pattern for optimizing bit-field compares. This is needed
3359 ;; because combine uses this as a canonical form.
3361 (define_insn "*cmp_zero_extract"
3362 [(set (reg:CC CC_REG)
3364 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3365 (match_operand:SI 1 "small_int_operand" "I")
3366 (match_operand:SI 2 "small_int_operand" "I"))
3368 "INTVAL (operands[2]) > 19"
3370 int len = INTVAL (operands[1]);
3371 int pos = 32 - INTVAL (operands[2]) - len;
3372 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3373 operands[1] = GEN_INT (mask);
3374 return "andcc\t%0, %1, %%g0";
3376 [(set_attr "type" "compare")])
3378 (define_insn "*cmp_zero_extract_sp64"
3379 [(set (reg:CCX CC_REG)
3381 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3382 (match_operand:SI 1 "small_int_operand" "I")
3383 (match_operand:SI 2 "small_int_operand" "I"))
3385 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3387 int len = INTVAL (operands[1]);
3388 int pos = 64 - INTVAL (operands[2]) - len;
3389 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3390 operands[1] = GEN_INT (mask);
3391 return "andcc\t%0, %1, %%g0";
3393 [(set_attr "type" "compare")])
3396 ;; Conversions between float, double and long double.
3398 (define_insn "extendsfdf2"
3399 [(set (match_operand:DF 0 "register_operand" "=e")
3401 (match_operand:SF 1 "register_operand" "f")))]
3404 [(set_attr "type" "fp")
3405 (set_attr "fptype" "double")])
3407 (define_expand "extendsftf2"
3408 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3410 (match_operand:SF 1 "register_operand" "")))]
3411 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3412 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3414 (define_insn "*extendsftf2_hq"
3415 [(set (match_operand:TF 0 "register_operand" "=e")
3417 (match_operand:SF 1 "register_operand" "f")))]
3418 "TARGET_FPU && TARGET_HARD_QUAD"
3420 [(set_attr "type" "fp")])
3422 (define_expand "extenddftf2"
3423 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3425 (match_operand:DF 1 "register_operand" "")))]
3426 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3427 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3429 (define_insn "*extenddftf2_hq"
3430 [(set (match_operand:TF 0 "register_operand" "=e")
3432 (match_operand:DF 1 "register_operand" "e")))]
3433 "TARGET_FPU && TARGET_HARD_QUAD"
3435 [(set_attr "type" "fp")])
3437 (define_insn "truncdfsf2"
3438 [(set (match_operand:SF 0 "register_operand" "=f")
3440 (match_operand:DF 1 "register_operand" "e")))]
3443 [(set_attr "type" "fp")
3444 (set_attr "fptype" "double")
3445 (set_attr "fptype_ut699" "single")])
3447 (define_expand "trunctfsf2"
3448 [(set (match_operand:SF 0 "register_operand" "")
3450 (match_operand:TF 1 "general_operand" "")))]
3451 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3452 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3454 (define_insn "*trunctfsf2_hq"
3455 [(set (match_operand:SF 0 "register_operand" "=f")
3457 (match_operand:TF 1 "register_operand" "e")))]
3458 "TARGET_FPU && TARGET_HARD_QUAD"
3460 [(set_attr "type" "fp")])
3462 (define_expand "trunctfdf2"
3463 [(set (match_operand:DF 0 "register_operand" "")
3465 (match_operand:TF 1 "general_operand" "")))]
3466 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3467 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3469 (define_insn "*trunctfdf2_hq"
3470 [(set (match_operand:DF 0 "register_operand" "=e")
3472 (match_operand:TF 1 "register_operand" "e")))]
3473 "TARGET_FPU && TARGET_HARD_QUAD"
3475 [(set_attr "type" "fp")])
3478 ;; Conversion between fixed point and floating point.
3480 (define_insn "floatsisf2"
3481 [(set (match_operand:SF 0 "register_operand" "=f")
3482 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3485 [(set_attr "type" "fp")
3486 (set_attr "fptype" "single")])
3488 (define_insn "floatsidf2"
3489 [(set (match_operand:DF 0 "register_operand" "=e")
3490 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3493 [(set_attr "type" "fp")
3494 (set_attr "fptype" "double")])
3496 (define_expand "floatsitf2"
3497 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498 (float:TF (match_operand:SI 1 "register_operand" "")))]
3499 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3500 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3502 (define_insn "*floatsitf2_hq"
3503 [(set (match_operand:TF 0 "register_operand" "=e")
3504 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3505 "TARGET_FPU && TARGET_HARD_QUAD"
3507 [(set_attr "type" "fp")])
3509 (define_expand "floatunssitf2"
3510 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3511 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3512 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3513 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3515 ;; Now the same for 64 bit sources.
3517 (define_insn "floatdisf2"
3518 [(set (match_operand:SF 0 "register_operand" "=f")
3519 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3520 "TARGET_V9 && TARGET_FPU"
3522 [(set_attr "type" "fp")
3523 (set_attr "fptype" "double")])
3525 (define_expand "floatunsdisf2"
3526 [(use (match_operand:SF 0 "register_operand" ""))
3527 (use (match_operand:DI 1 "general_operand" ""))]
3528 "TARGET_ARCH64 && TARGET_FPU"
3529 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3531 (define_insn "floatdidf2"
3532 [(set (match_operand:DF 0 "register_operand" "=e")
3533 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3534 "TARGET_V9 && TARGET_FPU"
3536 [(set_attr "type" "fp")
3537 (set_attr "fptype" "double")])
3539 (define_expand "floatunsdidf2"
3540 [(use (match_operand:DF 0 "register_operand" ""))
3541 (use (match_operand:DI 1 "general_operand" ""))]
3542 "TARGET_ARCH64 && TARGET_FPU"
3543 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3545 (define_expand "floatditf2"
3546 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3547 (float:TF (match_operand:DI 1 "register_operand" "")))]
3548 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3549 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3551 (define_insn "*floatditf2_hq"
3552 [(set (match_operand:TF 0 "register_operand" "=e")
3553 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3554 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3556 [(set_attr "type" "fp")])
3558 (define_expand "floatunsditf2"
3559 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3560 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3561 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3562 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3564 ;; Convert a float to an actual integer.
3565 ;; Truncation is performed as part of the conversion.
3567 (define_insn "fix_truncsfsi2"
3568 [(set (match_operand:SI 0 "register_operand" "=f")
3569 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3572 [(set_attr "type" "fp")
3573 (set_attr "fptype" "single")])
3575 (define_insn "fix_truncdfsi2"
3576 [(set (match_operand:SI 0 "register_operand" "=f")
3577 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3580 [(set_attr "type" "fp")
3581 (set_attr "fptype" "double")
3582 (set_attr "fptype_ut699" "single")])
3584 (define_expand "fix_trunctfsi2"
3585 [(set (match_operand:SI 0 "register_operand" "")
3586 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3587 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3588 "emit_tfmode_cvt (FIX, operands); DONE;")
3590 (define_insn "*fix_trunctfsi2_hq"
3591 [(set (match_operand:SI 0 "register_operand" "=f")
3592 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3593 "TARGET_FPU && TARGET_HARD_QUAD"
3595 [(set_attr "type" "fp")])
3597 (define_expand "fixuns_trunctfsi2"
3598 [(set (match_operand:SI 0 "register_operand" "")
3599 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3600 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3601 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3603 ;; Now the same, for V9 targets
3605 (define_insn "fix_truncsfdi2"
3606 [(set (match_operand:DI 0 "register_operand" "=e")
3607 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3608 "TARGET_V9 && TARGET_FPU"
3610 [(set_attr "type" "fp")
3611 (set_attr "fptype" "double")])
3613 (define_expand "fixuns_truncsfdi2"
3614 [(use (match_operand:DI 0 "register_operand" ""))
3615 (use (match_operand:SF 1 "general_operand" ""))]
3616 "TARGET_ARCH64 && TARGET_FPU"
3617 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3619 (define_insn "fix_truncdfdi2"
3620 [(set (match_operand:DI 0 "register_operand" "=e")
3621 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3622 "TARGET_V9 && TARGET_FPU"
3624 [(set_attr "type" "fp")
3625 (set_attr "fptype" "double")])
3627 (define_expand "fixuns_truncdfdi2"
3628 [(use (match_operand:DI 0 "register_operand" ""))
3629 (use (match_operand:DF 1 "general_operand" ""))]
3630 "TARGET_ARCH64 && TARGET_FPU"
3631 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3633 (define_expand "fix_trunctfdi2"
3634 [(set (match_operand:DI 0 "register_operand" "")
3635 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3636 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3637 "emit_tfmode_cvt (FIX, operands); DONE;")
3639 (define_insn "*fix_trunctfdi2_hq"
3640 [(set (match_operand:DI 0 "register_operand" "=e")
3641 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3642 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3644 [(set_attr "type" "fp")])
3646 (define_expand "fixuns_trunctfdi2"
3647 [(set (match_operand:DI 0 "register_operand" "")
3648 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3649 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3650 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3653 ;; Integer addition/subtraction instructions.
3655 (define_expand "adddi3"
3656 [(set (match_operand:DI 0 "register_operand" "")
3657 (plus:DI (match_operand:DI 1 "register_operand" "")
3658 (match_operand:DI 2 "arith_double_add_operand" "")))]
3661 if (! TARGET_ARCH64)
3663 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3664 gen_rtx_SET (operands[0],
3665 gen_rtx_PLUS (DImode, operands[1],
3667 gen_rtx_CLOBBER (VOIDmode,
3668 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3673 (define_insn_and_split "*adddi3_insn_sp32"
3674 [(set (match_operand:DI 0 "register_operand" "=&r")
3675 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3676 (match_operand:DI 2 "arith_double_operand" "rHI")))
3677 (clobber (reg:CC CC_REG))]
3680 "&& reload_completed"
3681 [(parallel [(set (reg:CC_NOOV CC_REG)
3682 (compare:CC_NOOV (plus:SI (match_dup 4)
3686 (plus:SI (match_dup 4) (match_dup 5)))])
3688 (plus:SI (plus:SI (match_dup 7)
3690 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3692 operands[3] = gen_lowpart (SImode, operands[0]);
3693 operands[4] = gen_lowpart (SImode, operands[1]);
3694 operands[5] = gen_lowpart (SImode, operands[2]);
3695 operands[6] = gen_highpart (SImode, operands[0]);
3696 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3697 #if HOST_BITS_PER_WIDE_INT == 32
3698 if (GET_CODE (operands[2]) == CONST_INT)
3700 if (INTVAL (operands[2]) < 0)
3701 operands[8] = constm1_rtx;
3703 operands[8] = const0_rtx;
3707 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3709 [(set_attr "length" "2")])
3711 ;; LTU here means "carry set"
3713 [(set (match_operand:SI 0 "register_operand" "=r")
3714 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3715 (match_operand:SI 2 "arith_operand" "rI"))
3716 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3719 [(set_attr "type" "ialuX")])
3721 (define_insn "addxc"
3722 [(set (match_operand:DI 0 "register_operand" "=r")
3723 (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3724 (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3725 (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3726 "TARGET_ARCH64 && TARGET_VIS3"
3727 "addxc\t%r1, %r2, %0"
3728 [(set_attr "type" "ialuX")])
3730 (define_insn_and_split "*addx_extend_sp32"
3731 [(set (match_operand:DI 0 "register_operand" "=r")
3732 (zero_extend:DI (plus:SI (plus:SI
3733 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3734 (match_operand:SI 2 "arith_operand" "rI"))
3735 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3738 "&& reload_completed"
3739 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3740 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3741 (set (match_dup 4) (const_int 0))]
3742 "operands[3] = gen_lowpart (SImode, operands[0]);
3743 operands[4] = gen_highpart (SImode, operands[0]);"
3744 [(set_attr "length" "2")])
3746 (define_insn "*addx_extend_sp64"
3747 [(set (match_operand:DI 0 "register_operand" "=r")
3748 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3749 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3750 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3752 "addx\t%r1, %r2, %0"
3753 [(set_attr "type" "ialuX")])
3755 (define_insn "*addxc_trunc_sp64_vis3"
3756 [(set (match_operand:SI 0 "register_operand" "=r")
3757 (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3758 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3759 (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3760 "TARGET_ARCH64 && TARGET_VIS3"
3761 "addxc\t%r1, %r2, %0"
3762 [(set_attr "type" "ialuX")])
3764 (define_insn_and_split "*adddi3_extend_sp32"
3765 [(set (match_operand:DI 0 "register_operand" "=&r")
3766 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3767 (match_operand:DI 2 "register_operand" "r")))
3768 (clobber (reg:CC CC_REG))]
3771 "&& reload_completed"
3772 [(parallel [(set (reg:CC_NOOV CC_REG)
3773 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3775 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3777 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3778 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3779 "operands[3] = gen_lowpart (SImode, operands[2]);
3780 operands[4] = gen_highpart (SImode, operands[2]);
3781 operands[5] = gen_lowpart (SImode, operands[0]);
3782 operands[6] = gen_highpart (SImode, operands[0]);"
3783 [(set_attr "length" "2")])
3785 (define_insn "*adddi3_sp64"
3786 [(set (match_operand:DI 0 "register_operand" "=r,r")
3787 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3788 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3794 (define_insn "addsi3"
3795 [(set (match_operand:SI 0 "register_operand" "=r,r")
3796 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3797 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3802 [(set_attr "type" "*,*")
3803 (set_attr "fptype" "*,*")])
3805 (define_insn "*cmp_cc_plus"
3806 [(set (reg:CC_NOOV CC_REG)
3807 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3808 (match_operand:SI 1 "arith_operand" "rI"))
3811 "addcc\t%0, %1, %%g0"
3812 [(set_attr "type" "compare")])
3814 (define_insn "*cmp_ccx_plus"
3815 [(set (reg:CCX_NOOV CC_REG)
3816 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3817 (match_operand:DI 1 "arith_operand" "rI"))
3820 "addcc\t%0, %1, %%g0"
3821 [(set_attr "type" "compare")])
3823 (define_insn "*cmp_cc_plus_set"
3824 [(set (reg:CC_NOOV CC_REG)
3825 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3826 (match_operand:SI 2 "arith_operand" "rI"))
3828 (set (match_operand:SI 0 "register_operand" "=r")
3829 (plus:SI (match_dup 1) (match_dup 2)))]
3832 [(set_attr "type" "compare")])
3834 (define_insn "*cmp_ccx_plus_set"
3835 [(set (reg:CCX_NOOV CC_REG)
3836 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3837 (match_operand:DI 2 "arith_operand" "rI"))
3839 (set (match_operand:DI 0 "register_operand" "=r")
3840 (plus:DI (match_dup 1) (match_dup 2)))]
3843 [(set_attr "type" "compare")])
3845 (define_expand "subdi3"
3846 [(set (match_operand:DI 0 "register_operand" "")
3847 (minus:DI (match_operand:DI 1 "register_operand" "")
3848 (match_operand:DI 2 "arith_double_add_operand" "")))]
3851 if (! TARGET_ARCH64)
3853 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3854 gen_rtx_SET (operands[0],
3855 gen_rtx_MINUS (DImode, operands[1],
3857 gen_rtx_CLOBBER (VOIDmode,
3858 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3863 (define_insn_and_split "*subdi3_insn_sp32"
3864 [(set (match_operand:DI 0 "register_operand" "=&r")
3865 (minus:DI (match_operand:DI 1 "register_operand" "r")
3866 (match_operand:DI 2 "arith_double_operand" "rHI")))
3867 (clobber (reg:CC CC_REG))]
3870 "&& reload_completed"
3871 [(parallel [(set (reg:CC_NOOV CC_REG)
3872 (compare:CC_NOOV (minus:SI (match_dup 4)
3876 (minus:SI (match_dup 4) (match_dup 5)))])
3878 (minus:SI (minus:SI (match_dup 7)
3880 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3882 operands[3] = gen_lowpart (SImode, operands[0]);
3883 operands[4] = gen_lowpart (SImode, operands[1]);
3884 operands[5] = gen_lowpart (SImode, operands[2]);
3885 operands[6] = gen_highpart (SImode, operands[0]);
3886 operands[7] = gen_highpart (SImode, operands[1]);
3887 #if HOST_BITS_PER_WIDE_INT == 32
3888 if (GET_CODE (operands[2]) == CONST_INT)
3890 if (INTVAL (operands[2]) < 0)
3891 operands[8] = constm1_rtx;
3893 operands[8] = const0_rtx;
3897 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3899 [(set_attr "length" "2")])
3901 ;; LTU here means "carry set"
3903 [(set (match_operand:SI 0 "register_operand" "=r")
3904 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3905 (match_operand:SI 2 "arith_operand" "rI"))
3906 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3909 [(set_attr "type" "ialuX")])
3911 (define_insn "*subx_extend_sp64"
3912 [(set (match_operand:DI 0 "register_operand" "=r")
3913 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3914 (match_operand:SI 2 "arith_operand" "rI"))
3915 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3918 [(set_attr "type" "ialuX")])
3920 (define_insn_and_split "*subx_extend_sp32"
3921 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3923 (match_operand:SI 2 "arith_operand" "rI"))
3924 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3927 "&& reload_completed"
3928 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3929 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3930 (set (match_dup 4) (const_int 0))]
3931 "operands[3] = gen_lowpart (SImode, operands[0]);
3932 operands[4] = gen_highpart (SImode, operands[0]);"
3933 [(set_attr "length" "2")])
3935 (define_insn_and_split "*subdi3_extend_sp32"
3936 [(set (match_operand:DI 0 "register_operand" "=&r")
3937 (minus:DI (match_operand:DI 1 "register_operand" "r")
3938 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3939 (clobber (reg:CC CC_REG))]
3942 "&& reload_completed"
3943 [(parallel [(set (reg:CC_NOOV CC_REG)
3944 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3946 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3948 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3949 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3950 "operands[3] = gen_lowpart (SImode, operands[1]);
3951 operands[4] = gen_highpart (SImode, operands[1]);
3952 operands[5] = gen_lowpart (SImode, operands[0]);
3953 operands[6] = gen_highpart (SImode, operands[0]);"
3954 [(set_attr "length" "2")])
3956 (define_insn "*subdi3_sp64"
3957 [(set (match_operand:DI 0 "register_operand" "=r,r")
3958 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3959 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3965 (define_insn "subsi3"
3966 [(set (match_operand:SI 0 "register_operand" "=r,r")
3967 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3968 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3973 [(set_attr "type" "*,*")
3974 (set_attr "fptype" "*,*")])
3976 (define_insn "*cmp_minus_cc"
3977 [(set (reg:CC_NOOV CC_REG)
3978 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3979 (match_operand:SI 1 "arith_operand" "rI"))
3982 "subcc\t%r0, %1, %%g0"
3983 [(set_attr "type" "compare")])
3985 (define_insn "*cmp_minus_ccx"
3986 [(set (reg:CCX_NOOV CC_REG)
3987 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3988 (match_operand:DI 1 "arith_operand" "rI"))
3991 "subcc\t%0, %1, %%g0"
3992 [(set_attr "type" "compare")])
3994 (define_insn "cmp_minus_cc_set"
3995 [(set (reg:CC_NOOV CC_REG)
3996 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3997 (match_operand:SI 2 "arith_operand" "rI"))
3999 (set (match_operand:SI 0 "register_operand" "=r")
4000 (minus:SI (match_dup 1) (match_dup 2)))]
4002 "subcc\t%r1, %2, %0"
4003 [(set_attr "type" "compare")])
4005 (define_insn "*cmp_minus_ccx_set"
4006 [(set (reg:CCX_NOOV CC_REG)
4007 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4008 (match_operand:DI 2 "arith_operand" "rI"))
4010 (set (match_operand:DI 0 "register_operand" "=r")
4011 (minus:DI (match_dup 1) (match_dup 2)))]
4014 [(set_attr "type" "compare")])
4017 ;; Integer multiply/divide instructions.
4019 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4020 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4022 (define_insn "mulsi3"
4023 [(set (match_operand:SI 0 "register_operand" "=r")
4024 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4025 (match_operand:SI 2 "arith_operand" "rI")))]
4028 [(set_attr "type" "imul")])
4030 (define_expand "muldi3"
4031 [(set (match_operand:DI 0 "register_operand" "")
4032 (mult:DI (match_operand:DI 1 "arith_operand" "")
4033 (match_operand:DI 2 "arith_operand" "")))]
4034 "TARGET_ARCH64 || TARGET_V8PLUS"
4038 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4043 (define_insn "*muldi3_sp64"
4044 [(set (match_operand:DI 0 "register_operand" "=r")
4045 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4046 (match_operand:DI 2 "arith_operand" "rI")))]
4049 [(set_attr "type" "imul")])
4051 ;; V8plus wide multiply.
4053 (define_insn "muldi3_v8plus"
4054 [(set (match_operand:DI 0 "register_operand" "=r,h")
4055 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4056 (match_operand:DI 2 "arith_operand" "rI,rI")))
4057 (clobber (match_scratch:SI 3 "=&h,X"))
4058 (clobber (match_scratch:SI 4 "=&h,X"))]
4060 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4061 [(set_attr "type" "multi")
4062 (set_attr "length" "9,8")])
4064 (define_insn "*cmp_mul_set"
4065 [(set (reg:CC CC_REG)
4066 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4067 (match_operand:SI 2 "arith_operand" "rI"))
4069 (set (match_operand:SI 0 "register_operand" "=r")
4070 (mult:SI (match_dup 1) (match_dup 2)))]
4071 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4072 "smulcc\t%1, %2, %0"
4073 [(set_attr "type" "imul")])
4075 (define_expand "mulsidi3"
4076 [(set (match_operand:DI 0 "register_operand" "")
4077 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4078 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4081 if (CONSTANT_P (operands[2]))
4084 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4086 else if (TARGET_ARCH32)
4087 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4090 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4096 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4101 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4102 ;; registers can hold 64-bit values in the V8plus environment.
4104 (define_insn "mulsidi3_v8plus"
4105 [(set (match_operand:DI 0 "register_operand" "=h,r")
4106 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4107 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4108 (clobber (match_scratch:SI 3 "=X,&h"))]
4111 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4112 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4113 [(set_attr "type" "multi")
4114 (set_attr "length" "2,3")])
4117 (define_insn "const_mulsidi3_v8plus"
4118 [(set (match_operand:DI 0 "register_operand" "=h,r")
4119 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4120 (match_operand:DI 2 "small_int_operand" "I,I")))
4121 (clobber (match_scratch:SI 3 "=X,&h"))]
4124 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4125 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4126 [(set_attr "type" "multi")
4127 (set_attr "length" "2,3")])
4130 (define_insn "*mulsidi3_sp32"
4131 [(set (match_operand:DI 0 "register_operand" "=r")
4132 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4133 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4136 return TARGET_SPARCLET
4137 ? "smuld\t%1, %2, %L0"
4138 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4141 (if_then_else (eq_attr "isa" "sparclet")
4142 (const_string "imul") (const_string "multi")))
4143 (set (attr "length")
4144 (if_then_else (eq_attr "isa" "sparclet")
4145 (const_int 1) (const_int 2)))])
4147 (define_insn "*mulsidi3_sp64"
4148 [(set (match_operand:DI 0 "register_operand" "=r")
4149 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4150 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4151 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4153 [(set_attr "type" "imul")])
4155 ;; Extra pattern, because sign_extend of a constant isn't valid.
4158 (define_insn "const_mulsidi3_sp32"
4159 [(set (match_operand:DI 0 "register_operand" "=r")
4160 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4161 (match_operand:DI 2 "small_int_operand" "I")))]
4164 return TARGET_SPARCLET
4165 ? "smuld\t%1, %2, %L0"
4166 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4169 (if_then_else (eq_attr "isa" "sparclet")
4170 (const_string "imul") (const_string "multi")))
4171 (set (attr "length")
4172 (if_then_else (eq_attr "isa" "sparclet")
4173 (const_int 1) (const_int 2)))])
4175 (define_insn "const_mulsidi3_sp64"
4176 [(set (match_operand:DI 0 "register_operand" "=r")
4177 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4178 (match_operand:DI 2 "small_int_operand" "I")))]
4179 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4181 [(set_attr "type" "imul")])
4183 (define_expand "smulsi3_highpart"
4184 [(set (match_operand:SI 0 "register_operand" "")
4186 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4187 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4189 "TARGET_HARD_MUL && TARGET_ARCH32"
4191 if (CONSTANT_P (operands[2]))
4195 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4201 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4206 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4207 operands[2], GEN_INT (32)));
4213 (define_insn "smulsi3_highpart_v8plus"
4214 [(set (match_operand:SI 0 "register_operand" "=h,r")
4216 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4217 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4218 (match_operand:SI 3 "small_int_operand" "I,I"))))
4219 (clobber (match_scratch:SI 4 "=X,&h"))]
4222 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4223 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4224 [(set_attr "type" "multi")
4225 (set_attr "length" "2")])
4227 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4230 [(set (match_operand:SI 0 "register_operand" "=h,r")
4233 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4234 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4235 (match_operand:SI 3 "small_int_operand" "I,I"))
4237 (clobber (match_scratch:SI 4 "=X,&h"))]
4240 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4241 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4242 [(set_attr "type" "multi")
4243 (set_attr "length" "2")])
4246 (define_insn "const_smulsi3_highpart_v8plus"
4247 [(set (match_operand:SI 0 "register_operand" "=h,r")
4249 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4250 (match_operand:DI 2 "small_int_operand" "I,I"))
4251 (match_operand:SI 3 "small_int_operand" "I,I"))))
4252 (clobber (match_scratch:SI 4 "=X,&h"))]
4255 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4256 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4257 [(set_attr "type" "multi")
4258 (set_attr "length" "2")])
4261 (define_insn "*smulsi3_highpart_sp32"
4262 [(set (match_operand:SI 0 "register_operand" "=r")
4264 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4265 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4268 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4269 [(set_attr "type" "multi")
4270 (set_attr "length" "2")])
4273 (define_insn "const_smulsi3_highpart"
4274 [(set (match_operand:SI 0 "register_operand" "=r")
4276 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4277 (match_operand:DI 2 "small_int_operand" "i"))
4280 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4281 [(set_attr "type" "multi")
4282 (set_attr "length" "2")])
4284 (define_expand "umulsidi3"
4285 [(set (match_operand:DI 0 "register_operand" "")
4286 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4287 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4290 if (CONSTANT_P (operands[2]))
4293 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4295 else if (TARGET_ARCH32)
4296 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4299 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4305 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4311 (define_insn "umulsidi3_v8plus"
4312 [(set (match_operand:DI 0 "register_operand" "=h,r")
4313 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4314 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4315 (clobber (match_scratch:SI 3 "=X,&h"))]
4318 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4319 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4320 [(set_attr "type" "multi")
4321 (set_attr "length" "2,3")])
4324 (define_insn "*umulsidi3_sp32"
4325 [(set (match_operand:DI 0 "register_operand" "=r")
4326 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4327 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4330 return TARGET_SPARCLET
4331 ? "umuld\t%1, %2, %L0"
4332 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4335 (if_then_else (eq_attr "isa" "sparclet")
4336 (const_string "imul") (const_string "multi")))
4337 (set (attr "length")
4338 (if_then_else (eq_attr "isa" "sparclet")
4339 (const_int 1) (const_int 2)))])
4341 (define_insn "*umulsidi3_sp64"
4342 [(set (match_operand:DI 0 "register_operand" "=r")
4343 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4344 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4345 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4347 [(set_attr "type" "imul")])
4349 ;; Extra pattern, because sign_extend of a constant isn't valid.
4352 (define_insn "const_umulsidi3_sp32"
4353 [(set (match_operand:DI 0 "register_operand" "=r")
4354 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4355 (match_operand:DI 2 "uns_small_int_operand" "")))]
4358 return TARGET_SPARCLET
4359 ? "umuld\t%1, %s2, %L0"
4360 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4363 (if_then_else (eq_attr "isa" "sparclet")
4364 (const_string "imul") (const_string "multi")))
4365 (set (attr "length")
4366 (if_then_else (eq_attr "isa" "sparclet")
4367 (const_int 1) (const_int 2)))])
4369 (define_insn "const_umulsidi3_sp64"
4370 [(set (match_operand:DI 0 "register_operand" "=r")
4371 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4372 (match_operand:DI 2 "uns_small_int_operand" "")))]
4373 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4375 [(set_attr "type" "imul")])
4378 (define_insn "const_umulsidi3_v8plus"
4379 [(set (match_operand:DI 0 "register_operand" "=h,r")
4380 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4381 (match_operand:DI 2 "uns_small_int_operand" "")))
4382 (clobber (match_scratch:SI 3 "=X,h"))]
4385 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4386 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4387 [(set_attr "type" "multi")
4388 (set_attr "length" "2,3")])
4390 (define_expand "umulsi3_highpart"
4391 [(set (match_operand:SI 0 "register_operand" "")
4393 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4394 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4396 "TARGET_HARD_MUL && TARGET_ARCH32"
4398 if (CONSTANT_P (operands[2]))
4402 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4408 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4413 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4414 operands[2], GEN_INT (32)));
4420 (define_insn "umulsi3_highpart_v8plus"
4421 [(set (match_operand:SI 0 "register_operand" "=h,r")
4423 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4424 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4425 (match_operand:SI 3 "small_int_operand" "I,I"))))
4426 (clobber (match_scratch:SI 4 "=X,h"))]
4429 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4430 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4431 [(set_attr "type" "multi")
4432 (set_attr "length" "2")])
4435 (define_insn "const_umulsi3_highpart_v8plus"
4436 [(set (match_operand:SI 0 "register_operand" "=h,r")
4438 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4439 (match_operand:DI 2 "uns_small_int_operand" ""))
4440 (match_operand:SI 3 "small_int_operand" "I,I"))))
4441 (clobber (match_scratch:SI 4 "=X,h"))]
4444 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4445 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4446 [(set_attr "type" "multi")
4447 (set_attr "length" "2")])
4450 (define_insn "*umulsi3_highpart_sp32"
4451 [(set (match_operand:SI 0 "register_operand" "=r")
4453 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4454 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4457 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4458 [(set_attr "type" "multi")
4459 (set_attr "length" "2")])
4462 (define_insn "const_umulsi3_highpart"
4463 [(set (match_operand:SI 0 "register_operand" "=r")
4465 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4466 (match_operand:DI 2 "uns_small_int_operand" ""))
4469 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4470 [(set_attr "type" "multi")
4471 (set_attr "length" "2")])
4473 (define_expand "divsi3"
4474 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4475 (div:SI (match_operand:SI 1 "register_operand" "")
4476 (match_operand:SI 2 "input_operand" "")))
4477 (clobber (match_scratch:SI 3 ""))])]
4478 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4482 operands[3] = gen_reg_rtx(SImode);
4483 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4484 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4490 ;; The V8 architecture specifies that there must be at least 3 instructions
4491 ;; between a write to the Y register and a use of it for correct results.
4492 ;; We try to fill one of them with a simple constant or a memory load.
4494 (define_insn "divsi3_sp32"
4495 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4496 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4497 (match_operand:SI 2 "input_operand" "rI,K,m")))
4498 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4499 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4501 output_asm_insn ("sra\t%1, 31, %3", operands);
4502 output_asm_insn ("wr\t%3, 0, %%y", operands);
4504 switch (which_alternative)
4508 return "sdiv\t%1, %2, %0";
4510 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4513 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4515 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4518 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4520 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4525 [(set_attr "type" "multi")
4526 (set (attr "length")
4527 (if_then_else (eq_attr "isa" "v9")
4528 (const_int 4) (const_int 6)))])
4530 (define_insn "divsi3_sp64"
4531 [(set (match_operand:SI 0 "register_operand" "=r")
4532 (div:SI (match_operand:SI 1 "register_operand" "r")
4533 (match_operand:SI 2 "input_operand" "rI")))
4534 (use (match_operand:SI 3 "register_operand" "r"))]
4535 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4536 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4537 [(set_attr "type" "multi")
4538 (set_attr "length" "2")])
4540 (define_insn "divdi3"
4541 [(set (match_operand:DI 0 "register_operand" "=r")
4542 (div:DI (match_operand:DI 1 "register_operand" "r")
4543 (match_operand:DI 2 "arith_operand" "rI")))]
4546 [(set_attr "type" "idiv")])
4548 (define_insn "*cmp_sdiv_cc_set"
4549 [(set (reg:CC CC_REG)
4550 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4551 (match_operand:SI 2 "arith_operand" "rI"))
4553 (set (match_operand:SI 0 "register_operand" "=r")
4554 (div:SI (match_dup 1) (match_dup 2)))
4555 (clobber (match_scratch:SI 3 "=&r"))]
4556 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4558 output_asm_insn ("sra\t%1, 31, %3", operands);
4559 output_asm_insn ("wr\t%3, 0, %%y", operands);
4562 return "sdivcc\t%1, %2, %0";
4564 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4566 [(set_attr "type" "multi")
4567 (set (attr "length")
4568 (if_then_else (eq_attr "isa" "v9")
4569 (const_int 3) (const_int 6)))])
4572 (define_expand "udivsi3"
4573 [(set (match_operand:SI 0 "register_operand" "")
4574 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4575 (match_operand:SI 2 "input_operand" "")))]
4576 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4579 ;; The V8 architecture specifies that there must be at least 3 instructions
4580 ;; between a write to the Y register and a use of it for correct results.
4581 ;; We try to fill one of them with a simple constant or a memory load.
4583 (define_insn "udivsi3_sp32"
4584 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4585 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4586 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4587 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4589 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4591 switch (which_alternative)
4595 return "udiv\t%1, %2, %0";
4597 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4600 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4602 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4605 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4607 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4610 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4612 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4617 [(set_attr "type" "multi")
4618 (set (attr "length")
4619 (if_then_else (eq_attr "isa" "v9")
4620 (const_int 3) (const_int 5)))])
4622 (define_insn "udivsi3_sp64"
4623 [(set (match_operand:SI 0 "register_operand" "=r")
4624 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4625 (match_operand:SI 2 "input_operand" "rI")))]
4626 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4627 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4628 [(set_attr "type" "multi")
4629 (set_attr "length" "2")])
4631 (define_insn "udivdi3"
4632 [(set (match_operand:DI 0 "register_operand" "=r")
4633 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4634 (match_operand:DI 2 "arith_operand" "rI")))]
4637 [(set_attr "type" "idiv")])
4639 (define_insn "*cmp_udiv_cc_set"
4640 [(set (reg:CC CC_REG)
4641 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4642 (match_operand:SI 2 "arith_operand" "rI"))
4644 (set (match_operand:SI 0 "register_operand" "=r")
4645 (udiv:SI (match_dup 1) (match_dup 2)))]
4646 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4648 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4651 return "udivcc\t%1, %2, %0";
4653 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4655 [(set_attr "type" "multi")
4656 (set (attr "length")
4657 (if_then_else (eq_attr "isa" "v9")
4658 (const_int 2) (const_int 5)))])
4660 ; sparclet multiply/accumulate insns
4662 (define_insn "*smacsi"
4663 [(set (match_operand:SI 0 "register_operand" "=r")
4664 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4665 (match_operand:SI 2 "arith_operand" "rI"))
4666 (match_operand:SI 3 "register_operand" "0")))]
4669 [(set_attr "type" "imul")])
4671 (define_insn "*smacdi"
4672 [(set (match_operand:DI 0 "register_operand" "=r")
4673 (plus:DI (mult:DI (sign_extend:DI
4674 (match_operand:SI 1 "register_operand" "%r"))
4676 (match_operand:SI 2 "register_operand" "r")))
4677 (match_operand:DI 3 "register_operand" "0")))]
4679 "smacd\t%1, %2, %L0"
4680 [(set_attr "type" "imul")])
4682 (define_insn "*umacdi"
4683 [(set (match_operand:DI 0 "register_operand" "=r")
4684 (plus:DI (mult:DI (zero_extend:DI
4685 (match_operand:SI 1 "register_operand" "%r"))
4687 (match_operand:SI 2 "register_operand" "r")))
4688 (match_operand:DI 3 "register_operand" "0")))]
4690 "umacd\t%1, %2, %L0"
4691 [(set_attr "type" "imul")])
4694 ;; Boolean instructions.
4696 ;; We define DImode `and' so with DImode `not' we can get
4697 ;; DImode `andn'. Other combinations are possible.
4699 (define_expand "anddi3"
4700 [(set (match_operand:DI 0 "register_operand" "")
4701 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4702 (match_operand:DI 2 "arith_double_operand" "")))]
4706 (define_insn "*anddi3_sp32"
4707 [(set (match_operand:DI 0 "register_operand" "=r")
4708 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4709 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4713 (define_insn "*anddi3_sp64"
4714 [(set (match_operand:DI 0 "register_operand" "=r")
4715 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4716 (match_operand:DI 2 "arith_operand" "rI")))]
4720 (define_insn "andsi3"
4721 [(set (match_operand:SI 0 "register_operand" "=r")
4722 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4723 (match_operand:SI 2 "arith_operand" "rI")))]
4728 [(set (match_operand:SI 0 "register_operand" "")
4729 (and:SI (match_operand:SI 1 "register_operand" "")
4730 (match_operand:SI 2 "const_compl_high_operand" "")))
4731 (clobber (match_operand:SI 3 "register_operand" ""))]
4733 [(set (match_dup 3) (match_dup 4))
4734 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4736 operands[4] = GEN_INT (~INTVAL (operands[2]));
4739 (define_insn_and_split "*and_not_di_sp32"
4740 [(set (match_operand:DI 0 "register_operand" "=&r")
4741 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4742 (match_operand:DI 2 "register_operand" "r")))]
4745 "&& reload_completed
4746 && ((GET_CODE (operands[0]) == REG
4747 && SPARC_INT_REG_P (REGNO (operands[0])))
4748 || (GET_CODE (operands[0]) == SUBREG
4749 && GET_CODE (SUBREG_REG (operands[0])) == REG
4750 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4751 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4752 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4753 "operands[3] = gen_highpart (SImode, operands[0]);
4754 operands[4] = gen_highpart (SImode, operands[1]);
4755 operands[5] = gen_highpart (SImode, operands[2]);
4756 operands[6] = gen_lowpart (SImode, operands[0]);
4757 operands[7] = gen_lowpart (SImode, operands[1]);
4758 operands[8] = gen_lowpart (SImode, operands[2]);"
4759 [(set_attr "length" "2")])
4761 (define_insn "*and_not_di_sp64"
4762 [(set (match_operand:DI 0 "register_operand" "=r")
4763 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4764 (match_operand:DI 2 "register_operand" "r")))]
4768 (define_insn "*and_not_si"
4769 [(set (match_operand:SI 0 "register_operand" "=r")
4770 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4771 (match_operand:SI 2 "register_operand" "r")))]
4775 (define_expand "iordi3"
4776 [(set (match_operand:DI 0 "register_operand" "")
4777 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4778 (match_operand:DI 2 "arith_double_operand" "")))]
4782 (define_insn "*iordi3_sp32"
4783 [(set (match_operand:DI 0 "register_operand" "=r")
4784 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4785 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4788 [(set_attr "length" "2")])
4790 (define_insn "*iordi3_sp64"
4791 [(set (match_operand:DI 0 "register_operand" "=r")
4792 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4793 (match_operand:DI 2 "arith_operand" "rI")))]
4797 (define_insn "iorsi3"
4798 [(set (match_operand:SI 0 "register_operand" "=r")
4799 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4800 (match_operand:SI 2 "arith_operand" "rI")))]
4805 [(set (match_operand:SI 0 "register_operand" "")
4806 (ior:SI (match_operand:SI 1 "register_operand" "")
4807 (match_operand:SI 2 "const_compl_high_operand" "")))
4808 (clobber (match_operand:SI 3 "register_operand" ""))]
4810 [(set (match_dup 3) (match_dup 4))
4811 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4813 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4816 (define_insn_and_split "*or_not_di_sp32"
4817 [(set (match_operand:DI 0 "register_operand" "=&r")
4818 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4819 (match_operand:DI 2 "register_operand" "r")))]
4822 "&& reload_completed
4823 && ((GET_CODE (operands[0]) == REG
4824 && SPARC_INT_REG_P (REGNO (operands[0])))
4825 || (GET_CODE (operands[0]) == SUBREG
4826 && GET_CODE (SUBREG_REG (operands[0])) == REG
4827 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4828 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4829 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4830 "operands[3] = gen_highpart (SImode, operands[0]);
4831 operands[4] = gen_highpart (SImode, operands[1]);
4832 operands[5] = gen_highpart (SImode, operands[2]);
4833 operands[6] = gen_lowpart (SImode, operands[0]);
4834 operands[7] = gen_lowpart (SImode, operands[1]);
4835 operands[8] = gen_lowpart (SImode, operands[2]);"
4836 [(set_attr "length" "2")])
4838 (define_insn "*or_not_di_sp64"
4839 [(set (match_operand:DI 0 "register_operand" "=r")
4840 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4841 (match_operand:DI 2 "register_operand" "r")))]
4845 (define_insn "*or_not_si"
4846 [(set (match_operand:SI 0 "register_operand" "=r")
4847 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4848 (match_operand:SI 2 "register_operand" "r")))]
4852 (define_expand "xordi3"
4853 [(set (match_operand:DI 0 "register_operand" "")
4854 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4855 (match_operand:DI 2 "arith_double_operand" "")))]
4859 (define_insn "*xordi3_sp32"
4860 [(set (match_operand:DI 0 "register_operand" "=r")
4861 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4862 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4865 [(set_attr "length" "2")])
4867 (define_insn "*xordi3_sp64"
4868 [(set (match_operand:DI 0 "register_operand" "=r")
4869 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4870 (match_operand:DI 2 "arith_operand" "rI")))]
4874 (define_insn "xorsi3"
4875 [(set (match_operand:SI 0 "register_operand" "=r")
4876 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4877 (match_operand:SI 2 "arith_operand" "rI")))]
4882 [(set (match_operand:SI 0 "register_operand" "")
4883 (xor:SI (match_operand:SI 1 "register_operand" "")
4884 (match_operand:SI 2 "const_compl_high_operand" "")))
4885 (clobber (match_operand:SI 3 "register_operand" ""))]
4887 [(set (match_dup 3) (match_dup 4))
4888 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4890 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4894 [(set (match_operand:SI 0 "register_operand" "")
4895 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4896 (match_operand:SI 2 "const_compl_high_operand" ""))))
4897 (clobber (match_operand:SI 3 "register_operand" ""))]
4899 [(set (match_dup 3) (match_dup 4))
4900 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4902 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4905 ;; Split DImode logical operations requiring two instructions.
4907 [(set (match_operand:DI 0 "register_operand" "")
4908 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4909 [(match_operand:DI 2 "register_operand" "")
4910 (match_operand:DI 3 "arith_double_operand" "")]))]
4913 && ((GET_CODE (operands[0]) == REG
4914 && SPARC_INT_REG_P (REGNO (operands[0])))
4915 || (GET_CODE (operands[0]) == SUBREG
4916 && GET_CODE (SUBREG_REG (operands[0])) == REG
4917 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4918 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4919 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4921 operands[4] = gen_highpart (SImode, operands[0]);
4922 operands[5] = gen_lowpart (SImode, operands[0]);
4923 operands[6] = gen_highpart (SImode, operands[2]);
4924 operands[7] = gen_lowpart (SImode, operands[2]);
4925 #if HOST_BITS_PER_WIDE_INT == 32
4926 if (GET_CODE (operands[3]) == CONST_INT)
4928 if (INTVAL (operands[3]) < 0)
4929 operands[8] = constm1_rtx;
4931 operands[8] = const0_rtx;
4935 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4936 operands[9] = gen_lowpart (SImode, operands[3]);
4939 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4940 ;; Combine now canonicalizes to the rightmost expression.
4941 (define_insn_and_split "*xor_not_di_sp32"
4942 [(set (match_operand:DI 0 "register_operand" "=&r")
4943 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4944 (match_operand:DI 2 "register_operand" "r"))))]
4947 "&& reload_completed
4948 && ((GET_CODE (operands[0]) == REG
4949 && SPARC_INT_REG_P (REGNO (operands[0])))
4950 || (GET_CODE (operands[0]) == SUBREG
4951 && GET_CODE (SUBREG_REG (operands[0])) == REG
4952 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4953 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4954 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4955 "operands[3] = gen_highpart (SImode, operands[0]);
4956 operands[4] = gen_highpart (SImode, operands[1]);
4957 operands[5] = gen_highpart (SImode, operands[2]);
4958 operands[6] = gen_lowpart (SImode, operands[0]);
4959 operands[7] = gen_lowpart (SImode, operands[1]);
4960 operands[8] = gen_lowpart (SImode, operands[2]);"
4961 [(set_attr "length" "2")])
4963 (define_insn "*xor_not_di_sp64"
4964 [(set (match_operand:DI 0 "register_operand" "=r")
4965 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4966 (match_operand:DI 2 "arith_operand" "rI"))))]
4968 "xnor\t%r1, %2, %0")
4970 (define_insn "*xor_not_si"
4971 [(set (match_operand:SI 0 "register_operand" "=r")
4972 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4973 (match_operand:SI 2 "arith_operand" "rI"))))]
4975 "xnor\t%r1, %2, %0")
4977 ;; These correspond to the above in the case where we also (or only)
4978 ;; want to set the condition code.
4980 (define_insn "*cmp_cc_arith_op"
4981 [(set (reg:CC CC_REG)
4983 (match_operator:SI 2 "cc_arith_operator"
4984 [(match_operand:SI 0 "arith_operand" "%r")
4985 (match_operand:SI 1 "arith_operand" "rI")])
4988 "%A2cc\t%0, %1, %%g0"
4989 [(set_attr "type" "compare")])
4991 (define_insn "*cmp_ccx_arith_op"
4992 [(set (reg:CCX CC_REG)
4994 (match_operator:DI 2 "cc_arith_operator"
4995 [(match_operand:DI 0 "arith_operand" "%r")
4996 (match_operand:DI 1 "arith_operand" "rI")])
4999 "%A2cc\t%0, %1, %%g0"
5000 [(set_attr "type" "compare")])
5002 (define_insn "*cmp_cc_arith_op_set"
5003 [(set (reg:CC CC_REG)
5005 (match_operator:SI 3 "cc_arith_operator"
5006 [(match_operand:SI 1 "arith_operand" "%r")
5007 (match_operand:SI 2 "arith_operand" "rI")])
5009 (set (match_operand:SI 0 "register_operand" "=r")
5010 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5011 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5013 [(set_attr "type" "compare")])
5015 (define_insn "*cmp_ccx_arith_op_set"
5016 [(set (reg:CCX CC_REG)
5018 (match_operator:DI 3 "cc_arith_operator"
5019 [(match_operand:DI 1 "arith_operand" "%r")
5020 (match_operand:DI 2 "arith_operand" "rI")])
5022 (set (match_operand:DI 0 "register_operand" "=r")
5023 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5024 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5026 [(set_attr "type" "compare")])
5028 (define_insn "*cmp_cc_xor_not"
5029 [(set (reg:CC CC_REG)
5031 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5032 (match_operand:SI 1 "arith_operand" "rI")))
5035 "xnorcc\t%r0, %1, %%g0"
5036 [(set_attr "type" "compare")])
5038 (define_insn "*cmp_ccx_xor_not"
5039 [(set (reg:CCX CC_REG)
5041 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5042 (match_operand:DI 1 "arith_operand" "rI")))
5045 "xnorcc\t%r0, %1, %%g0"
5046 [(set_attr "type" "compare")])
5048 (define_insn "*cmp_cc_xor_not_set"
5049 [(set (reg:CC CC_REG)
5051 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5052 (match_operand:SI 2 "arith_operand" "rI")))
5054 (set (match_operand:SI 0 "register_operand" "=r")
5055 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5057 "xnorcc\t%r1, %2, %0"
5058 [(set_attr "type" "compare")])
5060 (define_insn "*cmp_ccx_xor_not_set"
5061 [(set (reg:CCX CC_REG)
5063 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5064 (match_operand:DI 2 "arith_operand" "rI")))
5066 (set (match_operand:DI 0 "register_operand" "=r")
5067 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5069 "xnorcc\t%r1, %2, %0"
5070 [(set_attr "type" "compare")])
5072 (define_insn "*cmp_cc_arith_op_not"
5073 [(set (reg:CC CC_REG)
5075 (match_operator:SI 2 "cc_arith_not_operator"
5076 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5077 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5080 "%B2cc\t%r1, %0, %%g0"
5081 [(set_attr "type" "compare")])
5083 (define_insn "*cmp_ccx_arith_op_not"
5084 [(set (reg:CCX CC_REG)
5086 (match_operator:DI 2 "cc_arith_not_operator"
5087 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5088 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5091 "%B2cc\t%r1, %0, %%g0"
5092 [(set_attr "type" "compare")])
5094 (define_insn "*cmp_cc_arith_op_not_set"
5095 [(set (reg:CC CC_REG)
5097 (match_operator:SI 3 "cc_arith_not_operator"
5098 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5099 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5101 (set (match_operand:SI 0 "register_operand" "=r")
5102 (match_operator:SI 4 "cc_arith_not_operator"
5103 [(not:SI (match_dup 1)) (match_dup 2)]))]
5104 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5105 "%B3cc\t%r2, %1, %0"
5106 [(set_attr "type" "compare")])
5108 (define_insn "*cmp_ccx_arith_op_not_set"
5109 [(set (reg:CCX CC_REG)
5111 (match_operator:DI 3 "cc_arith_not_operator"
5112 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5113 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5115 (set (match_operand:DI 0 "register_operand" "=r")
5116 (match_operator:DI 4 "cc_arith_not_operator"
5117 [(not:DI (match_dup 1)) (match_dup 2)]))]
5118 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5119 "%B3cc\t%r2, %1, %0"
5120 [(set_attr "type" "compare")])
5122 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5123 ;; does not know how to make it work for constants.
5125 (define_expand "negdi2"
5126 [(set (match_operand:DI 0 "register_operand" "=r")
5127 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5130 if (! TARGET_ARCH64)
5132 emit_insn (gen_rtx_PARALLEL
5135 gen_rtx_SET (operand0,
5136 gen_rtx_NEG (DImode, operand1)),
5137 gen_rtx_CLOBBER (VOIDmode,
5138 gen_rtx_REG (CCmode,
5144 (define_insn_and_split "*negdi2_sp32"
5145 [(set (match_operand:DI 0 "register_operand" "=&r")
5146 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5147 (clobber (reg:CC CC_REG))]
5150 "&& reload_completed"
5151 [(parallel [(set (reg:CC_NOOV CC_REG)
5152 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5154 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5155 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5156 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5157 "operands[2] = gen_highpart (SImode, operands[0]);
5158 operands[3] = gen_highpart (SImode, operands[1]);
5159 operands[4] = gen_lowpart (SImode, operands[0]);
5160 operands[5] = gen_lowpart (SImode, operands[1]);"
5161 [(set_attr "length" "2")])
5163 (define_insn "*negdi2_sp64"
5164 [(set (match_operand:DI 0 "register_operand" "=r")
5165 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5167 "sub\t%%g0, %1, %0")
5169 (define_insn "negsi2"
5170 [(set (match_operand:SI 0 "register_operand" "=r")
5171 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5173 "sub\t%%g0, %1, %0")
5175 (define_insn "*cmp_cc_neg"
5176 [(set (reg:CC_NOOV CC_REG)
5177 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5180 "subcc\t%%g0, %0, %%g0"
5181 [(set_attr "type" "compare")])
5183 (define_insn "*cmp_ccx_neg"
5184 [(set (reg:CCX_NOOV CC_REG)
5185 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5188 "subcc\t%%g0, %0, %%g0"
5189 [(set_attr "type" "compare")])
5191 (define_insn "*cmp_cc_set_neg"
5192 [(set (reg:CC_NOOV CC_REG)
5193 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5195 (set (match_operand:SI 0 "register_operand" "=r")
5196 (neg:SI (match_dup 1)))]
5198 "subcc\t%%g0, %1, %0"
5199 [(set_attr "type" "compare")])
5201 (define_insn "*cmp_ccx_set_neg"
5202 [(set (reg:CCX_NOOV CC_REG)
5203 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5205 (set (match_operand:DI 0 "register_operand" "=r")
5206 (neg:DI (match_dup 1)))]
5208 "subcc\t%%g0, %1, %0"
5209 [(set_attr "type" "compare")])
5211 ;; We cannot use the "not" pseudo insn because the Sun assembler
5212 ;; does not know how to make it work for constants.
5213 (define_expand "one_cmpldi2"
5214 [(set (match_operand:DI 0 "register_operand" "")
5215 (not:DI (match_operand:DI 1 "register_operand" "")))]
5219 (define_insn_and_split "*one_cmpldi2_sp32"
5220 [(set (match_operand:DI 0 "register_operand" "=&r")
5221 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5224 "&& reload_completed
5225 && ((GET_CODE (operands[0]) == REG
5226 && SPARC_INT_REG_P (REGNO (operands[0])))
5227 || (GET_CODE (operands[0]) == SUBREG
5228 && GET_CODE (SUBREG_REG (operands[0])) == REG
5229 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5230 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5231 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5232 "operands[2] = gen_highpart (SImode, operands[0]);
5233 operands[3] = gen_highpart (SImode, operands[1]);
5234 operands[4] = gen_lowpart (SImode, operands[0]);
5235 operands[5] = gen_lowpart (SImode, operands[1]);"
5236 [(set_attr "length" "2")])
5238 (define_insn "*one_cmpldi2_sp64"
5239 [(set (match_operand:DI 0 "register_operand" "=r")
5240 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5242 "xnor\t%%g0, %1, %0")
5244 (define_insn "one_cmplsi2"
5245 [(set (match_operand:SI 0 "register_operand" "=r")
5246 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5248 "xnor\t%%g0, %1, %0")
5250 (define_insn "*cmp_cc_not"
5251 [(set (reg:CC CC_REG)
5252 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5255 "xnorcc\t%%g0, %0, %%g0"
5256 [(set_attr "type" "compare")])
5258 (define_insn "*cmp_ccx_not"
5259 [(set (reg:CCX CC_REG)
5260 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5263 "xnorcc\t%%g0, %0, %%g0"
5264 [(set_attr "type" "compare")])
5266 (define_insn "*cmp_cc_set_not"
5267 [(set (reg:CC CC_REG)
5268 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5270 (set (match_operand:SI 0 "register_operand" "=r")
5271 (not:SI (match_dup 1)))]
5273 "xnorcc\t%%g0, %1, %0"
5274 [(set_attr "type" "compare")])
5276 (define_insn "*cmp_ccx_set_not"
5277 [(set (reg:CCX CC_REG)
5278 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5280 (set (match_operand:DI 0 "register_operand" "=r")
5281 (not:DI (match_dup 1)))]
5283 "xnorcc\t%%g0, %1, %0"
5284 [(set_attr "type" "compare")])
5286 (define_insn "*cmp_cc_set"
5287 [(set (match_operand:SI 0 "register_operand" "=r")
5288 (match_operand:SI 1 "register_operand" "r"))
5289 (set (reg:CC CC_REG)
5290 (compare:CC (match_dup 1)
5294 [(set_attr "type" "compare")])
5296 (define_insn "*cmp_ccx_set64"
5297 [(set (match_operand:DI 0 "register_operand" "=r")
5298 (match_operand:DI 1 "register_operand" "r"))
5299 (set (reg:CCX CC_REG)
5300 (compare:CCX (match_dup 1)
5304 [(set_attr "type" "compare")])
5307 ;; Floating point arithmetic instructions.
5309 (define_expand "addtf3"
5310 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5311 (plus:TF (match_operand:TF 1 "general_operand" "")
5312 (match_operand:TF 2 "general_operand" "")))]
5313 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5314 "emit_tfmode_binop (PLUS, operands); DONE;")
5316 (define_insn "*addtf3_hq"
5317 [(set (match_operand:TF 0 "register_operand" "=e")
5318 (plus:TF (match_operand:TF 1 "register_operand" "e")
5319 (match_operand:TF 2 "register_operand" "e")))]
5320 "TARGET_FPU && TARGET_HARD_QUAD"
5322 [(set_attr "type" "fp")])
5324 (define_insn "adddf3"
5325 [(set (match_operand:DF 0 "register_operand" "=e")
5326 (plus:DF (match_operand:DF 1 "register_operand" "e")
5327 (match_operand:DF 2 "register_operand" "e")))]
5330 [(set_attr "type" "fp")
5331 (set_attr "fptype" "double")])
5333 (define_insn "addsf3"
5334 [(set (match_operand:SF 0 "register_operand" "=f")
5335 (plus:SF (match_operand:SF 1 "register_operand" "f")
5336 (match_operand:SF 2 "register_operand" "f")))]
5339 [(set_attr "type" "fp")])
5341 (define_expand "subtf3"
5342 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5343 (minus:TF (match_operand:TF 1 "general_operand" "")
5344 (match_operand:TF 2 "general_operand" "")))]
5345 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5346 "emit_tfmode_binop (MINUS, operands); DONE;")
5348 (define_insn "*subtf3_hq"
5349 [(set (match_operand:TF 0 "register_operand" "=e")
5350 (minus:TF (match_operand:TF 1 "register_operand" "e")
5351 (match_operand:TF 2 "register_operand" "e")))]
5352 "TARGET_FPU && TARGET_HARD_QUAD"
5354 [(set_attr "type" "fp")])
5356 (define_insn "subdf3"
5357 [(set (match_operand:DF 0 "register_operand" "=e")
5358 (minus:DF (match_operand:DF 1 "register_operand" "e")
5359 (match_operand:DF 2 "register_operand" "e")))]
5362 [(set_attr "type" "fp")
5363 (set_attr "fptype" "double")])
5365 (define_insn "subsf3"
5366 [(set (match_operand:SF 0 "register_operand" "=f")
5367 (minus:SF (match_operand:SF 1 "register_operand" "f")
5368 (match_operand:SF 2 "register_operand" "f")))]
5371 [(set_attr "type" "fp")])
5373 (define_expand "multf3"
5374 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5375 (mult:TF (match_operand:TF 1 "general_operand" "")
5376 (match_operand:TF 2 "general_operand" "")))]
5377 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5378 "emit_tfmode_binop (MULT, operands); DONE;")
5380 (define_insn "*multf3_hq"
5381 [(set (match_operand:TF 0 "register_operand" "=e")
5382 (mult:TF (match_operand:TF 1 "register_operand" "e")
5383 (match_operand:TF 2 "register_operand" "e")))]
5384 "TARGET_FPU && TARGET_HARD_QUAD"
5386 [(set_attr "type" "fpmul")])
5388 (define_insn "muldf3"
5389 [(set (match_operand:DF 0 "register_operand" "=e")
5390 (mult:DF (match_operand:DF 1 "register_operand" "e")
5391 (match_operand:DF 2 "register_operand" "e")))]
5394 [(set_attr "type" "fpmul")
5395 (set_attr "fptype" "double")])
5397 (define_insn "mulsf3"
5398 [(set (match_operand:SF 0 "register_operand" "=f")
5399 (mult:SF (match_operand:SF 1 "register_operand" "f")
5400 (match_operand:SF 2 "register_operand" "f")))]
5403 [(set_attr "type" "fpmul")])
5405 (define_insn "fmadf4"
5406 [(set (match_operand:DF 0 "register_operand" "=e")
5407 (fma:DF (match_operand:DF 1 "register_operand" "e")
5408 (match_operand:DF 2 "register_operand" "e")
5409 (match_operand:DF 3 "register_operand" "e")))]
5411 "fmaddd\t%1, %2, %3, %0"
5412 [(set_attr "type" "fpmul")])
5414 (define_insn "fmsdf4"
5415 [(set (match_operand:DF 0 "register_operand" "=e")
5416 (fma:DF (match_operand:DF 1 "register_operand" "e")
5417 (match_operand:DF 2 "register_operand" "e")
5418 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5420 "fmsubd\t%1, %2, %3, %0"
5421 [(set_attr "type" "fpmul")])
5423 (define_insn "*nfmadf4"
5424 [(set (match_operand:DF 0 "register_operand" "=e")
5425 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5426 (match_operand:DF 2 "register_operand" "e")
5427 (match_operand:DF 3 "register_operand" "e"))))]
5429 "fnmaddd\t%1, %2, %3, %0"
5430 [(set_attr "type" "fpmul")])
5432 (define_insn "*nfmsdf4"
5433 [(set (match_operand:DF 0 "register_operand" "=e")
5434 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5435 (match_operand:DF 2 "register_operand" "e")
5436 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5438 "fnmsubd\t%1, %2, %3, %0"
5439 [(set_attr "type" "fpmul")])
5441 (define_insn "fmasf4"
5442 [(set (match_operand:SF 0 "register_operand" "=f")
5443 (fma:SF (match_operand:SF 1 "register_operand" "f")
5444 (match_operand:SF 2 "register_operand" "f")
5445 (match_operand:SF 3 "register_operand" "f")))]
5447 "fmadds\t%1, %2, %3, %0"
5448 [(set_attr "type" "fpmul")])
5450 (define_insn "fmssf4"
5451 [(set (match_operand:SF 0 "register_operand" "=f")
5452 (fma:SF (match_operand:SF 1 "register_operand" "f")
5453 (match_operand:SF 2 "register_operand" "f")
5454 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5456 "fmsubs\t%1, %2, %3, %0"
5457 [(set_attr "type" "fpmul")])
5459 (define_insn "*nfmasf4"
5460 [(set (match_operand:SF 0 "register_operand" "=f")
5461 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5462 (match_operand:SF 2 "register_operand" "f")
5463 (match_operand:SF 3 "register_operand" "f"))))]
5465 "fnmadds\t%1, %2, %3, %0"
5466 [(set_attr "type" "fpmul")])
5468 (define_insn "*nfmssf4"
5469 [(set (match_operand:SF 0 "register_operand" "=f")
5470 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5471 (match_operand:SF 2 "register_operand" "f")
5472 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5474 "fnmsubs\t%1, %2, %3, %0"
5475 [(set_attr "type" "fpmul")])
5477 (define_insn "*muldf3_extend"
5478 [(set (match_operand:DF 0 "register_operand" "=e")
5479 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5480 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5481 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5482 "fsmuld\t%1, %2, %0"
5483 [(set_attr "type" "fpmul")
5484 (set_attr "fptype" "double")])
5486 (define_insn "*multf3_extend"
5487 [(set (match_operand:TF 0 "register_operand" "=e")
5488 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5489 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5490 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5491 "fdmulq\t%1, %2, %0"
5492 [(set_attr "type" "fpmul")])
5494 (define_expand "divtf3"
5495 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5496 (div:TF (match_operand:TF 1 "general_operand" "")
5497 (match_operand:TF 2 "general_operand" "")))]
5498 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5499 "emit_tfmode_binop (DIV, operands); DONE;")
5501 ;; don't have timing for quad-prec. divide.
5502 (define_insn "*divtf3_hq"
5503 [(set (match_operand:TF 0 "register_operand" "=e")
5504 (div:TF (match_operand:TF 1 "register_operand" "e")
5505 (match_operand:TF 2 "register_operand" "e")))]
5506 "TARGET_FPU && TARGET_HARD_QUAD"
5508 [(set_attr "type" "fpdivs")])
5510 (define_expand "divdf3"
5511 [(set (match_operand:DF 0 "register_operand" "=e")
5512 (div:DF (match_operand:DF 1 "register_operand" "e")
5513 (match_operand:DF 2 "register_operand" "e")))]
5517 (define_insn "*divdf3_nofix"
5518 [(set (match_operand:DF 0 "register_operand" "=e")
5519 (div:DF (match_operand:DF 1 "register_operand" "e")
5520 (match_operand:DF 2 "register_operand" "e")))]
5521 "TARGET_FPU && !sparc_fix_ut699"
5523 [(set_attr "type" "fpdivd")
5524 (set_attr "fptype" "double")])
5526 (define_insn "*divdf3_fix"
5527 [(set (match_operand:DF 0 "register_operand" "=e")
5528 (div:DF (match_operand:DF 1 "register_operand" "e")
5529 (match_operand:DF 2 "register_operand" "e")))]
5530 "TARGET_FPU && sparc_fix_ut699"
5531 "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5532 [(set_attr "type" "fpdivd")
5533 (set_attr "fptype" "double")
5534 (set_attr "length" "2")])
5536 (define_insn "divsf3"
5537 [(set (match_operand:SF 0 "register_operand" "=f")
5538 (div:SF (match_operand:SF 1 "register_operand" "f")
5539 (match_operand:SF 2 "register_operand" "f")))]
5540 "TARGET_FPU && !sparc_fix_ut699"
5542 [(set_attr "type" "fpdivs")])
5544 (define_expand "negtf2"
5545 [(set (match_operand:TF 0 "register_operand" "")
5546 (neg:TF (match_operand:TF 1 "register_operand" "")))]
5550 (define_insn "*negtf2_hq"
5551 [(set (match_operand:TF 0 "register_operand" "=e")
5552 (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5553 "TARGET_FPU && TARGET_HARD_QUAD"
5555 [(set_attr "type" "fpmove")])
5557 (define_insn_and_split "*negtf2"
5558 [(set (match_operand:TF 0 "register_operand" "=e")
5559 (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5560 "TARGET_FPU && !TARGET_HARD_QUAD"
5562 "&& reload_completed"
5563 [(clobber (const_int 0))]
5565 rtx set_dest = operands[0];
5566 rtx set_src = operands[1];
5570 dest1 = gen_df_reg (set_dest, 0);
5571 dest2 = gen_df_reg (set_dest, 1);
5572 src1 = gen_df_reg (set_src, 0);
5573 src2 = gen_df_reg (set_src, 1);
5575 /* Now emit using the real source and destination we found, swapping
5576 the order if we detect overlap. */
5577 if (reg_overlap_mentioned_p (dest1, src2))
5579 emit_insn (gen_movdf (dest2, src2));
5580 emit_insn (gen_negdf2 (dest1, src1));
5584 emit_insn (gen_negdf2 (dest1, src1));
5585 if (REGNO (dest2) != REGNO (src2))
5586 emit_insn (gen_movdf (dest2, src2));
5590 [(set_attr "length" "2")])
5592 (define_expand "negdf2"
5593 [(set (match_operand:DF 0 "register_operand" "")
5594 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5598 (define_insn_and_split "*negdf2_notv9"
5599 [(set (match_operand:DF 0 "register_operand" "=e")
5600 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5601 "TARGET_FPU && !TARGET_V9"
5603 "&& reload_completed"
5604 [(clobber (const_int 0))]
5606 rtx set_dest = operands[0];
5607 rtx set_src = operands[1];
5611 dest1 = gen_highpart (SFmode, set_dest);
5612 dest2 = gen_lowpart (SFmode, set_dest);
5613 src1 = gen_highpart (SFmode, set_src);
5614 src2 = gen_lowpart (SFmode, set_src);
5616 /* Now emit using the real source and destination we found, swapping
5617 the order if we detect overlap. */
5618 if (reg_overlap_mentioned_p (dest1, src2))
5620 emit_insn (gen_movsf (dest2, src2));
5621 emit_insn (gen_negsf2 (dest1, src1));
5625 emit_insn (gen_negsf2 (dest1, src1));
5626 if (REGNO (dest2) != REGNO (src2))
5627 emit_insn (gen_movsf (dest2, src2));
5631 [(set_attr "length" "2")])
5633 (define_insn "*negdf2_v9"
5634 [(set (match_operand:DF 0 "register_operand" "=e")
5635 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5636 "TARGET_FPU && TARGET_V9"
5638 [(set_attr "type" "fpmove")
5639 (set_attr "fptype" "double")])
5641 (define_insn "negsf2"
5642 [(set (match_operand:SF 0 "register_operand" "=f")
5643 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5646 [(set_attr "type" "fpmove")])
5648 (define_expand "abstf2"
5649 [(set (match_operand:TF 0 "register_operand" "")
5650 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5654 (define_insn "*abstf2_hq"
5655 [(set (match_operand:TF 0 "register_operand" "=e")
5656 (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5657 "TARGET_FPU && TARGET_HARD_QUAD"
5659 [(set_attr "type" "fpmove")])
5661 (define_insn_and_split "*abstf2"
5662 [(set (match_operand:TF 0 "register_operand" "=e")
5663 (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5664 "TARGET_FPU && !TARGET_HARD_QUAD"
5666 "&& reload_completed"
5667 [(clobber (const_int 0))]
5669 rtx set_dest = operands[0];
5670 rtx set_src = operands[1];
5674 dest1 = gen_df_reg (set_dest, 0);
5675 dest2 = gen_df_reg (set_dest, 1);
5676 src1 = gen_df_reg (set_src, 0);
5677 src2 = gen_df_reg (set_src, 1);
5679 /* Now emit using the real source and destination we found, swapping
5680 the order if we detect overlap. */
5681 if (reg_overlap_mentioned_p (dest1, src2))
5683 emit_insn (gen_movdf (dest2, src2));
5684 emit_insn (gen_absdf2 (dest1, src1));
5688 emit_insn (gen_absdf2 (dest1, src1));
5689 if (REGNO (dest2) != REGNO (src2))
5690 emit_insn (gen_movdf (dest2, src2));
5694 [(set_attr "length" "2")])
5696 (define_expand "absdf2"
5697 [(set (match_operand:DF 0 "register_operand" "")
5698 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5702 (define_insn_and_split "*absdf2_notv9"
5703 [(set (match_operand:DF 0 "register_operand" "=e")
5704 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5705 "TARGET_FPU && !TARGET_V9"
5707 "&& reload_completed"
5708 [(clobber (const_int 0))]
5710 rtx set_dest = operands[0];
5711 rtx set_src = operands[1];
5715 dest1 = gen_highpart (SFmode, set_dest);
5716 dest2 = gen_lowpart (SFmode, set_dest);
5717 src1 = gen_highpart (SFmode, set_src);
5718 src2 = gen_lowpart (SFmode, set_src);
5720 /* Now emit using the real source and destination we found, swapping
5721 the order if we detect overlap. */
5722 if (reg_overlap_mentioned_p (dest1, src2))
5724 emit_insn (gen_movsf (dest2, src2));
5725 emit_insn (gen_abssf2 (dest1, src1));
5729 emit_insn (gen_abssf2 (dest1, src1));
5730 if (REGNO (dest2) != REGNO (src2))
5731 emit_insn (gen_movsf (dest2, src2));
5735 [(set_attr "length" "2")])
5737 (define_insn "*absdf2_v9"
5738 [(set (match_operand:DF 0 "register_operand" "=e")
5739 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5740 "TARGET_FPU && TARGET_V9"
5742 [(set_attr "type" "fpmove")
5743 (set_attr "fptype" "double")])
5745 (define_insn "abssf2"
5746 [(set (match_operand:SF 0 "register_operand" "=f")
5747 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5750 [(set_attr "type" "fpmove")])
5752 (define_expand "sqrttf2"
5753 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5754 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5755 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5756 "emit_tfmode_unop (SQRT, operands); DONE;")
5758 (define_insn "*sqrttf2_hq"
5759 [(set (match_operand:TF 0 "register_operand" "=e")
5760 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5761 "TARGET_FPU && TARGET_HARD_QUAD"
5763 [(set_attr "type" "fpsqrts")])
5765 (define_expand "sqrtdf2"
5766 [(set (match_operand:DF 0 "register_operand" "=e")
5767 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5771 (define_insn "*sqrtdf2_nofix"
5772 [(set (match_operand:DF 0 "register_operand" "=e")
5773 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5774 "TARGET_FPU && !sparc_fix_ut699"
5776 [(set_attr "type" "fpsqrtd")
5777 (set_attr "fptype" "double")])
5779 (define_insn "*sqrtdf2_fix"
5780 [(set (match_operand:DF 0 "register_operand" "=e")
5781 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5782 "TARGET_FPU && sparc_fix_ut699"
5783 "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5784 [(set_attr "type" "fpsqrtd")
5785 (set_attr "fptype" "double")
5786 (set_attr "length" "2")])
5788 (define_insn "sqrtsf2"
5789 [(set (match_operand:SF 0 "register_operand" "=f")
5790 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5791 "TARGET_FPU && !sparc_fix_ut699"
5793 [(set_attr "type" "fpsqrts")])
5796 ;; Arithmetic shift instructions.
5798 (define_insn "ashlsi3"
5799 [(set (match_operand:SI 0 "register_operand" "=r")
5800 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5801 (match_operand:SI 2 "arith_operand" "rI")))]
5804 if (GET_CODE (operands[2]) == CONST_INT)
5805 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5806 return "sll\t%1, %2, %0";
5808 [(set_attr "type" "shift")])
5810 (define_expand "ashldi3"
5811 [(set (match_operand:DI 0 "register_operand" "=r")
5812 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:SI 2 "arith_operand" "rI")))]
5814 "TARGET_ARCH64 || TARGET_V8PLUS"
5816 if (! TARGET_ARCH64)
5818 if (GET_CODE (operands[2]) == CONST_INT)
5820 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5825 (define_insn "*ashldi3_sp64"
5826 [(set (match_operand:DI 0 "register_operand" "=r")
5827 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5828 (match_operand:SI 2 "arith_operand" "rI")))]
5831 if (GET_CODE (operands[2]) == CONST_INT)
5832 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5833 return "sllx\t%1, %2, %0";
5835 [(set_attr "type" "shift")])
5838 (define_insn "ashldi3_v8plus"
5839 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5840 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5841 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5842 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5844 "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5845 [(set_attr "type" "multi")
5846 (set_attr "length" "5,5,6")])
5848 ;; Optimize (1LL<<x)-1
5849 ;; XXX this also needs to be fixed to handle equal subregs
5850 ;; XXX first before we could re-enable it.
5852 ; [(set (match_operand:DI 0 "register_operand" "=h")
5853 ; (plus:DI (ashift:DI (const_int 1)
5854 ; (match_operand:SI 1 "arith_operand" "rI"))
5856 ; "0 && TARGET_V8PLUS"
5858 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5859 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5860 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5862 ; [(set_attr "type" "multi")
5863 ; (set_attr "length" "4")])
5865 (define_insn "*cmp_cc_ashift_1"
5866 [(set (reg:CC_NOOV CC_REG)
5867 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5871 "addcc\t%0, %0, %%g0"
5872 [(set_attr "type" "compare")])
5874 (define_insn "*cmp_cc_set_ashift_1"
5875 [(set (reg:CC_NOOV CC_REG)
5876 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5879 (set (match_operand:SI 0 "register_operand" "=r")
5880 (ashift:SI (match_dup 1) (const_int 1)))]
5883 [(set_attr "type" "compare")])
5885 (define_insn "ashrsi3"
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5887 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5888 (match_operand:SI 2 "arith_operand" "rI")))]
5891 if (GET_CODE (operands[2]) == CONST_INT)
5892 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5893 return "sra\t%1, %2, %0";
5895 [(set_attr "type" "shift")])
5897 (define_insn "*ashrsi3_extend"
5898 [(set (match_operand:DI 0 "register_operand" "=r")
5899 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5900 (match_operand:SI 2 "arith_operand" "r"))))]
5903 [(set_attr "type" "shift")])
5905 ;; This handles the case as above, but with constant shift instead of
5906 ;; register. Combiner "simplifies" it for us a little bit though.
5907 (define_insn "*ashrsi3_extend2"
5908 [(set (match_operand:DI 0 "register_operand" "=r")
5909 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5911 (match_operand:SI 2 "small_int_operand" "I")))]
5912 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5914 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5915 return "sra\t%1, %2, %0";
5917 [(set_attr "type" "shift")])
5919 (define_expand "ashrdi3"
5920 [(set (match_operand:DI 0 "register_operand" "=r")
5921 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5922 (match_operand:SI 2 "arith_operand" "rI")))]
5923 "TARGET_ARCH64 || TARGET_V8PLUS"
5925 if (! TARGET_ARCH64)
5927 if (GET_CODE (operands[2]) == CONST_INT)
5928 FAIL; /* prefer generic code in this case */
5929 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5934 (define_insn "*ashrdi3_sp64"
5935 [(set (match_operand:DI 0 "register_operand" "=r")
5936 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5937 (match_operand:SI 2 "arith_operand" "rI")))]
5941 if (GET_CODE (operands[2]) == CONST_INT)
5942 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5943 return "srax\t%1, %2, %0";
5945 [(set_attr "type" "shift")])
5948 (define_insn "ashrdi3_v8plus"
5949 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5950 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5951 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5952 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5954 "* return output_v8plus_shift (insn, operands, \"srax\");"
5955 [(set_attr "type" "multi")
5956 (set_attr "length" "5,5,6")])
5958 (define_insn "lshrsi3"
5959 [(set (match_operand:SI 0 "register_operand" "=r")
5960 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5961 (match_operand:SI 2 "arith_operand" "rI")))]
5964 if (GET_CODE (operands[2]) == CONST_INT)
5965 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5966 return "srl\t%1, %2, %0";
5968 [(set_attr "type" "shift")])
5970 (define_insn "*lshrsi3_extend0"
5971 [(set (match_operand:DI 0 "register_operand" "=r")
5973 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5974 (match_operand:SI 2 "arith_operand" "rI"))))]
5977 if (GET_CODE (operands[2]) == CONST_INT)
5978 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5979 return "srl\t%1, %2, %0";
5981 [(set_attr "type" "shift")])
5983 ;; This handles the case where
5984 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5985 ;; but combiner "simplifies" it for us.
5986 (define_insn "*lshrsi3_extend1"
5987 [(set (match_operand:DI 0 "register_operand" "=r")
5988 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5989 (match_operand:SI 2 "arith_operand" "r")) 0)
5990 (match_operand 3 "const_int_operand" "")))]
5991 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5993 [(set_attr "type" "shift")])
5995 ;; This handles the case where
5996 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5997 ;; but combiner "simplifies" it for us.
5998 (define_insn "*lshrsi3_extend2"
5999 [(set (match_operand:DI 0 "register_operand" "=r")
6000 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6001 (match_operand 2 "small_int_operand" "I")
6003 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6005 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6006 return "srl\t%1, %2, %0";
6008 [(set_attr "type" "shift")])
6010 (define_expand "lshrdi3"
6011 [(set (match_operand:DI 0 "register_operand" "=r")
6012 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6013 (match_operand:SI 2 "arith_operand" "rI")))]
6014 "TARGET_ARCH64 || TARGET_V8PLUS"
6016 if (! TARGET_ARCH64)
6018 if (GET_CODE (operands[2]) == CONST_INT)
6020 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6025 (define_insn "*lshrdi3_sp64"
6026 [(set (match_operand:DI 0 "register_operand" "=r")
6027 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6028 (match_operand:SI 2 "arith_operand" "rI")))]
6031 if (GET_CODE (operands[2]) == CONST_INT)
6032 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6033 return "srlx\t%1, %2, %0";
6035 [(set_attr "type" "shift")])
6038 (define_insn "lshrdi3_v8plus"
6039 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6040 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6041 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6042 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6044 "* return output_v8plus_shift (insn, operands, \"srlx\");"
6045 [(set_attr "type" "multi")
6046 (set_attr "length" "5,5,6")])
6049 [(set (match_operand:SI 0 "register_operand" "=r")
6050 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6052 (match_operand:SI 2 "small_int_operand" "I")))]
6053 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6055 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6056 return "srax\t%1, %2, %0";
6058 [(set_attr "type" "shift")])
6061 [(set (match_operand:SI 0 "register_operand" "=r")
6062 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6064 (match_operand:SI 2 "small_int_operand" "I")))]
6065 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6067 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6068 return "srlx\t%1, %2, %0";
6070 [(set_attr "type" "shift")])
6073 [(set (match_operand:SI 0 "register_operand" "=r")
6074 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6075 (match_operand:SI 2 "small_int_operand" "I")) 4)
6076 (match_operand:SI 3 "small_int_operand" "I")))]
6078 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6079 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6080 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6082 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6084 return "srax\t%1, %2, %0";
6086 [(set_attr "type" "shift")])
6089 [(set (match_operand:SI 0 "register_operand" "=r")
6090 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6091 (match_operand:SI 2 "small_int_operand" "I")) 4)
6092 (match_operand:SI 3 "small_int_operand" "I")))]
6094 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6095 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6096 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6098 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6100 return "srlx\t%1, %2, %0";
6102 [(set_attr "type" "shift")])
6105 ;; Unconditional and other jump instructions.
6107 (define_expand "jump"
6108 [(set (pc) (label_ref (match_operand 0 "" "")))]
6111 (define_insn "*jump_ubranch"
6112 [(set (pc) (label_ref (match_operand 0 "" "")))]
6114 "* return output_ubranch (operands[0], insn);"
6115 [(set_attr "type" "uncond_branch")])
6117 (define_insn "*jump_cbcond"
6118 [(set (pc) (label_ref (match_operand 0 "" "")))]
6120 "* return output_ubranch (operands[0], insn);"
6121 [(set_attr "type" "uncond_cbcond")])
6123 (define_expand "tablejump"
6124 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6125 (use (label_ref (match_operand 1 "" "")))])]
6128 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6130 /* In pic mode, our address differences are against the base of the
6131 table. Add that base value back in; CSE ought to be able to combine
6132 the two address loads. */
6136 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6138 if (CASE_VECTOR_MODE != Pmode)
6139 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6140 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6141 operands[0] = memory_address (Pmode, tmp);
6145 (define_insn "*tablejump_sp32"
6146 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6147 (use (label_ref (match_operand 1 "" "")))]
6150 [(set_attr "type" "uncond_branch")])
6152 (define_insn "*tablejump_sp64"
6153 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6154 (use (label_ref (match_operand 1 "" "")))]
6157 [(set_attr "type" "uncond_branch")])
6160 ;; Jump to subroutine instructions.
6162 (define_expand "call"
6163 ;; Note that this expression is not used for generating RTL.
6164 ;; All the RTL is generated explicitly below.
6165 [(call (match_operand 0 "call_operand" "")
6166 (match_operand 3 "" "i"))]
6167 ;; operands[2] is next_arg_register
6168 ;; operands[3] is struct_value_size_rtx.
6173 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6175 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6177 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6179 /* This is really a PIC sequence. We want to represent
6180 it as a funny jump so its delay slots can be filled.
6182 ??? But if this really *is* a CALL, will not it clobber the
6183 call-clobbered registers? We lose this if it is a JUMP_INSN.
6184 Why cannot we have delay slots filled if it were a CALL? */
6186 /* We accept negative sizes for untyped calls. */
6187 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6192 gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6194 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6200 gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6201 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6205 fn_rtx = operands[0];
6207 /* We accept negative sizes for untyped calls. */
6208 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6209 sparc_emit_call_insn
6212 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6214 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6217 sparc_emit_call_insn
6220 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6221 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6229 ;; We can't use the same pattern for these two insns, because then registers
6230 ;; in the address may not be properly reloaded.
6232 (define_insn "*call_address_sp32"
6233 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6234 (match_operand 1 "" ""))
6235 (clobber (reg:SI O7_REG))]
6236 ;;- Do not use operand 1 for most machines.
6239 [(set_attr "type" "call")])
6241 (define_insn "*call_symbolic_sp32"
6242 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6243 (match_operand 1 "" ""))
6244 (clobber (reg:SI O7_REG))]
6245 ;;- Do not use operand 1 for most machines.
6248 [(set_attr "type" "call")])
6250 (define_insn "*call_address_sp64"
6251 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6252 (match_operand 1 "" ""))
6253 (clobber (reg:DI O7_REG))]
6254 ;;- Do not use operand 1 for most machines.
6257 [(set_attr "type" "call")])
6259 (define_insn "*call_symbolic_sp64"
6260 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6261 (match_operand 1 "" ""))
6262 (clobber (reg:DI O7_REG))]
6263 ;;- Do not use operand 1 for most machines.
6266 [(set_attr "type" "call")])
6268 ;; This is a call that wants a structure value.
6269 ;; There is no such critter for v9 (??? we may need one anyway).
6270 (define_insn "*call_address_struct_value_sp32"
6271 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6272 (match_operand 1 "" ""))
6273 (match_operand 2 "immediate_operand" "")
6274 (clobber (reg:SI O7_REG))]
6275 ;;- Do not use operand 1 for most machines.
6276 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6278 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6279 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6281 [(set_attr "type" "call_no_delay_slot")
6282 (set_attr "length" "3")])
6284 ;; This is a call that wants a structure value.
6285 ;; There is no such critter for v9 (??? we may need one anyway).
6286 (define_insn "*call_symbolic_struct_value_sp32"
6287 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6288 (match_operand 1 "" ""))
6289 (match_operand 2 "immediate_operand" "")
6290 (clobber (reg:SI O7_REG))]
6291 ;;- Do not use operand 1 for most machines.
6292 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6294 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6295 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6297 [(set_attr "type" "call_no_delay_slot")
6298 (set_attr "length" "3")])
6300 ;; This is a call that may want a structure value. This is used for
6302 (define_insn "*call_address_untyped_struct_value_sp32"
6303 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6304 (match_operand 1 "" ""))
6305 (match_operand 2 "immediate_operand" "")
6306 (clobber (reg:SI O7_REG))]
6307 ;;- Do not use operand 1 for most machines.
6308 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6309 "call\t%a0, %1\n\t nop\n\tnop"
6310 [(set_attr "type" "call_no_delay_slot")
6311 (set_attr "length" "3")])
6313 ;; This is a call that may want a structure value. This is used for
6315 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6316 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6317 (match_operand 1 "" ""))
6318 (match_operand 2 "immediate_operand" "")
6319 (clobber (reg:SI O7_REG))]
6320 ;;- Do not use operand 1 for most machines.
6321 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6322 "call\t%a0, %1\n\t nop\n\tnop"
6323 [(set_attr "type" "call_no_delay_slot")
6324 (set_attr "length" "3")])
6326 (define_expand "call_value"
6327 ;; Note that this expression is not used for generating RTL.
6328 ;; All the RTL is generated explicitly below.
6329 [(set (match_operand 0 "register_operand" "=rf")
6330 (call (match_operand 1 "" "")
6331 (match_operand 4 "" "")))]
6332 ;; operand 2 is stack_size_rtx
6333 ;; operand 3 is next_arg_register
6339 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6341 fn_rtx = operands[1];
6344 gen_rtx_SET (operands[0],
6345 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6346 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6348 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6353 (define_insn "*call_value_address_sp32"
6354 [(set (match_operand 0 "" "=rf")
6355 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6356 (match_operand 2 "" "")))
6357 (clobber (reg:SI O7_REG))]
6358 ;;- Do not use operand 2 for most machines.
6361 [(set_attr "type" "call")])
6363 (define_insn "*call_value_symbolic_sp32"
6364 [(set (match_operand 0 "" "=rf")
6365 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6366 (match_operand 2 "" "")))
6367 (clobber (reg:SI O7_REG))]
6368 ;;- Do not use operand 2 for most machines.
6371 [(set_attr "type" "call")])
6373 (define_insn "*call_value_address_sp64"
6374 [(set (match_operand 0 "" "")
6375 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6376 (match_operand 2 "" "")))
6377 (clobber (reg:DI O7_REG))]
6378 ;;- Do not use operand 2 for most machines.
6381 [(set_attr "type" "call")])
6383 (define_insn "*call_value_symbolic_sp64"
6384 [(set (match_operand 0 "" "")
6385 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6386 (match_operand 2 "" "")))
6387 (clobber (reg:DI O7_REG))]
6388 ;;- Do not use operand 2 for most machines.
6391 [(set_attr "type" "call")])
6393 (define_expand "untyped_call"
6394 [(parallel [(call (match_operand 0 "" "")
6396 (match_operand:BLK 1 "memory_operand" "")
6397 (match_operand 2 "" "")])]
6400 rtx valreg1 = gen_rtx_REG (DImode, 8);
6401 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6402 rtx result = operands[1];
6404 /* Pass constm1 to indicate that it may expect a structure value, but
6405 we don't know what size it is. */
6406 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6408 /* Save the function value registers. */
6409 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6410 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6413 /* The optimizer does not know that the call sets the function value
6414 registers we stored in the result block. We avoid problems by
6415 claiming that all hard registers are used and clobbered at this
6417 emit_insn (gen_blockage ());
6422 ;; Tail call instructions.
6424 (define_expand "sibcall"
6425 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6430 (define_insn "*sibcall_symbolic_sp32"
6431 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6432 (match_operand 1 "" ""))
6435 "* return output_sibcall(insn, operands[0]);"
6436 [(set_attr "type" "sibcall")])
6438 (define_insn "*sibcall_symbolic_sp64"
6439 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6440 (match_operand 1 "" ""))
6443 "* return output_sibcall(insn, operands[0]);"
6444 [(set_attr "type" "sibcall")])
6446 (define_expand "sibcall_value"
6447 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6448 (call (match_operand 1 "" "") (const_int 0)))
6453 (define_insn "*sibcall_value_symbolic_sp32"
6454 [(set (match_operand 0 "" "=rf")
6455 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6456 (match_operand 2 "" "")))
6459 "* return output_sibcall(insn, operands[1]);"
6460 [(set_attr "type" "sibcall")])
6462 (define_insn "*sibcall_value_symbolic_sp64"
6463 [(set (match_operand 0 "" "")
6464 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6465 (match_operand 2 "" "")))
6468 "* return output_sibcall(insn, operands[1]);"
6469 [(set_attr "type" "sibcall")])
6472 ;; Special instructions.
6474 (define_expand "prologue"
6479 sparc_flat_expand_prologue ();
6481 sparc_expand_prologue ();
6485 ;; The "register window save" insn is modelled as follows. The dwarf2
6486 ;; information is manually added in emit_window_save.
6488 (define_insn "window_save"
6490 [(match_operand 0 "arith_operand" "rI")]
6493 "save\t%%sp, %0, %%sp"
6494 [(set_attr "type" "savew")])
6496 (define_expand "epilogue"
6501 sparc_flat_expand_epilogue (false);
6503 sparc_expand_epilogue (false);
6506 (define_expand "sibcall_epilogue"
6511 sparc_flat_expand_epilogue (false);
6513 sparc_expand_epilogue (false);
6517 (define_expand "eh_return"
6518 [(use (match_operand 0 "general_operand" ""))]
6521 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6522 emit_jump_insn (gen_eh_return_internal ());
6527 (define_insn_and_split "eh_return_internal"
6531 "epilogue_completed"
6535 sparc_flat_expand_epilogue (true);
6537 sparc_expand_epilogue (true);
6540 (define_expand "return"
6542 "sparc_can_use_return_insn_p ()"
6545 (define_insn "*return_internal"
6548 "* return output_return (insn);"
6549 [(set_attr "type" "return")
6550 (set (attr "length")
6551 (cond [(eq_attr "calls_eh_return" "true")
6552 (if_then_else (eq_attr "delayed_branch" "true")
6553 (if_then_else (ior (eq_attr "isa" "v9")
6554 (eq_attr "flat" "true"))
6557 (if_then_else (eq_attr "flat" "true")
6560 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6561 (if_then_else (eq_attr "empty_delay_slot" "true")
6564 (eq_attr "empty_delay_slot" "true")
6565 (if_then_else (eq_attr "delayed_branch" "true")
6570 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6571 ;; all of memory. This blocks insns from being moved across this point.
6573 (define_insn "blockage"
6574 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6577 [(set_attr "length" "0")])
6579 ;; Do not schedule instructions accessing memory before this point.
6581 (define_expand "frame_blockage"
6583 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6586 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6587 MEM_VOLATILE_P (operands[0]) = 1;
6588 operands[1] = stack_pointer_rtx;
6591 (define_insn "*frame_blockage<P:mode>"
6592 [(set (match_operand:BLK 0 "" "")
6593 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6596 [(set_attr "length" "0")])
6598 (define_expand "probe_stack"
6599 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6603 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6606 (define_insn "probe_stack_range<P:mode>"
6607 [(set (match_operand:P 0 "register_operand" "=r")
6608 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6609 (match_operand:P 2 "register_operand" "r")]
6610 UNSPECV_PROBE_STACK_RANGE))]
6612 "* return output_probe_stack_range (operands[0], operands[2]);"
6613 [(set_attr "type" "multi")])
6615 ;; Prepare to return any type including a structure value.
6617 (define_expand "untyped_return"
6618 [(match_operand:BLK 0 "memory_operand" "")
6619 (match_operand 1 "" "")]
6622 rtx valreg1 = gen_rtx_REG (DImode, 24);
6623 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6624 rtx result = operands[0];
6626 if (! TARGET_ARCH64)
6628 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6629 rtx value = gen_reg_rtx (SImode);
6631 /* Fetch the instruction where we will return to and see if it's an unimp
6632 instruction (the most significant 10 bits will be zero). If so,
6633 update the return address to skip the unimp instruction. */
6634 emit_move_insn (value,
6635 gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6636 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6637 emit_insn (gen_update_return (rtnreg, value));
6640 /* Reload the function value registers. */
6641 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6642 emit_move_insn (valreg2,
6643 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6645 /* Put USE insns before the return. */
6649 /* Construct the return. */
6650 expand_naked_return ();
6655 ;; Adjust the return address conditionally. If the value of op1 is equal
6656 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6657 ;; This is technically *half* the check required by the 32-bit SPARC
6658 ;; psABI. This check only ensures that an "unimp" insn was written by
6659 ;; the caller, but doesn't check to see if the expected size matches
6660 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6661 ;; only used by the above code "untyped_return".
6663 (define_insn "update_return"
6664 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6665 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6668 if (flag_delayed_branch)
6669 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6671 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6673 [(set (attr "type") (const_string "multi"))
6674 (set (attr "length")
6675 (if_then_else (eq_attr "delayed_branch" "true")
6684 (define_expand "indirect_jump"
6685 [(set (pc) (match_operand 0 "address_operand" "p"))]
6689 (define_insn "*branch_sp32"
6690 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6693 [(set_attr "type" "uncond_branch")])
6695 (define_insn "*branch_sp64"
6696 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6699 [(set_attr "type" "uncond_branch")])
6701 (define_expand "save_stack_nonlocal"
6702 [(set (match_operand 0 "memory_operand" "")
6703 (match_operand 1 "register_operand" ""))
6704 (set (match_dup 2) (match_dup 3))]
6707 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6708 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6709 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6712 (define_expand "restore_stack_nonlocal"
6713 [(set (match_operand 0 "register_operand" "")
6714 (match_operand 1 "memory_operand" ""))]
6717 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6720 (define_expand "nonlocal_goto"
6721 [(match_operand 0 "general_operand" "")
6722 (match_operand 1 "general_operand" "")
6723 (match_operand 2 "memory_operand" "")
6724 (match_operand 3 "memory_operand" "")]
6727 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6728 rtx r_label = copy_to_reg (operands[1]);
6729 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6730 rtx r_fp = operands[3];
6731 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6733 /* We need to flush all the register windows so that their contents will
6734 be re-synchronized by the restore insn of the target function. */
6736 emit_insn (gen_flush_register_windows ());
6738 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6739 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6741 /* Restore frame pointer for containing function. */
6742 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6743 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6744 emit_move_insn (i7, r_i7);
6746 /* USE of hard_frame_pointer_rtx added for consistency;
6747 not clear if really needed. */
6748 emit_use (hard_frame_pointer_rtx);
6749 emit_use (stack_pointer_rtx);
6752 emit_jump_insn (gen_indirect_jump (r_label));
6757 (define_expand "builtin_setjmp_receiver"
6758 [(label_ref (match_operand 0 "" ""))]
6761 load_got_register ();
6765 ;; Special insn to flush register windows.
6767 (define_insn "flush_register_windows"
6768 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6770 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6771 [(set_attr "type" "flushw")])
6773 ;; Special pattern for the FLUSH instruction.
6775 (define_insn "flush<P:mode>"
6776 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6778 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6779 [(set_attr "type" "iflush")])
6781 ;; Special insns to load and store the 32-bit FP Status Register.
6783 (define_insn "ldfsr"
6784 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6787 [(set_attr "type" "load")])
6789 (define_insn "stfsr"
6790 [(set (match_operand:SI 0 "memory_operand" "=m")
6791 (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6794 [(set_attr "type" "store")])
6797 ;; Find first set instructions.
6799 ;; The scan instruction searches from the most significant bit while ffs
6800 ;; searches from the least significant bit. The bit index and treatment of
6801 ;; zero also differ. It takes at least 7 instructions to get the proper
6802 ;; result. Here is an obvious 8 instruction sequence.
6805 (define_insn "ffssi2"
6806 [(set (match_operand:SI 0 "register_operand" "=&r")
6807 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6808 (clobber (match_scratch:SI 2 "=&r"))]
6809 "TARGET_SPARCLITE || TARGET_SPARCLET"
6811 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";
6813 [(set_attr "type" "multi")
6814 (set_attr "length" "8")])
6816 (define_expand "popcountdi2"
6817 [(set (match_operand:DI 0 "register_operand" "")
6818 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6821 if (! TARGET_ARCH64)
6823 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6828 (define_insn "*popcountdi_sp64"
6829 [(set (match_operand:DI 0 "register_operand" "=r")
6830 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6831 "TARGET_POPC && TARGET_ARCH64"
6834 (define_insn "popcountdi_v8plus"
6835 [(set (match_operand:DI 0 "register_operand" "=r")
6836 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6837 (clobber (match_scratch:SI 2 "=&h"))]
6838 "TARGET_POPC && ! TARGET_ARCH64"
6840 if (sparc_check_64 (operands[1], insn) <= 0)
6841 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6842 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6844 [(set_attr "type" "multi")
6845 (set_attr "length" "5")])
6847 (define_expand "popcountsi2"
6849 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6850 (set (match_operand:SI 0 "register_operand" "")
6851 (truncate:SI (popcount:DI (match_dup 2))))]
6854 if (! TARGET_ARCH64)
6856 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6860 operands[2] = gen_reg_rtx (DImode);
6863 (define_insn "*popcountsi_sp64"
6864 [(set (match_operand:SI 0 "register_operand" "=r")
6866 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6867 "TARGET_POPC && TARGET_ARCH64"
6870 (define_insn "popcountsi_v8plus"
6871 [(set (match_operand:SI 0 "register_operand" "=r")
6872 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6873 "TARGET_POPC && ! TARGET_ARCH64"
6875 if (sparc_check_64 (operands[1], insn) <= 0)
6876 output_asm_insn ("srl\t%1, 0, %1", operands);
6877 return "popc\t%1, %0";
6879 [(set_attr "type" "multi")
6880 (set_attr "length" "2")])
6882 (define_expand "clzdi2"
6883 [(set (match_operand:DI 0 "register_operand" "")
6884 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6887 if (! TARGET_ARCH64)
6889 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6894 (define_insn "*clzdi_sp64"
6895 [(set (match_operand:DI 0 "register_operand" "=r")
6896 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6897 "TARGET_VIS3 && TARGET_ARCH64"
6900 (define_insn "clzdi_v8plus"
6901 [(set (match_operand:DI 0 "register_operand" "=r")
6902 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6903 (clobber (match_scratch:SI 2 "=&h"))]
6904 "TARGET_VIS3 && ! TARGET_ARCH64"
6906 if (sparc_check_64 (operands[1], insn) <= 0)
6907 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6908 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6910 [(set_attr "type" "multi")
6911 (set_attr "length" "5")])
6913 (define_expand "clzsi2"
6915 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6917 (truncate:SI (clz:DI (match_dup 2))))
6918 (set (match_operand:SI 0 "register_operand" "")
6919 (minus:SI (match_dup 3) (const_int 32)))]
6922 if (! TARGET_ARCH64)
6924 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6929 operands[2] = gen_reg_rtx (DImode);
6930 operands[3] = gen_reg_rtx (SImode);
6934 (define_insn "*clzsi_sp64"
6935 [(set (match_operand:SI 0 "register_operand" "=r")
6937 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6938 "TARGET_VIS3 && TARGET_ARCH64"
6941 (define_insn "clzsi_v8plus"
6942 [(set (match_operand:SI 0 "register_operand" "=r")
6943 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6944 "TARGET_VIS3 && ! TARGET_ARCH64"
6946 if (sparc_check_64 (operands[1], insn) <= 0)
6947 output_asm_insn ("srl\t%1, 0, %1", operands);
6948 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6950 [(set_attr "type" "multi")
6951 (set_attr "length" "3")])
6954 ;; Peepholes go at the end.
6956 ;; Optimize consecutive loads or stores into ldd and std when possible.
6957 ;; The conditions in which we do this are very restricted and are
6958 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6961 [(set (match_operand:SI 0 "memory_operand" "")
6963 (set (match_operand:SI 1 "memory_operand" "")
6966 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6967 [(set (match_dup 0) (const_int 0))]
6969 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6973 [(set (match_operand:SI 0 "memory_operand" "")
6975 (set (match_operand:SI 1 "memory_operand" "")
6978 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6979 [(set (match_dup 1) (const_int 0))]
6981 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
6985 [(set (match_operand:SI 0 "register_operand" "")
6986 (match_operand:SI 1 "memory_operand" ""))
6987 (set (match_operand:SI 2 "register_operand" "")
6988 (match_operand:SI 3 "memory_operand" ""))]
6989 "registers_ok_for_ldd_peep (operands[0], operands[2])
6990 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6991 [(set (match_dup 0) (match_dup 1))]
6993 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
6994 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6998 [(set (match_operand:SI 0 "memory_operand" "")
6999 (match_operand:SI 1 "register_operand" ""))
7000 (set (match_operand:SI 2 "memory_operand" "")
7001 (match_operand:SI 3 "register_operand" ""))]
7002 "registers_ok_for_ldd_peep (operands[1], operands[3])
7003 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7004 [(set (match_dup 0) (match_dup 1))]
7006 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7007 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7011 [(set (match_operand:SF 0 "register_operand" "")
7012 (match_operand:SF 1 "memory_operand" ""))
7013 (set (match_operand:SF 2 "register_operand" "")
7014 (match_operand:SF 3 "memory_operand" ""))]
7015 "registers_ok_for_ldd_peep (operands[0], operands[2])
7016 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7017 [(set (match_dup 0) (match_dup 1))]
7019 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7020 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7024 [(set (match_operand:SF 0 "memory_operand" "")
7025 (match_operand:SF 1 "register_operand" ""))
7026 (set (match_operand:SF 2 "memory_operand" "")
7027 (match_operand:SF 3 "register_operand" ""))]
7028 "registers_ok_for_ldd_peep (operands[1], operands[3])
7029 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7030 [(set (match_dup 0) (match_dup 1))]
7032 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7033 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7037 [(set (match_operand:SI 0 "register_operand" "")
7038 (match_operand:SI 1 "memory_operand" ""))
7039 (set (match_operand:SI 2 "register_operand" "")
7040 (match_operand:SI 3 "memory_operand" ""))]
7041 "registers_ok_for_ldd_peep (operands[2], operands[0])
7042 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7043 [(set (match_dup 2) (match_dup 3))]
7045 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7046 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7050 [(set (match_operand:SI 0 "memory_operand" "")
7051 (match_operand:SI 1 "register_operand" ""))
7052 (set (match_operand:SI 2 "memory_operand" "")
7053 (match_operand:SI 3 "register_operand" ""))]
7054 "registers_ok_for_ldd_peep (operands[3], operands[1])
7055 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7056 [(set (match_dup 2) (match_dup 3))]
7058 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode);
7059 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7063 [(set (match_operand:SF 0 "register_operand" "")
7064 (match_operand:SF 1 "memory_operand" ""))
7065 (set (match_operand:SF 2 "register_operand" "")
7066 (match_operand:SF 3 "memory_operand" ""))]
7067 "registers_ok_for_ldd_peep (operands[2], operands[0])
7068 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7069 [(set (match_dup 2) (match_dup 3))]
7071 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7072 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7076 [(set (match_operand:SF 0 "memory_operand" "")
7077 (match_operand:SF 1 "register_operand" ""))
7078 (set (match_operand:SF 2 "memory_operand" "")
7079 (match_operand:SF 3 "register_operand" ""))]
7080 "registers_ok_for_ldd_peep (operands[3], operands[1])
7081 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7082 [(set (match_dup 2) (match_dup 3))]
7084 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7085 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7088 ;; Optimize the case of following a reg-reg move with a test
7089 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7090 ;; This can result from a float to fix conversion.
7093 [(set (match_operand:SI 0 "register_operand" "")
7094 (match_operand:SI 1 "register_operand" ""))
7095 (set (reg:CC CC_REG)
7096 (compare:CC (match_operand:SI 2 "register_operand" "")
7098 "(rtx_equal_p (operands[2], operands[0])
7099 || rtx_equal_p (operands[2], operands[1]))
7100 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7101 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7102 [(parallel [(set (match_dup 0) (match_dup 1))
7103 (set (reg:CC CC_REG)
7104 (compare:CC (match_dup 1) (const_int 0)))])]
7108 [(set (match_operand:DI 0 "register_operand" "")
7109 (match_operand:DI 1 "register_operand" ""))
7110 (set (reg:CCX CC_REG)
7111 (compare:CCX (match_operand:DI 2 "register_operand" "")
7114 && (rtx_equal_p (operands[2], operands[0])
7115 || rtx_equal_p (operands[2], operands[1]))
7116 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7117 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7118 [(parallel [(set (match_dup 0) (match_dup 1))
7119 (set (reg:CCX CC_REG)
7120 (compare:CCX (match_dup 1) (const_int 0)))])]
7124 ;; Prefetch instructions.
7126 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7127 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7128 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7130 (define_expand "prefetch"
7131 [(match_operand 0 "address_operand" "")
7132 (match_operand 1 "const_int_operand" "")
7133 (match_operand 2 "const_int_operand" "")]
7137 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7139 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7143 (define_insn "prefetch_64"
7144 [(prefetch (match_operand:DI 0 "address_operand" "p")
7145 (match_operand:DI 1 "const_int_operand" "n")
7146 (match_operand:DI 2 "const_int_operand" "n"))]
7149 static const char * const prefetch_instr[2][2] = {
7151 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7152 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7155 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7156 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7159 int read_or_write = INTVAL (operands[1]);
7160 int locality = INTVAL (operands[2]);
7162 gcc_assert (read_or_write == 0 || read_or_write == 1);
7163 gcc_assert (locality >= 0 && locality < 4);
7164 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7166 [(set_attr "type" "load")])
7168 (define_insn "prefetch_32"
7169 [(prefetch (match_operand:SI 0 "address_operand" "p")
7170 (match_operand:SI 1 "const_int_operand" "n")
7171 (match_operand:SI 2 "const_int_operand" "n"))]
7174 static const char * const prefetch_instr[2][2] = {
7176 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7177 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7180 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7181 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7184 int read_or_write = INTVAL (operands[1]);
7185 int locality = INTVAL (operands[2]);
7187 gcc_assert (read_or_write == 0 || read_or_write == 1);
7188 gcc_assert (locality >= 0 && locality < 4);
7189 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7191 [(set_attr "type" "load")])
7194 ;; Trap instructions.
7197 [(trap_if (const_int 1) (const_int 5))]
7200 [(set_attr "type" "trap")])
7202 (define_expand "ctrapsi4"
7203 [(trap_if (match_operator 0 "noov_compare_operator"
7204 [(match_operand:SI 1 "compare_operand" "")
7205 (match_operand:SI 2 "arith_operand" "")])
7206 (match_operand 3 "arith_operand"))]
7208 "operands[1] = gen_compare_reg (operands[0]);
7209 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7211 operands[2] = const0_rtx;")
7213 (define_expand "ctrapdi4"
7214 [(trap_if (match_operator 0 "noov_compare_operator"
7215 [(match_operand:DI 1 "compare_operand" "")
7216 (match_operand:DI 2 "arith_operand" "")])
7217 (match_operand 3 "arith_operand"))]
7219 "operands[1] = gen_compare_reg (operands[0]);
7220 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7222 operands[2] = const0_rtx;")
7226 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7227 (match_operand:SI 1 "arith_operand" "rM"))]
7231 return "t%C0\t%%icc, %1";
7235 [(set_attr "type" "trap")])
7238 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7239 (match_operand:SI 1 "arith_operand" "rM"))]
7242 [(set_attr "type" "trap")])
7245 ;; TLS support instructions.
7247 (define_insn "tgd_hi22"
7248 [(set (match_operand:SI 0 "register_operand" "=r")
7249 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7252 "sethi\\t%%tgd_hi22(%a1), %0")
7254 (define_insn "tgd_lo10"
7255 [(set (match_operand:SI 0 "register_operand" "=r")
7256 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7257 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7260 "add\\t%1, %%tgd_lo10(%a2), %0")
7262 (define_insn "tgd_add32"
7263 [(set (match_operand:SI 0 "register_operand" "=r")
7264 (plus:SI (match_operand:SI 1 "register_operand" "r")
7265 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7266 (match_operand 3 "tgd_symbolic_operand" "")]
7268 "TARGET_TLS && TARGET_ARCH32"
7269 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7271 (define_insn "tgd_add64"
7272 [(set (match_operand:DI 0 "register_operand" "=r")
7273 (plus:DI (match_operand:DI 1 "register_operand" "r")
7274 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7275 (match_operand 3 "tgd_symbolic_operand" "")]
7277 "TARGET_TLS && TARGET_ARCH64"
7278 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7280 (define_insn "tgd_call32"
7281 [(set (match_operand 0 "register_operand" "=r")
7282 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7283 (match_operand 2 "tgd_symbolic_operand" "")]
7285 (match_operand 3 "" "")))
7286 (clobber (reg:SI O7_REG))]
7287 "TARGET_TLS && TARGET_ARCH32"
7288 "call\t%a1, %%tgd_call(%a2)%#"
7289 [(set_attr "type" "call")])
7291 (define_insn "tgd_call64"
7292 [(set (match_operand 0 "register_operand" "=r")
7293 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7294 (match_operand 2 "tgd_symbolic_operand" "")]
7296 (match_operand 3 "" "")))
7297 (clobber (reg:DI O7_REG))]
7298 "TARGET_TLS && TARGET_ARCH64"
7299 "call\t%a1, %%tgd_call(%a2)%#"
7300 [(set_attr "type" "call")])
7302 (define_insn "tldm_hi22"
7303 [(set (match_operand:SI 0 "register_operand" "=r")
7304 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7306 "sethi\\t%%tldm_hi22(%&), %0")
7308 (define_insn "tldm_lo10"
7309 [(set (match_operand:SI 0 "register_operand" "=r")
7310 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7311 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7313 "add\\t%1, %%tldm_lo10(%&), %0")
7315 (define_insn "tldm_add32"
7316 [(set (match_operand:SI 0 "register_operand" "=r")
7317 (plus:SI (match_operand:SI 1 "register_operand" "r")
7318 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7320 "TARGET_TLS && TARGET_ARCH32"
7321 "add\\t%1, %2, %0, %%tldm_add(%&)")
7323 (define_insn "tldm_add64"
7324 [(set (match_operand:DI 0 "register_operand" "=r")
7325 (plus:DI (match_operand:DI 1 "register_operand" "r")
7326 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7328 "TARGET_TLS && TARGET_ARCH64"
7329 "add\\t%1, %2, %0, %%tldm_add(%&)")
7331 (define_insn "tldm_call32"
7332 [(set (match_operand 0 "register_operand" "=r")
7333 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7335 (match_operand 2 "" "")))
7336 (clobber (reg:SI O7_REG))]
7337 "TARGET_TLS && TARGET_ARCH32"
7338 "call\t%a1, %%tldm_call(%&)%#"
7339 [(set_attr "type" "call")])
7341 (define_insn "tldm_call64"
7342 [(set (match_operand 0 "register_operand" "=r")
7343 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7345 (match_operand 2 "" "")))
7346 (clobber (reg:DI O7_REG))]
7347 "TARGET_TLS && TARGET_ARCH64"
7348 "call\t%a1, %%tldm_call(%&)%#"
7349 [(set_attr "type" "call")])
7351 (define_insn "tldo_hix22"
7352 [(set (match_operand:SI 0 "register_operand" "=r")
7353 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7356 "sethi\\t%%tldo_hix22(%a1), %0")
7358 (define_insn "tldo_lox10"
7359 [(set (match_operand:SI 0 "register_operand" "=r")
7360 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7361 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7364 "xor\\t%1, %%tldo_lox10(%a2), %0")
7366 (define_insn "tldo_add32"
7367 [(set (match_operand:SI 0 "register_operand" "=r")
7368 (plus:SI (match_operand:SI 1 "register_operand" "r")
7369 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7370 (match_operand 3 "tld_symbolic_operand" "")]
7372 "TARGET_TLS && TARGET_ARCH32"
7373 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7375 (define_insn "tldo_add64"
7376 [(set (match_operand:DI 0 "register_operand" "=r")
7377 (plus:DI (match_operand:DI 1 "register_operand" "r")
7378 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7379 (match_operand 3 "tld_symbolic_operand" "")]
7381 "TARGET_TLS && TARGET_ARCH64"
7382 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7384 (define_insn "tie_hi22"
7385 [(set (match_operand:SI 0 "register_operand" "=r")
7386 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7389 "sethi\\t%%tie_hi22(%a1), %0")
7391 (define_insn "tie_lo10"
7392 [(set (match_operand:SI 0 "register_operand" "=r")
7393 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7394 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7397 "add\\t%1, %%tie_lo10(%a2), %0")
7399 (define_insn "tie_ld32"
7400 [(set (match_operand:SI 0 "register_operand" "=r")
7401 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7402 (match_operand:SI 2 "register_operand" "r")
7403 (match_operand 3 "tie_symbolic_operand" "")]
7405 "TARGET_TLS && TARGET_ARCH32"
7406 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7407 [(set_attr "type" "load")])
7409 (define_insn "tie_ld64"
7410 [(set (match_operand:DI 0 "register_operand" "=r")
7411 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7412 (match_operand:SI 2 "register_operand" "r")
7413 (match_operand 3 "tie_symbolic_operand" "")]
7415 "TARGET_TLS && TARGET_ARCH64"
7416 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7417 [(set_attr "type" "load")])
7419 (define_insn "tie_add32"
7420 [(set (match_operand:SI 0 "register_operand" "=r")
7421 (plus:SI (match_operand:SI 1 "register_operand" "r")
7422 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7423 (match_operand 3 "tie_symbolic_operand" "")]
7425 "TARGET_SUN_TLS && TARGET_ARCH32"
7426 "add\\t%1, %2, %0, %%tie_add(%a3)")
7428 (define_insn "tie_add64"
7429 [(set (match_operand:DI 0 "register_operand" "=r")
7430 (plus:DI (match_operand:DI 1 "register_operand" "r")
7431 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7432 (match_operand 3 "tie_symbolic_operand" "")]
7434 "TARGET_SUN_TLS && TARGET_ARCH64"
7435 "add\\t%1, %2, %0, %%tie_add(%a3)")
7437 (define_insn "tle_hix22_sp32"
7438 [(set (match_operand:SI 0 "register_operand" "=r")
7439 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7441 "TARGET_TLS && TARGET_ARCH32"
7442 "sethi\\t%%tle_hix22(%a1), %0")
7444 (define_insn "tle_lox10_sp32"
7445 [(set (match_operand:SI 0 "register_operand" "=r")
7446 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7447 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7449 "TARGET_TLS && TARGET_ARCH32"
7450 "xor\\t%1, %%tle_lox10(%a2), %0")
7452 (define_insn "tle_hix22_sp64"
7453 [(set (match_operand:DI 0 "register_operand" "=r")
7454 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7456 "TARGET_TLS && TARGET_ARCH64"
7457 "sethi\\t%%tle_hix22(%a1), %0")
7459 (define_insn "tle_lox10_sp64"
7460 [(set (match_operand:DI 0 "register_operand" "=r")
7461 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7462 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7464 "TARGET_TLS && TARGET_ARCH64"
7465 "xor\\t%1, %%tle_lox10(%a2), %0")
7467 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7468 (define_insn "*tldo_ldub_sp32"
7469 [(set (match_operand:QI 0 "register_operand" "=r")
7470 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7471 (match_operand 3 "tld_symbolic_operand" "")]
7473 (match_operand:SI 1 "register_operand" "r"))))]
7474 "TARGET_TLS && TARGET_ARCH32"
7475 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7476 [(set_attr "type" "load")
7477 (set_attr "us3load_type" "3cycle")])
7479 (define_insn "*tldo_ldub1_sp32"
7480 [(set (match_operand:HI 0 "register_operand" "=r")
7481 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7482 (match_operand 3 "tld_symbolic_operand" "")]
7484 (match_operand:SI 1 "register_operand" "r")))))]
7485 "TARGET_TLS && TARGET_ARCH32"
7486 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7487 [(set_attr "type" "load")
7488 (set_attr "us3load_type" "3cycle")])
7490 (define_insn "*tldo_ldub2_sp32"
7491 [(set (match_operand:SI 0 "register_operand" "=r")
7492 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7493 (match_operand 3 "tld_symbolic_operand" "")]
7495 (match_operand:SI 1 "register_operand" "r")))))]
7496 "TARGET_TLS && TARGET_ARCH32"
7497 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7498 [(set_attr "type" "load")
7499 (set_attr "us3load_type" "3cycle")])
7501 (define_insn "*tldo_ldsb1_sp32"
7502 [(set (match_operand:HI 0 "register_operand" "=r")
7503 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7504 (match_operand 3 "tld_symbolic_operand" "")]
7506 (match_operand:SI 1 "register_operand" "r")))))]
7507 "TARGET_TLS && TARGET_ARCH32"
7508 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7509 [(set_attr "type" "sload")
7510 (set_attr "us3load_type" "3cycle")])
7512 (define_insn "*tldo_ldsb2_sp32"
7513 [(set (match_operand:SI 0 "register_operand" "=r")
7514 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7515 (match_operand 3 "tld_symbolic_operand" "")]
7517 (match_operand:SI 1 "register_operand" "r")))))]
7518 "TARGET_TLS && TARGET_ARCH32"
7519 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7520 [(set_attr "type" "sload")
7521 (set_attr "us3load_type" "3cycle")])
7523 (define_insn "*tldo_ldub_sp64"
7524 [(set (match_operand:QI 0 "register_operand" "=r")
7525 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7526 (match_operand 3 "tld_symbolic_operand" "")]
7528 (match_operand:DI 1 "register_operand" "r"))))]
7529 "TARGET_TLS && TARGET_ARCH64"
7530 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7531 [(set_attr "type" "load")
7532 (set_attr "us3load_type" "3cycle")])
7534 (define_insn "*tldo_ldub1_sp64"
7535 [(set (match_operand:HI 0 "register_operand" "=r")
7536 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7537 (match_operand 3 "tld_symbolic_operand" "")]
7539 (match_operand:DI 1 "register_operand" "r")))))]
7540 "TARGET_TLS && TARGET_ARCH64"
7541 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7542 [(set_attr "type" "load")
7543 (set_attr "us3load_type" "3cycle")])
7545 (define_insn "*tldo_ldub2_sp64"
7546 [(set (match_operand:SI 0 "register_operand" "=r")
7547 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7548 (match_operand 3 "tld_symbolic_operand" "")]
7550 (match_operand:DI 1 "register_operand" "r")))))]
7551 "TARGET_TLS && TARGET_ARCH64"
7552 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7553 [(set_attr "type" "load")
7554 (set_attr "us3load_type" "3cycle")])
7556 (define_insn "*tldo_ldub3_sp64"
7557 [(set (match_operand:DI 0 "register_operand" "=r")
7558 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7559 (match_operand 3 "tld_symbolic_operand" "")]
7561 (match_operand:DI 1 "register_operand" "r")))))]
7562 "TARGET_TLS && TARGET_ARCH64"
7563 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7564 [(set_attr "type" "load")
7565 (set_attr "us3load_type" "3cycle")])
7567 (define_insn "*tldo_ldsb1_sp64"
7568 [(set (match_operand:HI 0 "register_operand" "=r")
7569 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7570 (match_operand 3 "tld_symbolic_operand" "")]
7572 (match_operand:DI 1 "register_operand" "r")))))]
7573 "TARGET_TLS && TARGET_ARCH64"
7574 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7575 [(set_attr "type" "sload")
7576 (set_attr "us3load_type" "3cycle")])
7578 (define_insn "*tldo_ldsb2_sp64"
7579 [(set (match_operand:SI 0 "register_operand" "=r")
7580 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7581 (match_operand 3 "tld_symbolic_operand" "")]
7583 (match_operand:DI 1 "register_operand" "r")))))]
7584 "TARGET_TLS && TARGET_ARCH64"
7585 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7586 [(set_attr "type" "sload")
7587 (set_attr "us3load_type" "3cycle")])
7589 (define_insn "*tldo_ldsb3_sp64"
7590 [(set (match_operand:DI 0 "register_operand" "=r")
7591 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7592 (match_operand 3 "tld_symbolic_operand" "")]
7594 (match_operand:DI 1 "register_operand" "r")))))]
7595 "TARGET_TLS && TARGET_ARCH64"
7596 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7597 [(set_attr "type" "sload")
7598 (set_attr "us3load_type" "3cycle")])
7600 (define_insn "*tldo_lduh_sp32"
7601 [(set (match_operand:HI 0 "register_operand" "=r")
7602 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7603 (match_operand 3 "tld_symbolic_operand" "")]
7605 (match_operand:SI 1 "register_operand" "r"))))]
7606 "TARGET_TLS && TARGET_ARCH32"
7607 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7608 [(set_attr "type" "load")
7609 (set_attr "us3load_type" "3cycle")])
7611 (define_insn "*tldo_lduh1_sp32"
7612 [(set (match_operand:SI 0 "register_operand" "=r")
7613 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7614 (match_operand 3 "tld_symbolic_operand" "")]
7616 (match_operand:SI 1 "register_operand" "r")))))]
7617 "TARGET_TLS && TARGET_ARCH32"
7618 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7619 [(set_attr "type" "load")
7620 (set_attr "us3load_type" "3cycle")])
7622 (define_insn "*tldo_ldsh1_sp32"
7623 [(set (match_operand:SI 0 "register_operand" "=r")
7624 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7625 (match_operand 3 "tld_symbolic_operand" "")]
7627 (match_operand:SI 1 "register_operand" "r")))))]
7628 "TARGET_TLS && TARGET_ARCH32"
7629 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7630 [(set_attr "type" "sload")
7631 (set_attr "us3load_type" "3cycle")])
7633 (define_insn "*tldo_lduh_sp64"
7634 [(set (match_operand:HI 0 "register_operand" "=r")
7635 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7636 (match_operand 3 "tld_symbolic_operand" "")]
7638 (match_operand:DI 1 "register_operand" "r"))))]
7639 "TARGET_TLS && TARGET_ARCH64"
7640 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7641 [(set_attr "type" "load")
7642 (set_attr "us3load_type" "3cycle")])
7644 (define_insn "*tldo_lduh1_sp64"
7645 [(set (match_operand:SI 0 "register_operand" "=r")
7646 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7647 (match_operand 3 "tld_symbolic_operand" "")]
7649 (match_operand:DI 1 "register_operand" "r")))))]
7650 "TARGET_TLS && TARGET_ARCH64"
7651 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7652 [(set_attr "type" "load")
7653 (set_attr "us3load_type" "3cycle")])
7655 (define_insn "*tldo_lduh2_sp64"
7656 [(set (match_operand:DI 0 "register_operand" "=r")
7657 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7658 (match_operand 3 "tld_symbolic_operand" "")]
7660 (match_operand:DI 1 "register_operand" "r")))))]
7661 "TARGET_TLS && TARGET_ARCH64"
7662 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7663 [(set_attr "type" "load")
7664 (set_attr "us3load_type" "3cycle")])
7666 (define_insn "*tldo_ldsh1_sp64"
7667 [(set (match_operand:SI 0 "register_operand" "=r")
7668 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7669 (match_operand 3 "tld_symbolic_operand" "")]
7671 (match_operand:DI 1 "register_operand" "r")))))]
7672 "TARGET_TLS && TARGET_ARCH64"
7673 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7674 [(set_attr "type" "sload")
7675 (set_attr "us3load_type" "3cycle")])
7677 (define_insn "*tldo_ldsh2_sp64"
7678 [(set (match_operand:DI 0 "register_operand" "=r")
7679 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7680 (match_operand 3 "tld_symbolic_operand" "")]
7682 (match_operand:DI 1 "register_operand" "r")))))]
7683 "TARGET_TLS && TARGET_ARCH64"
7684 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7685 [(set_attr "type" "sload")
7686 (set_attr "us3load_type" "3cycle")])
7688 (define_insn "*tldo_lduw_sp32"
7689 [(set (match_operand:SI 0 "register_operand" "=r")
7690 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7691 (match_operand 3 "tld_symbolic_operand" "")]
7693 (match_operand:SI 1 "register_operand" "r"))))]
7694 "TARGET_TLS && TARGET_ARCH32"
7695 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7696 [(set_attr "type" "load")])
7698 (define_insn "*tldo_lduw_sp64"
7699 [(set (match_operand:SI 0 "register_operand" "=r")
7700 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7701 (match_operand 3 "tld_symbolic_operand" "")]
7703 (match_operand:DI 1 "register_operand" "r"))))]
7704 "TARGET_TLS && TARGET_ARCH64"
7705 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7706 [(set_attr "type" "load")])
7708 (define_insn "*tldo_lduw1_sp64"
7709 [(set (match_operand:DI 0 "register_operand" "=r")
7710 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7711 (match_operand 3 "tld_symbolic_operand" "")]
7713 (match_operand:DI 1 "register_operand" "r")))))]
7714 "TARGET_TLS && TARGET_ARCH64"
7715 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7716 [(set_attr "type" "load")])
7718 (define_insn "*tldo_ldsw1_sp64"
7719 [(set (match_operand:DI 0 "register_operand" "=r")
7720 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7721 (match_operand 3 "tld_symbolic_operand" "")]
7723 (match_operand:DI 1 "register_operand" "r")))))]
7724 "TARGET_TLS && TARGET_ARCH64"
7725 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7726 [(set_attr "type" "sload")
7727 (set_attr "us3load_type" "3cycle")])
7729 (define_insn "*tldo_ldx_sp64"
7730 [(set (match_operand:DI 0 "register_operand" "=r")
7731 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7732 (match_operand 3 "tld_symbolic_operand" "")]
7734 (match_operand:DI 1 "register_operand" "r"))))]
7735 "TARGET_TLS && TARGET_ARCH64"
7736 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7737 [(set_attr "type" "load")])
7739 (define_insn "*tldo_stb_sp32"
7740 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7741 (match_operand 3 "tld_symbolic_operand" "")]
7743 (match_operand:SI 1 "register_operand" "r")))
7744 (match_operand:QI 0 "register_operand" "r"))]
7745 "TARGET_TLS && TARGET_ARCH32"
7746 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7747 [(set_attr "type" "store")])
7749 (define_insn "*tldo_stb_sp64"
7750 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7751 (match_operand 3 "tld_symbolic_operand" "")]
7753 (match_operand:DI 1 "register_operand" "r")))
7754 (match_operand:QI 0 "register_operand" "r"))]
7755 "TARGET_TLS && TARGET_ARCH64"
7756 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7757 [(set_attr "type" "store")])
7759 (define_insn "*tldo_sth_sp32"
7760 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7761 (match_operand 3 "tld_symbolic_operand" "")]
7763 (match_operand:SI 1 "register_operand" "r")))
7764 (match_operand:HI 0 "register_operand" "r"))]
7765 "TARGET_TLS && TARGET_ARCH32"
7766 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7767 [(set_attr "type" "store")])
7769 (define_insn "*tldo_sth_sp64"
7770 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7771 (match_operand 3 "tld_symbolic_operand" "")]
7773 (match_operand:DI 1 "register_operand" "r")))
7774 (match_operand:HI 0 "register_operand" "r"))]
7775 "TARGET_TLS && TARGET_ARCH64"
7776 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7777 [(set_attr "type" "store")])
7779 (define_insn "*tldo_stw_sp32"
7780 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7781 (match_operand 3 "tld_symbolic_operand" "")]
7783 (match_operand:SI 1 "register_operand" "r")))
7784 (match_operand:SI 0 "register_operand" "r"))]
7785 "TARGET_TLS && TARGET_ARCH32"
7786 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7787 [(set_attr "type" "store")])
7789 (define_insn "*tldo_stw_sp64"
7790 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7791 (match_operand 3 "tld_symbolic_operand" "")]
7793 (match_operand:DI 1 "register_operand" "r")))
7794 (match_operand:SI 0 "register_operand" "r"))]
7795 "TARGET_TLS && TARGET_ARCH64"
7796 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7797 [(set_attr "type" "store")])
7799 (define_insn "*tldo_stx_sp64"
7800 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7801 (match_operand 3 "tld_symbolic_operand" "")]
7803 (match_operand:DI 1 "register_operand" "r")))
7804 (match_operand:DI 0 "register_operand" "r"))]
7805 "TARGET_TLS && TARGET_ARCH64"
7806 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7807 [(set_attr "type" "store")])
7810 ;; Stack protector instructions.
7812 (define_expand "stack_protect_set"
7813 [(match_operand 0 "memory_operand" "")
7814 (match_operand 1 "memory_operand" "")]
7817 #ifdef TARGET_THREAD_SSP_OFFSET
7818 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7819 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7820 operands[1] = gen_rtx_MEM (Pmode, addr);
7823 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7825 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7829 (define_insn "stack_protect_setsi"
7830 [(set (match_operand:SI 0 "memory_operand" "=m")
7831 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7832 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7834 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7835 [(set_attr "type" "multi")
7836 (set_attr "length" "3")])
7838 (define_insn "stack_protect_setdi"
7839 [(set (match_operand:DI 0 "memory_operand" "=m")
7840 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7841 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7843 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7844 [(set_attr "type" "multi")
7845 (set_attr "length" "3")])
7847 (define_expand "stack_protect_test"
7848 [(match_operand 0 "memory_operand" "")
7849 (match_operand 1 "memory_operand" "")
7850 (match_operand 2 "" "")]
7854 #ifdef TARGET_THREAD_SSP_OFFSET
7855 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7856 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7857 operands[1] = gen_rtx_MEM (Pmode, addr);
7861 result = gen_reg_rtx (Pmode);
7862 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7863 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7864 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7868 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7869 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7870 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7871 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7876 (define_insn "stack_protect_testsi"
7877 [(set (reg:CC CC_REG)
7878 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7879 (match_operand:SI 1 "memory_operand" "m")]
7881 (set (match_scratch:SI 3 "=r") (const_int 0))
7882 (clobber (match_scratch:SI 2 "=&r"))]
7884 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7885 [(set_attr "type" "multi")
7886 (set_attr "length" "4")])
7888 (define_insn "stack_protect_testdi"
7889 [(set (match_operand:DI 0 "register_operand" "=&r")
7890 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7891 (match_operand:DI 2 "memory_operand" "m")]
7893 (set (match_scratch:DI 3 "=r") (const_int 0))]
7895 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7896 [(set_attr "type" "multi")
7897 (set_attr "length" "4")])
7899 ;; Vector instructions.
7901 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7902 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7903 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7905 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7906 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7907 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7908 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7909 (V1DI "double") (V2SI "double") (V4HI "double")
7912 (define_expand "mov<VMALL:mode>"
7913 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7914 (match_operand:VMALL 1 "general_operand" ""))]
7917 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7921 (define_insn "*mov<VM32:mode>_insn"
7922 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7923 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7925 && (register_operand (operands[0], <VM32:MODE>mode)
7926 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7939 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7940 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7942 (define_insn "*mov<VM64:mode>_insn_sp64"
7943 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7944 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7947 && (register_operand (operands[0], <VM64:MODE>mode)
7948 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7961 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7962 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7964 (define_insn "*mov<VM64:mode>_insn_sp32"
7965 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7966 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7969 && (register_operand (operands[0], <VM64:MODE>mode)
7970 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7984 [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
7985 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7986 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7989 [(set (match_operand:VM64 0 "memory_operand" "")
7990 (match_operand:VM64 1 "register_operand" ""))]
7994 && (((REGNO (operands[1]) % 2) != 0)
7995 || ! mem_min_alignment (operands[0], 8))
7996 && offsettable_memref_p (operands[0])"
7997 [(clobber (const_int 0))]
8001 word0 = adjust_address (operands[0], SImode, 0);
8002 word1 = adjust_address (operands[0], SImode, 4);
8004 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8005 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8010 [(set (match_operand:VM64 0 "register_operand" "")
8011 (match_operand:VM64 1 "register_operand" ""))]
8015 && sparc_split_regreg_legitimate (operands[0], operands[1])"
8016 [(clobber (const_int 0))]
8018 rtx set_dest = operands[0];
8019 rtx set_src = operands[1];
8023 dest1 = gen_highpart (SImode, set_dest);
8024 dest2 = gen_lowpart (SImode, set_dest);
8025 src1 = gen_highpart (SImode, set_src);
8026 src2 = gen_lowpart (SImode, set_src);
8028 /* Now emit using the real source and destination we found, swapping
8029 the order if we detect overlap. */
8030 if (reg_overlap_mentioned_p (dest1, src2))
8032 emit_insn (gen_movsi (dest2, src2));
8033 emit_insn (gen_movsi (dest1, src1));
8037 emit_insn (gen_movsi (dest1, src1));
8038 emit_insn (gen_movsi (dest2, src2));
8043 (define_expand "vec_init<mode>"
8044 [(match_operand:VMALL 0 "register_operand" "")
8045 (match_operand:VMALL 1 "" "")]
8048 sparc_expand_vector_init (operands[0], operands[1]);
8052 (define_code_iterator plusminus [plus minus])
8053 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8055 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8057 (define_insn "<plusminus_insn><mode>3"
8058 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8059 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8060 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8062 "fp<plusminus_insn><vbits>\t%1, %2, %0"
8063 [(set_attr "type" "fga")
8064 (set_attr "fptype" "<vfptype>")])
8066 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8067 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8068 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
8069 (define_code_iterator vlop [ior and xor])
8070 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8071 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8073 (define_insn "<code><mode>3"
8074 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8075 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8076 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8078 "f<vlinsn><vlsuf>\t%1, %2, %0"
8079 [(set_attr "type" "visl")
8080 (set_attr "fptype" "<vfptype>")])
8082 (define_insn "*not_<code><mode>3"
8083 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8084 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8085 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8087 "f<vlninsn><vlsuf>\t%1, %2, %0"
8088 [(set_attr "type" "visl")
8089 (set_attr "fptype" "<vfptype>")])
8091 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8092 (define_insn "*nand<mode>_vis"
8093 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8094 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8095 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8097 "fnand<vlsuf>\t%1, %2, %0"
8098 [(set_attr "type" "visl")
8099 (set_attr "fptype" "<vfptype>")])
8101 (define_code_iterator vlnotop [ior and])
8103 (define_insn "*<code>_not1<mode>_vis"
8104 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8105 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8106 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8108 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8109 [(set_attr "type" "visl")
8110 (set_attr "fptype" "<vfptype>")])
8112 (define_insn "*<code>_not2<mode>_vis"
8113 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8114 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8115 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8117 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8118 [(set_attr "type" "visl")
8119 (set_attr "fptype" "<vfptype>")])
8121 (define_insn "one_cmpl<mode>2"
8122 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8123 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8125 "fnot1<vlsuf>\t%1, %0"
8126 [(set_attr "type" "visl")
8127 (set_attr "fptype" "<vfptype>")])
8129 ;; Hard to generate VIS instructions. We have builtins for these.
8131 (define_insn "fpack16_vis"
8132 [(set (match_operand:V4QI 0 "register_operand" "=f")
8133 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8138 [(set_attr "type" "fgm_pack")
8139 (set_attr "fptype" "double")])
8141 (define_insn "fpackfix_vis"
8142 [(set (match_operand:V2HI 0 "register_operand" "=f")
8143 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8148 [(set_attr "type" "fgm_pack")
8149 (set_attr "fptype" "double")])
8151 (define_insn "fpack32_vis"
8152 [(set (match_operand:V8QI 0 "register_operand" "=e")
8153 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8154 (match_operand:V8QI 2 "register_operand" "e")
8158 "fpack32\t%1, %2, %0"
8159 [(set_attr "type" "fgm_pack")
8160 (set_attr "fptype" "double")])
8162 (define_insn "fexpand_vis"
8163 [(set (match_operand:V4HI 0 "register_operand" "=e")
8164 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8168 [(set_attr "type" "fga")
8169 (set_attr "fptype" "double")])
8171 (define_insn "fpmerge_vis"
8172 [(set (match_operand:V8QI 0 "register_operand" "=e")
8174 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8175 (match_operand:V4QI 2 "register_operand" "f"))
8176 (parallel [(const_int 0) (const_int 4)
8177 (const_int 1) (const_int 5)
8178 (const_int 2) (const_int 6)
8179 (const_int 3) (const_int 7)])))]
8181 "fpmerge\t%1, %2, %0"
8182 [(set_attr "type" "fga")
8183 (set_attr "fptype" "double")])
8185 (define_insn "vec_interleave_lowv8qi"
8186 [(set (match_operand:V8QI 0 "register_operand" "=e")
8188 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8189 (match_operand:V8QI 2 "register_operand" "f"))
8190 (parallel [(const_int 0) (const_int 8)
8191 (const_int 1) (const_int 9)
8192 (const_int 2) (const_int 10)
8193 (const_int 3) (const_int 11)])))]
8195 "fpmerge\t%L1, %L2, %0"
8196 [(set_attr "type" "fga")
8197 (set_attr "fptype" "double")])
8199 (define_insn "vec_interleave_highv8qi"
8200 [(set (match_operand:V8QI 0 "register_operand" "=e")
8202 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8203 (match_operand:V8QI 2 "register_operand" "f"))
8204 (parallel [(const_int 4) (const_int 12)
8205 (const_int 5) (const_int 13)
8206 (const_int 6) (const_int 14)
8207 (const_int 7) (const_int 15)])))]
8209 "fpmerge\t%H1, %H2, %0"
8210 [(set_attr "type" "fga")
8211 (set_attr "fptype" "double")])
8213 ;; Partitioned multiply instructions
8214 (define_insn "fmul8x16_vis"
8215 [(set (match_operand:V4HI 0 "register_operand" "=e")
8216 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8217 (match_operand:V4HI 2 "register_operand" "e")]
8220 "fmul8x16\t%1, %2, %0"
8221 [(set_attr "type" "fgm_mul")
8222 (set_attr "fptype" "double")])
8224 (define_insn "fmul8x16au_vis"
8225 [(set (match_operand:V4HI 0 "register_operand" "=e")
8226 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8227 (match_operand:V2HI 2 "register_operand" "f")]
8230 "fmul8x16au\t%1, %2, %0"
8231 [(set_attr "type" "fgm_mul")
8232 (set_attr "fptype" "double")])
8234 (define_insn "fmul8x16al_vis"
8235 [(set (match_operand:V4HI 0 "register_operand" "=e")
8236 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8237 (match_operand:V2HI 2 "register_operand" "f")]
8240 "fmul8x16al\t%1, %2, %0"
8241 [(set_attr "type" "fgm_mul")
8242 (set_attr "fptype" "double")])
8244 (define_insn "fmul8sux16_vis"
8245 [(set (match_operand:V4HI 0 "register_operand" "=e")
8246 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8247 (match_operand:V4HI 2 "register_operand" "e")]
8250 "fmul8sux16\t%1, %2, %0"
8251 [(set_attr "type" "fgm_mul")
8252 (set_attr "fptype" "double")])
8254 (define_insn "fmul8ulx16_vis"
8255 [(set (match_operand:V4HI 0 "register_operand" "=e")
8256 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8257 (match_operand:V4HI 2 "register_operand" "e")]
8260 "fmul8ulx16\t%1, %2, %0"
8261 [(set_attr "type" "fgm_mul")
8262 (set_attr "fptype" "double")])
8264 (define_insn "fmuld8sux16_vis"
8265 [(set (match_operand:V2SI 0 "register_operand" "=e")
8266 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8267 (match_operand:V2HI 2 "register_operand" "f")]
8270 "fmuld8sux16\t%1, %2, %0"
8271 [(set_attr "type" "fgm_mul")
8272 (set_attr "fptype" "double")])
8274 (define_insn "fmuld8ulx16_vis"
8275 [(set (match_operand:V2SI 0 "register_operand" "=e")
8276 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8277 (match_operand:V2HI 2 "register_operand" "f")]
8280 "fmuld8ulx16\t%1, %2, %0"
8281 [(set_attr "type" "fgm_mul")
8282 (set_attr "fptype" "double")])
8284 (define_expand "wrgsr_vis"
8285 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8288 if (! TARGET_ARCH64)
8290 emit_insn (gen_wrgsr_v8plus (operands[0]));
8295 (define_insn "*wrgsr_sp64"
8296 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8297 "TARGET_VIS && TARGET_ARCH64"
8298 "wr\t%%g0, %0, %%gsr"
8299 [(set_attr "type" "gsr")])
8301 (define_insn "wrgsr_v8plus"
8302 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8303 (clobber (match_scratch:SI 1 "=X,&h"))]
8304 "TARGET_VIS && ! TARGET_ARCH64"
8306 if (GET_CODE (operands[0]) == CONST_INT
8307 || sparc_check_64 (operands[0], insn))
8308 return "wr\t%%g0, %0, %%gsr";
8310 output_asm_insn("srl\t%L0, 0, %L0", operands);
8311 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8313 [(set_attr "type" "multi")])
8315 (define_expand "rdgsr_vis"
8316 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8319 if (! TARGET_ARCH64)
8321 emit_insn (gen_rdgsr_v8plus (operands[0]));
8326 (define_insn "*rdgsr_sp64"
8327 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8328 "TARGET_VIS && TARGET_ARCH64"
8330 [(set_attr "type" "gsr")])
8332 (define_insn "rdgsr_v8plus"
8333 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8334 (clobber (match_scratch:SI 1 "=&h"))]
8335 "TARGET_VIS && ! TARGET_ARCH64"
8337 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8339 [(set_attr "type" "multi")])
8341 ;; Using faligndata only makes sense after an alignaddr since the choice of
8342 ;; bytes to take out of each operand is dependent on the results of the last
8344 (define_insn "faligndata<VM64:mode>_vis"
8345 [(set (match_operand:VM64 0 "register_operand" "=e")
8346 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8347 (match_operand:VM64 2 "register_operand" "e")
8351 "faligndata\t%1, %2, %0"
8352 [(set_attr "type" "fga")
8353 (set_attr "fptype" "double")])
8355 (define_insn "alignaddrsi_vis"
8356 [(set (match_operand:SI 0 "register_operand" "=r")
8357 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8358 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8359 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8360 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8362 "alignaddr\t%r1, %r2, %0"
8363 [(set_attr "type" "gsr")])
8365 (define_insn "alignaddrdi_vis"
8366 [(set (match_operand:DI 0 "register_operand" "=r")
8367 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8368 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8369 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8370 (plus:DI (match_dup 1) (match_dup 2)))]
8372 "alignaddr\t%r1, %r2, %0"
8373 [(set_attr "type" "gsr")])
8375 (define_insn "alignaddrlsi_vis"
8376 [(set (match_operand:SI 0 "register_operand" "=r")
8377 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8378 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8379 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8380 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8383 "alignaddrl\t%r1, %r2, %0"
8384 [(set_attr "type" "gsr")])
8386 (define_insn "alignaddrldi_vis"
8387 [(set (match_operand:DI 0 "register_operand" "=r")
8388 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8389 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8390 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8391 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8394 "alignaddrl\t%r1, %r2, %0"
8395 [(set_attr "type" "gsr")])
8397 (define_insn "pdist_vis"
8398 [(set (match_operand:DI 0 "register_operand" "=e")
8399 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8400 (match_operand:V8QI 2 "register_operand" "e")
8401 (match_operand:DI 3 "register_operand" "0")]
8405 [(set_attr "type" "pdist")
8406 (set_attr "fptype" "double")])
8408 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8409 ;; with the same operands.
8410 (define_insn "edge8<P:mode>_vis"
8411 [(set (reg:CC_NOOV CC_REG)
8412 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8413 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8415 (set (match_operand:P 0 "register_operand" "=r")
8416 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8418 "edge8\t%r1, %r2, %0"
8419 [(set_attr "type" "edge")])
8421 (define_insn "edge8l<P:mode>_vis"
8422 [(set (reg:CC_NOOV CC_REG)
8423 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8424 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8426 (set (match_operand:P 0 "register_operand" "=r")
8427 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8429 "edge8l\t%r1, %r2, %0"
8430 [(set_attr "type" "edge")])
8432 (define_insn "edge16<P:mode>_vis"
8433 [(set (reg:CC_NOOV CC_REG)
8434 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8435 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8437 (set (match_operand:P 0 "register_operand" "=r")
8438 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8440 "edge16\t%r1, %r2, %0"
8441 [(set_attr "type" "edge")])
8443 (define_insn "edge16l<P:mode>_vis"
8444 [(set (reg:CC_NOOV CC_REG)
8445 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8446 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8448 (set (match_operand:P 0 "register_operand" "=r")
8449 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8451 "edge16l\t%r1, %r2, %0"
8452 [(set_attr "type" "edge")])
8454 (define_insn "edge32<P:mode>_vis"
8455 [(set (reg:CC_NOOV CC_REG)
8456 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8457 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8459 (set (match_operand:P 0 "register_operand" "=r")
8460 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8462 "edge32\t%r1, %r2, %0"
8463 [(set_attr "type" "edge")])
8465 (define_insn "edge32l<P:mode>_vis"
8466 [(set (reg:CC_NOOV CC_REG)
8467 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8468 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8470 (set (match_operand:P 0 "register_operand" "=r")
8471 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8473 "edge32l\t%r1, %r2, %0"
8474 [(set_attr "type" "edge")])
8476 (define_code_iterator gcond [le ne gt eq])
8477 (define_mode_iterator GCM [V4HI V2SI])
8478 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8480 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8481 [(set (match_operand:P 0 "register_operand" "=r")
8482 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8483 (match_operand:GCM 2 "register_operand" "e"))]
8486 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8487 [(set_attr "type" "visl")
8488 (set_attr "fptype" "double")])
8490 (define_expand "vcond<mode><mode>"
8491 [(match_operand:GCM 0 "register_operand" "")
8492 (match_operand:GCM 1 "register_operand" "")
8493 (match_operand:GCM 2 "register_operand" "")
8494 (match_operator 3 ""
8495 [(match_operand:GCM 4 "register_operand" "")
8496 (match_operand:GCM 5 "register_operand" "")])]
8499 sparc_expand_vcond (<MODE>mode, operands,
8500 UNSPEC_CMASK<gcm_name>,
8505 (define_expand "vconduv8qiv8qi"
8506 [(match_operand:V8QI 0 "register_operand" "")
8507 (match_operand:V8QI 1 "register_operand" "")
8508 (match_operand:V8QI 2 "register_operand" "")
8509 (match_operator 3 ""
8510 [(match_operand:V8QI 4 "register_operand" "")
8511 (match_operand:V8QI 5 "register_operand" "")])]
8514 sparc_expand_vcond (V8QImode, operands,
8520 (define_insn "array8<P:mode>_vis"
8521 [(set (match_operand:P 0 "register_operand" "=r")
8522 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8523 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8526 "array8\t%r1, %r2, %0"
8527 [(set_attr "type" "array")])
8529 (define_insn "array16<P:mode>_vis"
8530 [(set (match_operand:P 0 "register_operand" "=r")
8531 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8532 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8535 "array16\t%r1, %r2, %0"
8536 [(set_attr "type" "array")])
8538 (define_insn "array32<P:mode>_vis"
8539 [(set (match_operand:P 0 "register_operand" "=r")
8540 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8541 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8544 "array32\t%r1, %r2, %0"
8545 [(set_attr "type" "array")])
8547 (define_insn "bmaskdi_vis"
8548 [(set (match_operand:DI 0 "register_operand" "=r")
8549 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8550 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8551 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8552 (plus:DI (match_dup 1) (match_dup 2)))]
8554 "bmask\t%r1, %r2, %0"
8555 [(set_attr "type" "array")])
8557 (define_insn "bmasksi_vis"
8558 [(set (match_operand:SI 0 "register_operand" "=r")
8559 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8560 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8561 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8562 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8564 "bmask\t%r1, %r2, %0"
8565 [(set_attr "type" "array")])
8567 (define_insn "bshuffle<VM64:mode>_vis"
8568 [(set (match_operand:VM64 0 "register_operand" "=e")
8569 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8570 (match_operand:VM64 2 "register_operand" "e")
8574 "bshuffle\t%1, %2, %0"
8575 [(set_attr "type" "fga")
8576 (set_attr "fptype" "double")])
8578 ;; The rtl expanders will happily convert constant permutations on other
8579 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8580 ;; order of the permutation.
8581 (define_expand "vec_perm_constv8qi"
8582 [(match_operand:V8QI 0 "register_operand" "")
8583 (match_operand:V8QI 1 "register_operand" "")
8584 (match_operand:V8QI 2 "register_operand" "")
8585 (match_operand:V8QI 3 "" "")]
8588 unsigned int i, mask;
8589 rtx sel = operands[3];
8591 for (i = mask = 0; i < 8; ++i)
8592 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8593 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8595 emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8596 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8600 ;; Unlike constant permutation, we can vastly simplify the compression of
8601 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8602 ;; width of the input is.
8603 (define_expand "vec_perm<mode>"
8604 [(match_operand:VM64 0 "register_operand" "")
8605 (match_operand:VM64 1 "register_operand" "")
8606 (match_operand:VM64 2 "register_operand" "")
8607 (match_operand:VM64 3 "register_operand" "")]
8610 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8611 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8615 ;; VIS 2.0 adds edge variants which do not set the condition codes
8616 (define_insn "edge8n<P:mode>_vis"
8617 [(set (match_operand:P 0 "register_operand" "=r")
8618 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8619 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8622 "edge8n\t%r1, %r2, %0"
8623 [(set_attr "type" "edgen")])
8625 (define_insn "edge8ln<P:mode>_vis"
8626 [(set (match_operand:P 0 "register_operand" "=r")
8627 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8628 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8631 "edge8ln\t%r1, %r2, %0"
8632 [(set_attr "type" "edgen")])
8634 (define_insn "edge16n<P:mode>_vis"
8635 [(set (match_operand:P 0 "register_operand" "=r")
8636 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8637 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8640 "edge16n\t%r1, %r2, %0"
8641 [(set_attr "type" "edgen")])
8643 (define_insn "edge16ln<P:mode>_vis"
8644 [(set (match_operand:P 0 "register_operand" "=r")
8645 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8646 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8649 "edge16ln\t%r1, %r2, %0"
8650 [(set_attr "type" "edgen")])
8652 (define_insn "edge32n<P:mode>_vis"
8653 [(set (match_operand:P 0 "register_operand" "=r")
8654 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8655 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8658 "edge32n\t%r1, %r2, %0"
8659 [(set_attr "type" "edgen")])
8661 (define_insn "edge32ln<P:mode>_vis"
8662 [(set (match_operand:P 0 "register_operand" "=r")
8663 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8664 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8667 "edge32ln\t%r1, %r2, %0"
8668 [(set_attr "type" "edge")])
8670 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8671 (define_insn "cmask8<P:mode>_vis"
8672 [(set (reg:DI GSR_REG)
8673 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8678 [(set_attr "type" "fga")])
8680 (define_insn "cmask16<P:mode>_vis"
8681 [(set (reg:DI GSR_REG)
8682 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8687 [(set_attr "type" "fga")])
8689 (define_insn "cmask32<P:mode>_vis"
8690 [(set (reg:DI GSR_REG)
8691 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8696 [(set_attr "type" "fga")])
8698 (define_insn "fchksm16_vis"
8699 [(set (match_operand:V4HI 0 "register_operand" "=e")
8700 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8701 (match_operand:V4HI 2 "register_operand" "e")]
8704 "fchksm16\t%1, %2, %0"
8705 [(set_attr "type" "fga")])
8707 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8708 (define_code_attr vis3_shift_insn
8709 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8710 (define_code_attr vis3_shift_patname
8711 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8713 (define_insn "v<vis3_shift_patname><mode>3"
8714 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8715 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8716 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8718 "<vis3_shift_insn><vbits>\t%1, %2, %0"
8719 [(set_attr "type" "fga")])
8721 (define_insn "pdistn<mode>_vis"
8722 [(set (match_operand:P 0 "register_operand" "=r")
8723 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8724 (match_operand:V8QI 2 "register_operand" "e")]
8727 "pdistn\t%1, %2, %0"
8728 [(set_attr "type" "pdistn")
8729 (set_attr "fptype" "double")])
8731 (define_insn "fmean16_vis"
8732 [(set (match_operand:V4HI 0 "register_operand" "=e")
8738 (match_operand:V4HI 1 "register_operand" "e"))
8740 (match_operand:V4HI 2 "register_operand" "e")))
8741 (const_vector:V4SI [(const_int 1) (const_int 1)
8742 (const_int 1) (const_int 1)]))
8745 "fmean16\t%1, %2, %0"
8746 [(set_attr "type" "fga")])
8748 (define_insn "fp<plusminus_insn>64_vis"
8749 [(set (match_operand:V1DI 0 "register_operand" "=e")
8750 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8751 (match_operand:V1DI 2 "register_operand" "e")))]
8753 "fp<plusminus_insn>64\t%1, %2, %0"
8754 [(set_attr "type" "fga")])
8756 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8757 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8758 (define_code_attr vis3_addsub_ss_insn
8759 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8760 (define_code_attr vis3_addsub_ss_patname
8761 [(ss_plus "ssadd") (ss_minus "sssub")])
8763 (define_insn "<vis3_addsub_ss_patname><mode>3"
8764 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8765 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8766 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8768 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8769 [(set_attr "type" "fga")])
8771 (define_insn "fucmp<code>8<P:mode>_vis"
8772 [(set (match_operand:P 0 "register_operand" "=r")
8773 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8774 (match_operand:V8QI 2 "register_operand" "e"))]
8777 "fucmp<code>8\t%1, %2, %0"
8778 [(set_attr "type" "visl")])
8780 (define_insn "*naddsf3"
8781 [(set (match_operand:SF 0 "register_operand" "=f")
8782 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8783 (match_operand:SF 2 "register_operand" "f"))))]
8785 "fnadds\t%1, %2, %0"
8786 [(set_attr "type" "fp")])
8788 (define_insn "*nadddf3"
8789 [(set (match_operand:DF 0 "register_operand" "=e")
8790 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8791 (match_operand:DF 2 "register_operand" "e"))))]
8793 "fnaddd\t%1, %2, %0"
8794 [(set_attr "type" "fp")
8795 (set_attr "fptype" "double")])
8797 (define_insn "*nmulsf3"
8798 [(set (match_operand:SF 0 "register_operand" "=f")
8799 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8800 (match_operand:SF 2 "register_operand" "f")))]
8802 "fnmuls\t%1, %2, %0"
8803 [(set_attr "type" "fpmul")])
8805 (define_insn "*nmuldf3"
8806 [(set (match_operand:DF 0 "register_operand" "=e")
8807 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8808 (match_operand:DF 2 "register_operand" "e")))]
8810 "fnmuld\t%1, %2, %0"
8811 [(set_attr "type" "fpmul")
8812 (set_attr "fptype" "double")])
8814 (define_insn "*nmuldf3_extend"
8815 [(set (match_operand:DF 0 "register_operand" "=e")
8816 (mult:DF (neg:DF (float_extend:DF
8817 (match_operand:SF 1 "register_operand" "f")))
8819 (match_operand:SF 2 "register_operand" "f"))))]
8821 "fnsmuld\t%1, %2, %0"
8822 [(set_attr "type" "fpmul")
8823 (set_attr "fptype" "double")])
8825 (define_insn "fhaddsf_vis"
8826 [(set (match_operand:SF 0 "register_operand" "=f")
8827 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8828 (match_operand:SF 2 "register_operand" "f")]
8831 "fhadds\t%1, %2, %0"
8832 [(set_attr "type" "fp")])
8834 (define_insn "fhadddf_vis"
8835 [(set (match_operand:DF 0 "register_operand" "=f")
8836 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8837 (match_operand:DF 2 "register_operand" "f")]
8840 "fhaddd\t%1, %2, %0"
8841 [(set_attr "type" "fp")
8842 (set_attr "fptype" "double")])
8844 (define_insn "fhsubsf_vis"
8845 [(set (match_operand:SF 0 "register_operand" "=f")
8846 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8847 (match_operand:SF 2 "register_operand" "f")]
8850 "fhsubs\t%1, %2, %0"
8851 [(set_attr "type" "fp")])
8853 (define_insn "fhsubdf_vis"
8854 [(set (match_operand:DF 0 "register_operand" "=f")
8855 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8856 (match_operand:DF 2 "register_operand" "f")]
8859 "fhsubd\t%1, %2, %0"
8860 [(set_attr "type" "fp")
8861 (set_attr "fptype" "double")])
8863 (define_insn "fnhaddsf_vis"
8864 [(set (match_operand:SF 0 "register_operand" "=f")
8865 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8866 (match_operand:SF 2 "register_operand" "f")]
8869 "fnhadds\t%1, %2, %0"
8870 [(set_attr "type" "fp")])
8872 (define_insn "fnhadddf_vis"
8873 [(set (match_operand:DF 0 "register_operand" "=f")
8874 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8875 (match_operand:DF 2 "register_operand" "f")]
8878 "fnhaddd\t%1, %2, %0"
8879 [(set_attr "type" "fp")
8880 (set_attr "fptype" "double")])
8882 (define_expand "umulxhi_vis"
8883 [(set (match_operand:DI 0 "register_operand" "")
8886 (mult:TI (zero_extend:TI
8887 (match_operand:DI 1 "arith_operand" ""))
8889 (match_operand:DI 2 "arith_operand" "")))
8893 if (! TARGET_ARCH64)
8895 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8900 (define_insn "*umulxhi_sp64"
8901 [(set (match_operand:DI 0 "register_operand" "=r")
8904 (mult:TI (zero_extend:TI
8905 (match_operand:DI 1 "arith_operand" "%r"))
8907 (match_operand:DI 2 "arith_operand" "rI")))
8909 "TARGET_VIS3 && TARGET_ARCH64"
8910 "umulxhi\t%1, %2, %0"
8911 [(set_attr "type" "imul")])
8913 (define_insn "umulxhi_v8plus"
8914 [(set (match_operand:DI 0 "register_operand" "=r,h")
8917 (mult:TI (zero_extend:TI
8918 (match_operand:DI 1 "arith_operand" "%r,0"))
8920 (match_operand:DI 2 "arith_operand" "rI,rI")))
8922 (clobber (match_scratch:SI 3 "=&h,X"))
8923 (clobber (match_scratch:SI 4 "=&h,X"))]
8924 "TARGET_VIS3 && ! TARGET_ARCH64"
8925 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8926 [(set_attr "type" "imul")
8927 (set_attr "length" "9,8")])
8929 (define_expand "xmulx_vis"
8930 [(set (match_operand:DI 0 "register_operand" "")
8932 (unspec:TI [(zero_extend:TI
8933 (match_operand:DI 1 "arith_operand" ""))
8935 (match_operand:DI 2 "arith_operand" ""))]
8939 if (! TARGET_ARCH64)
8941 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8946 (define_insn "*xmulx_sp64"
8947 [(set (match_operand:DI 0 "register_operand" "=r")
8949 (unspec:TI [(zero_extend:TI
8950 (match_operand:DI 1 "arith_operand" "%r"))
8952 (match_operand:DI 2 "arith_operand" "rI"))]
8954 "TARGET_VIS3 && TARGET_ARCH64"
8956 [(set_attr "type" "imul")])
8958 (define_insn "xmulx_v8plus"
8959 [(set (match_operand:DI 0 "register_operand" "=r,h")
8961 (unspec:TI [(zero_extend:TI
8962 (match_operand:DI 1 "arith_operand" "%r,0"))
8964 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8966 (clobber (match_scratch:SI 3 "=&h,X"))
8967 (clobber (match_scratch:SI 4 "=&h,X"))]
8968 "TARGET_VIS3 && ! TARGET_ARCH64"
8969 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8970 [(set_attr "type" "imul")
8971 (set_attr "length" "9,8")])
8973 (define_expand "xmulxhi_vis"
8974 [(set (match_operand:DI 0 "register_operand" "")
8977 (unspec:TI [(zero_extend:TI
8978 (match_operand:DI 1 "arith_operand" ""))
8980 (match_operand:DI 2 "arith_operand" ""))]
8985 if (! TARGET_ARCH64)
8987 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8992 (define_insn "*xmulxhi_sp64"
8993 [(set (match_operand:DI 0 "register_operand" "=r")
8996 (unspec:TI [(zero_extend:TI
8997 (match_operand:DI 1 "arith_operand" "%r"))
8999 (match_operand:DI 2 "arith_operand" "rI"))]
9002 "TARGET_VIS3 && TARGET_ARCH64"
9003 "xmulxhi\t%1, %2, %0"
9004 [(set_attr "type" "imul")])
9006 (define_insn "xmulxhi_v8plus"
9007 [(set (match_operand:DI 0 "register_operand" "=r,h")
9010 (unspec:TI [(zero_extend:TI
9011 (match_operand:DI 1 "arith_operand" "%r,0"))
9013 (match_operand:DI 2 "arith_operand" "rI,rI"))]
9016 (clobber (match_scratch:SI 3 "=&h,X"))
9017 (clobber (match_scratch:SI 4 "=&h,X"))]
9018 "TARGET_VIS3 && !TARGET_ARCH64"
9019 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9020 [(set_attr "type" "imul")
9021 (set_attr "length" "9,8")])