816 dstenc -= 8;
817 }
818
819 emit_opcode(cbuf, 0x8B);
820 emit_rm(cbuf, 0x3, dstenc, srcenc);
821 }
822 }
823
824 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
825 if( dst_encoding == src_encoding ) {
826 // reg-reg copy, use an empty encoding
827 } else {
828 MacroAssembler _masm(&cbuf);
829
830 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
831 }
832 }
833
834
835 //=============================================================================
836 #ifndef PRODUCT
837 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
838 {
839 Compile* C = ra_->C;
840
841 int framesize = C->frame_slots() << LogBytesPerInt;
842 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
843 // Remove wordSize for return adr already pushed
844 // and another for the RBP we are going to save
845 framesize -= 2*wordSize;
846 bool need_nop = true;
847
848 // Calls to C2R adapters often do not accept exceptional returns.
849 // We require that their callers must bang for them. But be
850 // careful, because some VM calls (such as call site linkage) can
851 // use several kilobytes of stack. But the stack safety zone should
852 // account for that. See bugs 4446381, 4468289, 4497237.
853 if (C->need_stack_bang(framesize)) {
854 st->print_cr("# stack bang"); st->print("\t");
855 need_nop = false;
1905 address base =
1906 __ start_a_stub(size_deopt_handler());
1907 if (base == NULL) return 0; // CodeBuffer::expand failed
1908 int offset = __ offset();
1909 address the_pc = (address) __ pc();
1910 Label next;
1911 // push a "the_pc" on the stack without destroying any registers
1912 // as they all may be live.
1913
1914 // push address of "next"
1915 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1916 __ bind(next);
1917 // adjust it so it matches "the_pc"
1918 __ subptr(Address(rsp, 0), __ offset() - offset);
1919 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1920 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1921 __ end_a_stub();
1922 return offset;
1923 }
1924
1925 static void emit_double_constant(CodeBuffer& cbuf, double x) {
1926 int mark = cbuf.insts()->mark_off();
1927 MacroAssembler _masm(&cbuf);
1928 address double_address = __ double_constant(x);
1929 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1930 emit_d32_reloc(cbuf,
1931 (int) (double_address - cbuf.insts_end() - 4),
1932 internal_word_Relocation::spec(double_address),
1933 RELOC_DISP32);
1934 }
1935
1936 static void emit_float_constant(CodeBuffer& cbuf, float x) {
1937 int mark = cbuf.insts()->mark_off();
1938 MacroAssembler _masm(&cbuf);
1939 address float_address = __ float_constant(x);
1940 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1941 emit_d32_reloc(cbuf,
1942 (int) (float_address - cbuf.insts_end() - 4),
1943 internal_word_Relocation::spec(float_address),
1944 RELOC_DISP32);
1945 }
1946
1947
1948 const bool Matcher::match_rule_supported(int opcode) {
1949 if (!has_match_rule(opcode))
1950 return false;
1951
1952 return true; // Per default match rules are supported.
1953 }
1954
1955 int Matcher::regnum_to_fpu_offset(int regnum)
1956 {
1957 return regnum - 32; // The FP registers are in the second chunk
1958 }
1959
1960 // This is UltraSparc specific, true just means we have fast l2f conversion
1961 const bool Matcher::convL2FSupported(void) {
1962 return true;
1963 }
1964
1965 // Vector width in bytes
1966 const uint Matcher::vector_width_in_bytes(void) {
2772 %}
2773
2774 enc_class load_immP(rRegP dst, immP src)
2775 %{
2776 int dstenc = $dst$$reg;
2777 if (dstenc < 8) {
2778 emit_opcode(cbuf, Assembler::REX_W);
2779 } else {
2780 emit_opcode(cbuf, Assembler::REX_WB);
2781 dstenc -= 8;
2782 }
2783 emit_opcode(cbuf, 0xB8 | dstenc);
2784 // This next line should be generated from ADLC
2785 if ($src->constant_is_oop()) {
2786 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2787 } else {
2788 emit_d64(cbuf, $src$$constant);
2789 }
2790 %}
2791
2792 enc_class load_immF(regF dst, immF con)
2793 %{
2794 // XXX reg_mem doesn't support RIP-relative addressing yet
2795 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2796 emit_float_constant(cbuf, $con$$constant);
2797 %}
2798
2799 enc_class load_immD(regD dst, immD con)
2800 %{
2801 // XXX reg_mem doesn't support RIP-relative addressing yet
2802 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2803 emit_double_constant(cbuf, $con$$constant);
2804 %}
2805
2806 enc_class load_conF (regF dst, immF con) %{ // Load float constant
2807 emit_opcode(cbuf, 0xF3);
2808 if ($dst$$reg >= 8) {
2809 emit_opcode(cbuf, Assembler::REX_R);
2810 }
2811 emit_opcode(cbuf, 0x0F);
2812 emit_opcode(cbuf, 0x10);
2813 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2814 emit_float_constant(cbuf, $con$$constant);
2815 %}
2816
2817 enc_class load_conD (regD dst, immD con) %{ // Load double constant
2818 // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
2819 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
2820 if ($dst$$reg >= 8) {
2821 emit_opcode(cbuf, Assembler::REX_R);
2822 }
2823 emit_opcode(cbuf, 0x0F);
2824 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
2825 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2826 emit_double_constant(cbuf, $con$$constant);
2827 %}
2828
2829 // Encode a reg-reg copy. If it is useless, then empty encoding.
2830 enc_class enc_copy(rRegI dst, rRegI src)
2831 %{
2832 encode_copy(cbuf, $dst$$reg, $src$$reg);
2833 %}
2834
2835 // Encode xmm reg-reg copy. If it is useless, then empty encoding.
2836 enc_class enc_CopyXD( RegD dst, RegD src ) %{
2837 encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
2838 %}
2839
2840 enc_class enc_copy_always(rRegI dst, rRegI src)
2841 %{
2842 int srcenc = $src$$reg;
2843 int dstenc = $dst$$reg;
2844
2845 if (dstenc < 8) {
2846 if (srcenc >= 8) {
2847 emit_opcode(cbuf, Assembler::REX_B);
2848 srcenc -= 8;
2909 %}
2910
2911 enc_class Con16(immI src)
2912 %{
2913 // Output immediate
2914 $$$emit16$src$$constant;
2915 %}
2916
2917 // How is this different from Con32??? XXX
2918 enc_class Con_d32(immI src)
2919 %{
2920 emit_d32(cbuf,$src$$constant);
2921 %}
2922
2923 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2924 // Output immediate memory reference
2925 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2926 emit_d32(cbuf, 0x00);
2927 %}
2928
2929 enc_class jump_enc(rRegL switch_val, rRegI dest) %{
2930 MacroAssembler masm(&cbuf);
2931
2932 Register switch_reg = as_Register($switch_val$$reg);
2933 Register dest_reg = as_Register($dest$$reg);
2934 address table_base = masm.address_table_constant(_index2label);
2935
2936 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2937 // to do that and the compiler is using that register as one it can allocate.
2938 // So we build it all by hand.
2939 // Address index(noreg, switch_reg, Address::times_1);
2940 // ArrayAddress dispatch(table, index);
2941
2942 Address dispatch(dest_reg, switch_reg, Address::times_1);
2943
2944 masm.lea(dest_reg, InternalAddress(table_base));
2945 masm.jmp(dispatch);
2946 %}
2947
2948 enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
2949 MacroAssembler masm(&cbuf);
2950
2951 Register switch_reg = as_Register($switch_val$$reg);
2952 Register dest_reg = as_Register($dest$$reg);
2953 address table_base = masm.address_table_constant(_index2label);
2954
2955 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2956 // to do that and the compiler is using that register as one it can allocate.
2957 // So we build it all by hand.
2958 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2959 // ArrayAddress dispatch(table, index);
2960
2961 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2962
2963 masm.lea(dest_reg, InternalAddress(table_base));
2964 masm.jmp(dispatch);
2965 %}
2966
2967 enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
2968 MacroAssembler masm(&cbuf);
2969
2970 Register switch_reg = as_Register($switch_val$$reg);
2971 Register dest_reg = as_Register($dest$$reg);
2972 address table_base = masm.address_table_constant(_index2label);
2973
2974 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2975 // to do that and the compiler is using that register as one it can allocate.
2976 // So we build it all by hand.
2977 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2978 // ArrayAddress dispatch(table, index);
2979
2980 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2981 masm.lea(dest_reg, InternalAddress(table_base));
2982 masm.jmp(dispatch);
2983
2984 %}
2985
2986 enc_class lock_prefix()
2987 %{
2988 if (os::is_MP()) {
2989 emit_opcode(cbuf, 0xF0); // lock
2990 }
2991 %}
2992
2993 enc_class REX_mem(memory mem)
2994 %{
2995 if ($mem$$base >= 8) {
2996 if ($mem$$index < 8) {
2997 emit_opcode(cbuf, Assembler::REX_B);
2998 } else {
2999 emit_opcode(cbuf, Assembler::REX_XB);
3000 }
3001 } else {
3002 if ($mem$$index >= 8) {
3003 emit_opcode(cbuf, Assembler::REX_X);
3004 }
3005 }
6624 instruct loadConUL32(rRegL dst, immUL32 src)
6625 %{
6626 match(Set dst src);
6627
6628 ins_cost(60);
6629 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
6630 ins_encode(load_immUL32(dst, src));
6631 ins_pipe(ialu_reg);
6632 %}
6633
6634 instruct loadConL32(rRegL dst, immL32 src)
6635 %{
6636 match(Set dst src);
6637
6638 ins_cost(70);
6639 format %{ "movq $dst, $src\t# long (32-bit)" %}
6640 ins_encode(load_immL32(dst, src));
6641 ins_pipe(ialu_reg);
6642 %}
6643
6644 instruct loadConP(rRegP dst, immP src)
6645 %{
6646 match(Set dst src);
6647
6648 format %{ "movq $dst, $src\t# ptr" %}
6649 ins_encode(load_immP(dst, src));
6650 ins_pipe(ialu_reg_fat); // XXX
6651 %}
6652
6653 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
6654 %{
6655 match(Set dst src);
6656 effect(KILL cr);
6657
6658 ins_cost(50);
6659 format %{ "xorl $dst, $dst\t# ptr" %}
6660 opcode(0x33); /* + rd */
6661 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6662 ins_pipe(ialu_reg);
6663 %}
6664
6665 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
6666 %{
6667 match(Set dst src);
6668 effect(KILL cr);
6669
6670 ins_cost(60);
6671 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
6672 ins_encode(load_immP31(dst, src));
6673 ins_pipe(ialu_reg);
6674 %}
6675
6676 instruct loadConF(regF dst, immF src)
6677 %{
6678 match(Set dst src);
6679 ins_cost(125);
6680
6681 format %{ "movss $dst, [$src]" %}
6682 ins_encode(load_conF(dst, src));
6683 ins_pipe(pipe_slow);
6684 %}
6685
6686 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6687 match(Set dst src);
6688 effect(KILL cr);
6689 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
6690 ins_encode %{
6691 __ xorq($dst$$Register, $dst$$Register);
6692 %}
6693 ins_pipe(ialu_reg);
6694 %}
6695
6696 instruct loadConN(rRegN dst, immN src) %{
6697 match(Set dst src);
6698
6699 ins_cost(125);
6700 format %{ "movl $dst, $src\t# compressed ptr" %}
6701 ins_encode %{
6702 address con = (address)$src$$constant;
6704 ShouldNotReachHere();
6705 } else {
6706 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
6707 }
6708 %}
6709 ins_pipe(ialu_reg_fat); // XXX
6710 %}
6711
6712 instruct loadConF0(regF dst, immF0 src)
6713 %{
6714 match(Set dst src);
6715 ins_cost(100);
6716
6717 format %{ "xorps $dst, $dst\t# float 0.0" %}
6718 opcode(0x0F, 0x57);
6719 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
6720 ins_pipe(pipe_slow);
6721 %}
6722
6723 // Use the same format since predicate() can not be used here.
6724 instruct loadConD(regD dst, immD src)
6725 %{
6726 match(Set dst src);
6727 ins_cost(125);
6728
6729 format %{ "movsd $dst, [$src]" %}
6730 ins_encode(load_conD(dst, src));
6731 ins_pipe(pipe_slow);
6732 %}
6733
6734 instruct loadConD0(regD dst, immD0 src)
6735 %{
6736 match(Set dst src);
6737 ins_cost(100);
6738
6739 format %{ "xorpd $dst, $dst\t# double 0.0" %}
6740 opcode(0x66, 0x0F, 0x57);
6741 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst));
6742 ins_pipe(pipe_slow);
6743 %}
6744
6745 instruct loadSSI(rRegI dst, stackSlotI src)
6746 %{
6747 match(Set dst src);
6748
6749 ins_cost(125);
6750 format %{ "movl $dst, $src\t# int stk" %}
7677 Register d = $dst$$Register;
7678 if (s != d) {
7679 __ decode_heap_oop_not_null(d, s);
7680 } else {
7681 __ decode_heap_oop_not_null(d);
7682 }
7683 %}
7684 ins_pipe(ialu_reg_long);
7685 %}
7686
7687
7688 //----------Conditional Move---------------------------------------------------
7689 // Jump
7690 // dummy instruction for generating temp registers
7691 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
7692 match(Jump (LShiftL switch_val shift));
7693 ins_cost(350);
7694 predicate(false);
7695 effect(TEMP dest);
7696
7697 format %{ "leaq $dest, table_base\n\t"
7698 "jmp [$dest + $switch_val << $shift]\n\t" %}
7699 ins_encode(jump_enc_offset(switch_val, shift, dest));
7700 ins_pipe(pipe_jmp);
7701 ins_pc_relative(1);
7702 %}
7703
7704 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
7705 match(Jump (AddL (LShiftL switch_val shift) offset));
7706 ins_cost(350);
7707 effect(TEMP dest);
7708
7709 format %{ "leaq $dest, table_base\n\t"
7710 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
7711 ins_encode(jump_enc_addr(switch_val, shift, offset, dest));
7712 ins_pipe(pipe_jmp);
7713 ins_pc_relative(1);
7714 %}
7715
7716 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
7717 match(Jump switch_val);
7718 ins_cost(350);
7719 effect(TEMP dest);
7720
7721 format %{ "leaq $dest, table_base\n\t"
7722 "jmp [$dest + $switch_val]\n\t" %}
7723 ins_encode(jump_enc(switch_val, dest));
7724 ins_pipe(pipe_jmp);
7725 ins_pc_relative(1);
7726 %}
7727
7728 // Conditional move
7729 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
7730 %{
7731 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7732
7733 ins_cost(200); // XXX
7734 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7735 opcode(0x0F, 0x40);
7736 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7737 ins_pipe(pipe_cmov_reg);
7738 %}
7739
7740 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
7741 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7742
7743 ins_cost(200); // XXX
10359 "pushfq\t# saw NaN, set CF\n\t"
10360 "andq [rsp], #0xffffff2b\n\t"
10361 "popfq\n"
10362 "exit: nop\t# avoid branch to branch" %}
10363 opcode(0x0F, 0x2E);
10364 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10365 cmpfp_fixup);
10366 ins_pipe(pipe_slow);
10367 %}
10368
10369 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10370 match(Set cr (CmpF src1 (LoadF src2)));
10371
10372 ins_cost(100);
10373 format %{ "ucomiss $src1, $src2" %}
10374 opcode(0x0F, 0x2E);
10375 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
10376 ins_pipe(pipe_slow);
10377 %}
10378
10379 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
10380 %{
10381 match(Set cr (CmpF src1 src2));
10382
10383 ins_cost(145);
10384 format %{ "ucomiss $src1, $src2\n\t"
10385 "jnp,s exit\n\t"
10386 "pushfq\t# saw NaN, set CF\n\t"
10387 "andq [rsp], #0xffffff2b\n\t"
10388 "popfq\n"
10389 "exit: nop\t# avoid branch to branch" %}
10390 opcode(0x0F, 0x2E);
10391 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
10392 cmpfp_fixup);
10393 ins_pipe(pipe_slow);
10394 %}
10395
10396 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
10397 match(Set cr (CmpF src1 src2));
10398
10399 ins_cost(100);
10400 format %{ "ucomiss $src1, $src2" %}
10401 opcode(0x0F, 0x2E);
10402 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
10403 ins_pipe(pipe_slow);
10404 %}
10405
10406 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10407 %{
10408 match(Set cr (CmpD src1 src2));
10409
10410 ins_cost(145);
10411 format %{ "ucomisd $src1, $src2\n\t"
10412 "jnp,s exit\n\t"
10413 "pushfq\t# saw NaN, set CF\n\t"
10414 "andq [rsp], #0xffffff2b\n\t"
10415 "popfq\n"
10416 "exit: nop\t# avoid branch to branch" %}
10417 opcode(0x66, 0x0F, 0x2E);
10418 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10419 cmpfp_fixup);
10420 ins_pipe(pipe_slow);
10421 %}
10422
10441 "pushfq\t# saw NaN, set CF\n\t"
10442 "andq [rsp], #0xffffff2b\n\t"
10443 "popfq\n"
10444 "exit: nop\t# avoid branch to branch" %}
10445 opcode(0x66, 0x0F, 0x2E);
10446 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10447 cmpfp_fixup);
10448 ins_pipe(pipe_slow);
10449 %}
10450
10451 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10452 match(Set cr (CmpD src1 (LoadD src2)));
10453
10454 ins_cost(100);
10455 format %{ "ucomisd $src1, $src2" %}
10456 opcode(0x66, 0x0F, 0x2E);
10457 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
10458 ins_pipe(pipe_slow);
10459 %}
10460
10461 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
10462 %{
10463 match(Set cr (CmpD src1 src2));
10464
10465 ins_cost(145);
10466 format %{ "ucomisd $src1, [$src2]\n\t"
10467 "jnp,s exit\n\t"
10468 "pushfq\t# saw NaN, set CF\n\t"
10469 "andq [rsp], #0xffffff2b\n\t"
10470 "popfq\n"
10471 "exit: nop\t# avoid branch to branch" %}
10472 opcode(0x66, 0x0F, 0x2E);
10473 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
10474 cmpfp_fixup);
10475 ins_pipe(pipe_slow);
10476 %}
10477
10478 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
10479 match(Set cr (CmpD src1 src2));
10480
10481 ins_cost(100);
10482 format %{ "ucomisd $src1, [$src2]" %}
10483 opcode(0x66, 0x0F, 0x2E);
10484 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
10485 ins_pipe(pipe_slow);
10486 %}
10487
10488 // Compare into -1,0,1
10489 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10490 %{
10491 match(Set dst (CmpF3 src1 src2));
10492 effect(KILL cr);
10493
10494 ins_cost(275);
10495 format %{ "ucomiss $src1, $src2\n\t"
10496 "movl $dst, #-1\n\t"
10497 "jp,s done\n\t"
10498 "jb,s done\n\t"
10499 "setne $dst\n\t"
10500 "movzbl $dst, $dst\n"
10501 "done:" %}
10502
10503 opcode(0x0F, 0x2E);
10504 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10511 %{
10512 match(Set dst (CmpF3 src1 (LoadF src2)));
10513 effect(KILL cr);
10514
10515 ins_cost(275);
10516 format %{ "ucomiss $src1, $src2\n\t"
10517 "movl $dst, #-1\n\t"
10518 "jp,s done\n\t"
10519 "jb,s done\n\t"
10520 "setne $dst\n\t"
10521 "movzbl $dst, $dst\n"
10522 "done:" %}
10523
10524 opcode(0x0F, 0x2E);
10525 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10526 cmpfp3(dst));
10527 ins_pipe(pipe_slow);
10528 %}
10529
10530 // Compare into -1,0,1
10531 instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr)
10532 %{
10533 match(Set dst (CmpF3 src1 src2));
10534 effect(KILL cr);
10535
10536 ins_cost(275);
10537 format %{ "ucomiss $src1, [$src2]\n\t"
10538 "movl $dst, #-1\n\t"
10539 "jp,s done\n\t"
10540 "jb,s done\n\t"
10541 "setne $dst\n\t"
10542 "movzbl $dst, $dst\n"
10543 "done:" %}
10544
10545 opcode(0x0F, 0x2E);
10546 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
10547 cmpfp3(dst));
10548 ins_pipe(pipe_slow);
10549 %}
10550
10551 // Compare into -1,0,1
10552 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10553 %{
10554 match(Set dst (CmpD3 src1 src2));
10555 effect(KILL cr);
10556
10557 ins_cost(275);
10558 format %{ "ucomisd $src1, $src2\n\t"
10559 "movl $dst, #-1\n\t"
10560 "jp,s done\n\t"
10561 "jb,s done\n\t"
10562 "setne $dst\n\t"
10563 "movzbl $dst, $dst\n"
10564 "done:" %}
10565
10566 opcode(0x66, 0x0F, 0x2E);
10567 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10574 %{
10575 match(Set dst (CmpD3 src1 (LoadD src2)));
10576 effect(KILL cr);
10577
10578 ins_cost(275);
10579 format %{ "ucomisd $src1, $src2\n\t"
10580 "movl $dst, #-1\n\t"
10581 "jp,s done\n\t"
10582 "jb,s done\n\t"
10583 "setne $dst\n\t"
10584 "movzbl $dst, $dst\n"
10585 "done:" %}
10586
10587 opcode(0x66, 0x0F, 0x2E);
10588 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10589 cmpfp3(dst));
10590 ins_pipe(pipe_slow);
10591 %}
10592
10593 // Compare into -1,0,1
10594 instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr)
10595 %{
10596 match(Set dst (CmpD3 src1 src2));
10597 effect(KILL cr);
10598
10599 ins_cost(275);
10600 format %{ "ucomisd $src1, [$src2]\n\t"
10601 "movl $dst, #-1\n\t"
10602 "jp,s done\n\t"
10603 "jb,s done\n\t"
10604 "setne $dst\n\t"
10605 "movzbl $dst, $dst\n"
10606 "done:" %}
10607
10608 opcode(0x66, 0x0F, 0x2E);
10609 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
10610 cmpfp3(dst));
10611 ins_pipe(pipe_slow);
10612 %}
10613
10614 instruct addF_reg(regF dst, regF src)
10615 %{
10616 match(Set dst (AddF dst src));
10617
10618 format %{ "addss $dst, $src" %}
10619 ins_cost(150); // XXX
10620 opcode(0xF3, 0x0F, 0x58);
10621 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10622 ins_pipe(pipe_slow);
10623 %}
10624
10625 instruct addF_mem(regF dst, memory src)
10626 %{
10627 match(Set dst (AddF dst (LoadF src)));
10628
10629 format %{ "addss $dst, $src" %}
10630 ins_cost(150); // XXX
10631 opcode(0xF3, 0x0F, 0x58);
10632 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10633 ins_pipe(pipe_slow);
10634 %}
10635
10636 instruct addF_imm(regF dst, immF src)
10637 %{
10638 match(Set dst (AddF dst src));
10639
10640 format %{ "addss $dst, [$src]" %}
10641 ins_cost(150); // XXX
10642 opcode(0xF3, 0x0F, 0x58);
10643 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10644 ins_pipe(pipe_slow);
10645 %}
10646
10647 instruct addD_reg(regD dst, regD src)
10648 %{
10649 match(Set dst (AddD dst src));
10650
10651 format %{ "addsd $dst, $src" %}
10652 ins_cost(150); // XXX
10653 opcode(0xF2, 0x0F, 0x58);
10654 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10655 ins_pipe(pipe_slow);
10656 %}
10657
10658 instruct addD_mem(regD dst, memory src)
10659 %{
10660 match(Set dst (AddD dst (LoadD src)));
10661
10662 format %{ "addsd $dst, $src" %}
10663 ins_cost(150); // XXX
10664 opcode(0xF2, 0x0F, 0x58);
10665 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10666 ins_pipe(pipe_slow);
10667 %}
10668
10669 instruct addD_imm(regD dst, immD src)
10670 %{
10671 match(Set dst (AddD dst src));
10672
10673 format %{ "addsd $dst, [$src]" %}
10674 ins_cost(150); // XXX
10675 opcode(0xF2, 0x0F, 0x58);
10676 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10677 ins_pipe(pipe_slow);
10678 %}
10679
10680 instruct subF_reg(regF dst, regF src)
10681 %{
10682 match(Set dst (SubF dst src));
10683
10684 format %{ "subss $dst, $src" %}
10685 ins_cost(150); // XXX
10686 opcode(0xF3, 0x0F, 0x5C);
10687 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10688 ins_pipe(pipe_slow);
10689 %}
10690
10691 instruct subF_mem(regF dst, memory src)
10692 %{
10693 match(Set dst (SubF dst (LoadF src)));
10694
10695 format %{ "subss $dst, $src" %}
10696 ins_cost(150); // XXX
10697 opcode(0xF3, 0x0F, 0x5C);
10698 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10699 ins_pipe(pipe_slow);
10700 %}
10701
10702 instruct subF_imm(regF dst, immF src)
10703 %{
10704 match(Set dst (SubF dst src));
10705
10706 format %{ "subss $dst, [$src]" %}
10707 ins_cost(150); // XXX
10708 opcode(0xF3, 0x0F, 0x5C);
10709 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10710 ins_pipe(pipe_slow);
10711 %}
10712
10713 instruct subD_reg(regD dst, regD src)
10714 %{
10715 match(Set dst (SubD dst src));
10716
10717 format %{ "subsd $dst, $src" %}
10718 ins_cost(150); // XXX
10719 opcode(0xF2, 0x0F, 0x5C);
10720 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10721 ins_pipe(pipe_slow);
10722 %}
10723
10724 instruct subD_mem(regD dst, memory src)
10725 %{
10726 match(Set dst (SubD dst (LoadD src)));
10727
10728 format %{ "subsd $dst, $src" %}
10729 ins_cost(150); // XXX
10730 opcode(0xF2, 0x0F, 0x5C);
10731 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10732 ins_pipe(pipe_slow);
10733 %}
10734
10735 instruct subD_imm(regD dst, immD src)
10736 %{
10737 match(Set dst (SubD dst src));
10738
10739 format %{ "subsd $dst, [$src]" %}
10740 ins_cost(150); // XXX
10741 opcode(0xF2, 0x0F, 0x5C);
10742 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10743 ins_pipe(pipe_slow);
10744 %}
10745
10746 instruct mulF_reg(regF dst, regF src)
10747 %{
10748 match(Set dst (MulF dst src));
10749
10750 format %{ "mulss $dst, $src" %}
10751 ins_cost(150); // XXX
10752 opcode(0xF3, 0x0F, 0x59);
10753 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10754 ins_pipe(pipe_slow);
10755 %}
10756
10757 instruct mulF_mem(regF dst, memory src)
10758 %{
10759 match(Set dst (MulF dst (LoadF src)));
10760
10761 format %{ "mulss $dst, $src" %}
10762 ins_cost(150); // XXX
10763 opcode(0xF3, 0x0F, 0x59);
10764 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10765 ins_pipe(pipe_slow);
10766 %}
10767
10768 instruct mulF_imm(regF dst, immF src)
10769 %{
10770 match(Set dst (MulF dst src));
10771
10772 format %{ "mulss $dst, [$src]" %}
10773 ins_cost(150); // XXX
10774 opcode(0xF3, 0x0F, 0x59);
10775 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10776 ins_pipe(pipe_slow);
10777 %}
10778
10779 instruct mulD_reg(regD dst, regD src)
10780 %{
10781 match(Set dst (MulD dst src));
10782
10783 format %{ "mulsd $dst, $src" %}
10784 ins_cost(150); // XXX
10785 opcode(0xF2, 0x0F, 0x59);
10786 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10787 ins_pipe(pipe_slow);
10788 %}
10789
10790 instruct mulD_mem(regD dst, memory src)
10791 %{
10792 match(Set dst (MulD dst (LoadD src)));
10793
10794 format %{ "mulsd $dst, $src" %}
10795 ins_cost(150); // XXX
10796 opcode(0xF2, 0x0F, 0x59);
10797 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10798 ins_pipe(pipe_slow);
10799 %}
10800
10801 instruct mulD_imm(regD dst, immD src)
10802 %{
10803 match(Set dst (MulD dst src));
10804
10805 format %{ "mulsd $dst, [$src]" %}
10806 ins_cost(150); // XXX
10807 opcode(0xF2, 0x0F, 0x59);
10808 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10809 ins_pipe(pipe_slow);
10810 %}
10811
10812 instruct divF_reg(regF dst, regF src)
10813 %{
10814 match(Set dst (DivF dst src));
10815
10816 format %{ "divss $dst, $src" %}
10817 ins_cost(150); // XXX
10818 opcode(0xF3, 0x0F, 0x5E);
10819 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10820 ins_pipe(pipe_slow);
10821 %}
10822
10823 instruct divF_mem(regF dst, memory src)
10824 %{
10825 match(Set dst (DivF dst (LoadF src)));
10826
10827 format %{ "divss $dst, $src" %}
10828 ins_cost(150); // XXX
10829 opcode(0xF3, 0x0F, 0x5E);
10830 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10831 ins_pipe(pipe_slow);
10832 %}
10833
10834 instruct divF_imm(regF dst, immF src)
10835 %{
10836 match(Set dst (DivF dst src));
10837
10838 format %{ "divss $dst, [$src]" %}
10839 ins_cost(150); // XXX
10840 opcode(0xF3, 0x0F, 0x5E);
10841 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10842 ins_pipe(pipe_slow);
10843 %}
10844
10845 instruct divD_reg(regD dst, regD src)
10846 %{
10847 match(Set dst (DivD dst src));
10848
10849 format %{ "divsd $dst, $src" %}
10850 ins_cost(150); // XXX
10851 opcode(0xF2, 0x0F, 0x5E);
10852 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10853 ins_pipe(pipe_slow);
10854 %}
10855
10856 instruct divD_mem(regD dst, memory src)
10857 %{
10858 match(Set dst (DivD dst (LoadD src)));
10859
10860 format %{ "divsd $dst, $src" %}
10861 ins_cost(150); // XXX
10862 opcode(0xF2, 0x0F, 0x5E);
10863 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10864 ins_pipe(pipe_slow);
10865 %}
10866
10867 instruct divD_imm(regD dst, immD src)
10868 %{
10869 match(Set dst (DivD dst src));
10870
10871 format %{ "divsd $dst, [$src]" %}
10872 ins_cost(150); // XXX
10873 opcode(0xF2, 0x0F, 0x5E);
10874 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10875 ins_pipe(pipe_slow);
10876 %}
10877
10878 instruct sqrtF_reg(regF dst, regF src)
10879 %{
10880 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10881
10882 format %{ "sqrtss $dst, $src" %}
10883 ins_cost(150); // XXX
10884 opcode(0xF3, 0x0F, 0x51);
10885 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10886 ins_pipe(pipe_slow);
10887 %}
10888
10889 instruct sqrtF_mem(regF dst, memory src)
10890 %{
10891 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
10892
10893 format %{ "sqrtss $dst, $src" %}
10894 ins_cost(150); // XXX
10895 opcode(0xF3, 0x0F, 0x51);
10896 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10897 ins_pipe(pipe_slow);
10898 %}
10899
10900 instruct sqrtF_imm(regF dst, immF src)
10901 %{
10902 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10903
10904 format %{ "sqrtss $dst, [$src]" %}
10905 ins_cost(150); // XXX
10906 opcode(0xF3, 0x0F, 0x51);
10907 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10908 ins_pipe(pipe_slow);
10909 %}
10910
10911 instruct sqrtD_reg(regD dst, regD src)
10912 %{
10913 match(Set dst (SqrtD src));
10914
10915 format %{ "sqrtsd $dst, $src" %}
10916 ins_cost(150); // XXX
10917 opcode(0xF2, 0x0F, 0x51);
10918 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10919 ins_pipe(pipe_slow);
10920 %}
10921
10922 instruct sqrtD_mem(regD dst, memory src)
10923 %{
10924 match(Set dst (SqrtD (LoadD src)));
10925
10926 format %{ "sqrtsd $dst, $src" %}
10927 ins_cost(150); // XXX
10928 opcode(0xF2, 0x0F, 0x51);
10929 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10930 ins_pipe(pipe_slow);
10931 %}
10932
10933 instruct sqrtD_imm(regD dst, immD src)
10934 %{
10935 match(Set dst (SqrtD src));
10936
10937 format %{ "sqrtsd $dst, [$src]" %}
10938 ins_cost(150); // XXX
10939 opcode(0xF2, 0x0F, 0x51);
10940 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10941 ins_pipe(pipe_slow);
10942 %}
10943
10944 instruct absF_reg(regF dst)
10945 %{
10946 match(Set dst (AbsF dst));
10947
10948 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
10949 ins_encode(absF_encoding(dst));
10950 ins_pipe(pipe_slow);
10951 %}
10952
10953 instruct absD_reg(regD dst)
10954 %{
10955 match(Set dst (AbsD dst));
10956
10957 format %{ "andpd $dst, [0x7fffffffffffffff]\t"
10958 "# abs double by sign masking" %}
10959 ins_encode(absD_encoding(dst));
10960 ins_pipe(pipe_slow);
|
816 dstenc -= 8;
817 }
818
819 emit_opcode(cbuf, 0x8B);
820 emit_rm(cbuf, 0x3, dstenc, srcenc);
821 }
822 }
823
824 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
825 if( dst_encoding == src_encoding ) {
826 // reg-reg copy, use an empty encoding
827 } else {
828 MacroAssembler _masm(&cbuf);
829
830 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
831 }
832 }
833
834
835 //=============================================================================
836 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
837
838 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
839 emit_constant_table(cbuf);
840 set_table_base_offset(0);
841 // Empty encoding
842 }
843
844 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
845 // Compute the size (even if it's zero) since
846 // Compile::Shorten_branches needs the table to be emitted (which
847 // happens in Compile::scratch_emit_size) to calculate the size for
848 // MachConstantNodes.
849 return MachNode::size(ra_);
850 }
851
852 #ifndef PRODUCT
853 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
854 st->print("# MachConstantBase (empty encoding)");
855 }
856 #endif
857
858
859 //=============================================================================
860 #ifndef PRODUCT
861 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
862 {
863 Compile* C = ra_->C;
864
865 int framesize = C->frame_slots() << LogBytesPerInt;
866 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
867 // Remove wordSize for return adr already pushed
868 // and another for the RBP we are going to save
869 framesize -= 2*wordSize;
870 bool need_nop = true;
871
872 // Calls to C2R adapters often do not accept exceptional returns.
873 // We require that their callers must bang for them. But be
874 // careful, because some VM calls (such as call site linkage) can
875 // use several kilobytes of stack. But the stack safety zone should
876 // account for that. See bugs 4446381, 4468289, 4497237.
877 if (C->need_stack_bang(framesize)) {
878 st->print_cr("# stack bang"); st->print("\t");
879 need_nop = false;
1929 address base =
1930 __ start_a_stub(size_deopt_handler());
1931 if (base == NULL) return 0; // CodeBuffer::expand failed
1932 int offset = __ offset();
1933 address the_pc = (address) __ pc();
1934 Label next;
1935 // push a "the_pc" on the stack without destroying any registers
1936 // as they all may be live.
1937
1938 // push address of "next"
1939 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1940 __ bind(next);
1941 // adjust it so it matches "the_pc"
1942 __ subptr(Address(rsp, 0), __ offset() - offset);
1943 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1944 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1945 __ end_a_stub();
1946 return offset;
1947 }
1948
1949
1950 const bool Matcher::match_rule_supported(int opcode) {
1951 if (!has_match_rule(opcode))
1952 return false;
1953
1954 return true; // Per default match rules are supported.
1955 }
1956
1957 int Matcher::regnum_to_fpu_offset(int regnum)
1958 {
1959 return regnum - 32; // The FP registers are in the second chunk
1960 }
1961
1962 // This is UltraSparc specific, true just means we have fast l2f conversion
1963 const bool Matcher::convL2FSupported(void) {
1964 return true;
1965 }
1966
1967 // Vector width in bytes
1968 const uint Matcher::vector_width_in_bytes(void) {
2774 %}
2775
2776 enc_class load_immP(rRegP dst, immP src)
2777 %{
2778 int dstenc = $dst$$reg;
2779 if (dstenc < 8) {
2780 emit_opcode(cbuf, Assembler::REX_W);
2781 } else {
2782 emit_opcode(cbuf, Assembler::REX_WB);
2783 dstenc -= 8;
2784 }
2785 emit_opcode(cbuf, 0xB8 | dstenc);
2786 // This next line should be generated from ADLC
2787 if ($src->constant_is_oop()) {
2788 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2789 } else {
2790 emit_d64(cbuf, $src$$constant);
2791 }
2792 %}
2793
2794 // Encode a reg-reg copy. If it is useless, then empty encoding.
2795 enc_class enc_copy(rRegI dst, rRegI src)
2796 %{
2797 encode_copy(cbuf, $dst$$reg, $src$$reg);
2798 %}
2799
2800 // Encode xmm reg-reg copy. If it is useless, then empty encoding.
2801 enc_class enc_CopyXD( RegD dst, RegD src ) %{
2802 encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
2803 %}
2804
2805 enc_class enc_copy_always(rRegI dst, rRegI src)
2806 %{
2807 int srcenc = $src$$reg;
2808 int dstenc = $dst$$reg;
2809
2810 if (dstenc < 8) {
2811 if (srcenc >= 8) {
2812 emit_opcode(cbuf, Assembler::REX_B);
2813 srcenc -= 8;
2874 %}
2875
2876 enc_class Con16(immI src)
2877 %{
2878 // Output immediate
2879 $$$emit16$src$$constant;
2880 %}
2881
2882 // How is this different from Con32??? XXX
2883 enc_class Con_d32(immI src)
2884 %{
2885 emit_d32(cbuf,$src$$constant);
2886 %}
2887
2888 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2889 // Output immediate memory reference
2890 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2891 emit_d32(cbuf, 0x00);
2892 %}
2893
2894 enc_class lock_prefix()
2895 %{
2896 if (os::is_MP()) {
2897 emit_opcode(cbuf, 0xF0); // lock
2898 }
2899 %}
2900
2901 enc_class REX_mem(memory mem)
2902 %{
2903 if ($mem$$base >= 8) {
2904 if ($mem$$index < 8) {
2905 emit_opcode(cbuf, Assembler::REX_B);
2906 } else {
2907 emit_opcode(cbuf, Assembler::REX_XB);
2908 }
2909 } else {
2910 if ($mem$$index >= 8) {
2911 emit_opcode(cbuf, Assembler::REX_X);
2912 }
2913 }
6532 instruct loadConUL32(rRegL dst, immUL32 src)
6533 %{
6534 match(Set dst src);
6535
6536 ins_cost(60);
6537 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
6538 ins_encode(load_immUL32(dst, src));
6539 ins_pipe(ialu_reg);
6540 %}
6541
6542 instruct loadConL32(rRegL dst, immL32 src)
6543 %{
6544 match(Set dst src);
6545
6546 ins_cost(70);
6547 format %{ "movq $dst, $src\t# long (32-bit)" %}
6548 ins_encode(load_immL32(dst, src));
6549 ins_pipe(ialu_reg);
6550 %}
6551
6552 instruct loadConP(rRegP dst, immP con) %{
6553 match(Set dst con);
6554
6555 format %{ "movq $dst, $con\t# ptr" %}
6556 ins_encode(load_immP(dst, con));
6557 ins_pipe(ialu_reg_fat); // XXX
6558 %}
6559
6560 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
6561 %{
6562 match(Set dst src);
6563 effect(KILL cr);
6564
6565 ins_cost(50);
6566 format %{ "xorl $dst, $dst\t# ptr" %}
6567 opcode(0x33); /* + rd */
6568 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6569 ins_pipe(ialu_reg);
6570 %}
6571
6572 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
6573 %{
6574 match(Set dst src);
6575 effect(KILL cr);
6576
6577 ins_cost(60);
6578 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
6579 ins_encode(load_immP31(dst, src));
6580 ins_pipe(ialu_reg);
6581 %}
6582
6583 instruct loadConF(regF dst, immF con) %{
6584 match(Set dst con);
6585 ins_cost(125);
6586 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
6587 ins_encode %{
6588 __ movflt($dst$$XMMRegister, $constantaddress($con));
6589 %}
6590 ins_pipe(pipe_slow);
6591 %}
6592
6593 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6594 match(Set dst src);
6595 effect(KILL cr);
6596 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
6597 ins_encode %{
6598 __ xorq($dst$$Register, $dst$$Register);
6599 %}
6600 ins_pipe(ialu_reg);
6601 %}
6602
6603 instruct loadConN(rRegN dst, immN src) %{
6604 match(Set dst src);
6605
6606 ins_cost(125);
6607 format %{ "movl $dst, $src\t# compressed ptr" %}
6608 ins_encode %{
6609 address con = (address)$src$$constant;
6611 ShouldNotReachHere();
6612 } else {
6613 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
6614 }
6615 %}
6616 ins_pipe(ialu_reg_fat); // XXX
6617 %}
6618
6619 instruct loadConF0(regF dst, immF0 src)
6620 %{
6621 match(Set dst src);
6622 ins_cost(100);
6623
6624 format %{ "xorps $dst, $dst\t# float 0.0" %}
6625 opcode(0x0F, 0x57);
6626 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
6627 ins_pipe(pipe_slow);
6628 %}
6629
6630 // Use the same format since predicate() can not be used here.
6631 instruct loadConD(regD dst, immD con) %{
6632 match(Set dst con);
6633 ins_cost(125);
6634 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
6635 ins_encode %{
6636 __ movdbl($dst$$XMMRegister, $constantaddress($con));
6637 %}
6638 ins_pipe(pipe_slow);
6639 %}
6640
6641 instruct loadConD0(regD dst, immD0 src)
6642 %{
6643 match(Set dst src);
6644 ins_cost(100);
6645
6646 format %{ "xorpd $dst, $dst\t# double 0.0" %}
6647 opcode(0x66, 0x0F, 0x57);
6648 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst));
6649 ins_pipe(pipe_slow);
6650 %}
6651
6652 instruct loadSSI(rRegI dst, stackSlotI src)
6653 %{
6654 match(Set dst src);
6655
6656 ins_cost(125);
6657 format %{ "movl $dst, $src\t# int stk" %}
7584 Register d = $dst$$Register;
7585 if (s != d) {
7586 __ decode_heap_oop_not_null(d, s);
7587 } else {
7588 __ decode_heap_oop_not_null(d);
7589 }
7590 %}
7591 ins_pipe(ialu_reg_long);
7592 %}
7593
7594
7595 //----------Conditional Move---------------------------------------------------
7596 // Jump
7597 // dummy instruction for generating temp registers
7598 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
7599 match(Jump (LShiftL switch_val shift));
7600 ins_cost(350);
7601 predicate(false);
7602 effect(TEMP dest);
7603
7604 format %{ "leaq $dest, [$constantaddress]\n\t"
7605 "jmp [$dest + $switch_val << $shift]\n\t" %}
7606 ins_encode %{
7607 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7608 // to do that and the compiler is using that register as one it can allocate.
7609 // So we build it all by hand.
7610 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
7611 // ArrayAddress dispatch(table, index);
7612 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
7613 __ lea($dest$$Register, $constantaddress);
7614 __ jmp(dispatch);
7615 %}
7616 ins_pipe(pipe_jmp);
7617 ins_pc_relative(1);
7618 %}
7619
7620 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
7621 match(Jump (AddL (LShiftL switch_val shift) offset));
7622 ins_cost(350);
7623 effect(TEMP dest);
7624
7625 format %{ "leaq $dest, [$constantaddress]\n\t"
7626 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
7627 ins_encode %{
7628 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7629 // to do that and the compiler is using that register as one it can allocate.
7630 // So we build it all by hand.
7631 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
7632 // ArrayAddress dispatch(table, index);
7633 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
7634 __ lea($dest$$Register, $constantaddress);
7635 __ jmp(dispatch);
7636 %}
7637 ins_pipe(pipe_jmp);
7638 ins_pc_relative(1);
7639 %}
7640
7641 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
7642 match(Jump switch_val);
7643 ins_cost(350);
7644 effect(TEMP dest);
7645
7646 format %{ "leaq $dest, [$constantaddress]\n\t"
7647 "jmp [$dest + $switch_val]\n\t" %}
7648 ins_encode %{
7649 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7650 // to do that and the compiler is using that register as one it can allocate.
7651 // So we build it all by hand.
7652 // Address index(noreg, switch_reg, Address::times_1);
7653 // ArrayAddress dispatch(table, index);
7654 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
7655 __ lea($dest$$Register, $constantaddress);
7656 __ jmp(dispatch);
7657 %}
7658 ins_pipe(pipe_jmp);
7659 ins_pc_relative(1);
7660 %}
7661
7662 // Conditional move
7663 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
7664 %{
7665 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7666
7667 ins_cost(200); // XXX
7668 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7669 opcode(0x0F, 0x40);
7670 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7671 ins_pipe(pipe_cmov_reg);
7672 %}
7673
7674 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
7675 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7676
7677 ins_cost(200); // XXX
10293 "pushfq\t# saw NaN, set CF\n\t"
10294 "andq [rsp], #0xffffff2b\n\t"
10295 "popfq\n"
10296 "exit: nop\t# avoid branch to branch" %}
10297 opcode(0x0F, 0x2E);
10298 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10299 cmpfp_fixup);
10300 ins_pipe(pipe_slow);
10301 %}
10302
10303 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10304 match(Set cr (CmpF src1 (LoadF src2)));
10305
10306 ins_cost(100);
10307 format %{ "ucomiss $src1, $src2" %}
10308 opcode(0x0F, 0x2E);
10309 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
10310 ins_pipe(pipe_slow);
10311 %}
10312
10313 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10314 match(Set cr (CmpF src con));
10315
10316 ins_cost(145);
10317 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10318 "jnp,s exit\n\t"
10319 "pushfq\t# saw NaN, set CF\n\t"
10320 "andq [rsp], #0xffffff2b\n\t"
10321 "popfq\n"
10322 "exit: nop\t# avoid branch to branch" %}
10323 ins_encode %{
10324 Label L_exit;
10325 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10326 __ jcc(Assembler::noParity, L_exit);
10327 __ pushf();
10328 __ andq(rsp, 0xffffff2b);
10329 __ popf();
10330 __ bind(L_exit);
10331 __ nop();
10332 %}
10333 ins_pipe(pipe_slow);
10334 %}
10335
10336 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
10337 match(Set cr (CmpF src con));
10338 ins_cost(100);
10339 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
10340 ins_encode %{
10341 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10342 %}
10343 ins_pipe(pipe_slow);
10344 %}
10345
10346 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10347 %{
10348 match(Set cr (CmpD src1 src2));
10349
10350 ins_cost(145);
10351 format %{ "ucomisd $src1, $src2\n\t"
10352 "jnp,s exit\n\t"
10353 "pushfq\t# saw NaN, set CF\n\t"
10354 "andq [rsp], #0xffffff2b\n\t"
10355 "popfq\n"
10356 "exit: nop\t# avoid branch to branch" %}
10357 opcode(0x66, 0x0F, 0x2E);
10358 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10359 cmpfp_fixup);
10360 ins_pipe(pipe_slow);
10361 %}
10362
10381 "pushfq\t# saw NaN, set CF\n\t"
10382 "andq [rsp], #0xffffff2b\n\t"
10383 "popfq\n"
10384 "exit: nop\t# avoid branch to branch" %}
10385 opcode(0x66, 0x0F, 0x2E);
10386 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10387 cmpfp_fixup);
10388 ins_pipe(pipe_slow);
10389 %}
10390
10391 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10392 match(Set cr (CmpD src1 (LoadD src2)));
10393
10394 ins_cost(100);
10395 format %{ "ucomisd $src1, $src2" %}
10396 opcode(0x66, 0x0F, 0x2E);
10397 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
10398 ins_pipe(pipe_slow);
10399 %}
10400
10401 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10402 match(Set cr (CmpD src con));
10403
10404 ins_cost(145);
10405 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10406 "jnp,s exit\n\t"
10407 "pushfq\t# saw NaN, set CF\n\t"
10408 "andq [rsp], #0xffffff2b\n\t"
10409 "popfq\n"
10410 "exit: nop\t# avoid branch to branch" %}
10411 ins_encode %{
10412 Label L_exit;
10413 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10414 __ jcc(Assembler::noParity, L_exit);
10415 __ pushf();
10416 __ andq(rsp, 0xffffff2b);
10417 __ popf();
10418 __ bind(L_exit);
10419 __ nop();
10420 %}
10421 ins_pipe(pipe_slow);
10422 %}
10423
10424 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
10425 match(Set cr (CmpD src con));
10426 ins_cost(100);
10427 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
10428 ins_encode %{
10429 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10430 %}
10431 ins_pipe(pipe_slow);
10432 %}
10433
10434 // Compare into -1,0,1
10435 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10436 %{
10437 match(Set dst (CmpF3 src1 src2));
10438 effect(KILL cr);
10439
10440 ins_cost(275);
10441 format %{ "ucomiss $src1, $src2\n\t"
10442 "movl $dst, #-1\n\t"
10443 "jp,s done\n\t"
10444 "jb,s done\n\t"
10445 "setne $dst\n\t"
10446 "movzbl $dst, $dst\n"
10447 "done:" %}
10448
10449 opcode(0x0F, 0x2E);
10450 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10457 %{
10458 match(Set dst (CmpF3 src1 (LoadF src2)));
10459 effect(KILL cr);
10460
10461 ins_cost(275);
10462 format %{ "ucomiss $src1, $src2\n\t"
10463 "movl $dst, #-1\n\t"
10464 "jp,s done\n\t"
10465 "jb,s done\n\t"
10466 "setne $dst\n\t"
10467 "movzbl $dst, $dst\n"
10468 "done:" %}
10469
10470 opcode(0x0F, 0x2E);
10471 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10472 cmpfp3(dst));
10473 ins_pipe(pipe_slow);
10474 %}
10475
10476 // Compare into -1,0,1
10477 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10478 match(Set dst (CmpF3 src con));
10479 effect(KILL cr);
10480
10481 ins_cost(275);
10482 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10483 "movl $dst, #-1\n\t"
10484 "jp,s done\n\t"
10485 "jb,s done\n\t"
10486 "setne $dst\n\t"
10487 "movzbl $dst, $dst\n"
10488 "done:" %}
10489 ins_encode %{
10490 Label L_done;
10491 Register Rdst = $dst$$Register;
10492 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10493 __ movl(Rdst, -1);
10494 __ jcc(Assembler::parity, L_done);
10495 __ jcc(Assembler::below, L_done);
10496 __ setb(Assembler::notEqual, Rdst);
10497 __ movzbl(Rdst, Rdst);
10498 __ bind(L_done);
10499 %}
10500 ins_pipe(pipe_slow);
10501 %}
10502
10503 // Compare into -1,0,1
10504 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10505 %{
10506 match(Set dst (CmpD3 src1 src2));
10507 effect(KILL cr);
10508
10509 ins_cost(275);
10510 format %{ "ucomisd $src1, $src2\n\t"
10511 "movl $dst, #-1\n\t"
10512 "jp,s done\n\t"
10513 "jb,s done\n\t"
10514 "setne $dst\n\t"
10515 "movzbl $dst, $dst\n"
10516 "done:" %}
10517
10518 opcode(0x66, 0x0F, 0x2E);
10519 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10526 %{
10527 match(Set dst (CmpD3 src1 (LoadD src2)));
10528 effect(KILL cr);
10529
10530 ins_cost(275);
10531 format %{ "ucomisd $src1, $src2\n\t"
10532 "movl $dst, #-1\n\t"
10533 "jp,s done\n\t"
10534 "jb,s done\n\t"
10535 "setne $dst\n\t"
10536 "movzbl $dst, $dst\n"
10537 "done:" %}
10538
10539 opcode(0x66, 0x0F, 0x2E);
10540 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10541 cmpfp3(dst));
10542 ins_pipe(pipe_slow);
10543 %}
10544
10545 // Compare into -1,0,1
10546 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10547 match(Set dst (CmpD3 src con));
10548 effect(KILL cr);
10549
10550 ins_cost(275);
10551 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10552 "movl $dst, #-1\n\t"
10553 "jp,s done\n\t"
10554 "jb,s done\n\t"
10555 "setne $dst\n\t"
10556 "movzbl $dst, $dst\n"
10557 "done:" %}
10558 ins_encode %{
10559 Register Rdst = $dst$$Register;
10560 Label L_done;
10561 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10562 __ movl(Rdst, -1);
10563 __ jcc(Assembler::parity, L_done);
10564 __ jcc(Assembler::below, L_done);
10565 __ setb(Assembler::notEqual, Rdst);
10566 __ movzbl(Rdst, Rdst);
10567 __ bind(L_done);
10568 %}
10569 ins_pipe(pipe_slow);
10570 %}
10571
10572 instruct addF_reg(regF dst, regF src)
10573 %{
10574 match(Set dst (AddF dst src));
10575
10576 format %{ "addss $dst, $src" %}
10577 ins_cost(150); // XXX
10578 opcode(0xF3, 0x0F, 0x58);
10579 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10580 ins_pipe(pipe_slow);
10581 %}
10582
10583 instruct addF_mem(regF dst, memory src)
10584 %{
10585 match(Set dst (AddF dst (LoadF src)));
10586
10587 format %{ "addss $dst, $src" %}
10588 ins_cost(150); // XXX
10589 opcode(0xF3, 0x0F, 0x58);
10590 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10591 ins_pipe(pipe_slow);
10592 %}
10593
10594 instruct addF_imm(regF dst, immF con) %{
10595 match(Set dst (AddF dst con));
10596 format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10597 ins_cost(150); // XXX
10598 ins_encode %{
10599 __ addss($dst$$XMMRegister, $constantaddress($con));
10600 %}
10601 ins_pipe(pipe_slow);
10602 %}
10603
10604 instruct addD_reg(regD dst, regD src)
10605 %{
10606 match(Set dst (AddD dst src));
10607
10608 format %{ "addsd $dst, $src" %}
10609 ins_cost(150); // XXX
10610 opcode(0xF2, 0x0F, 0x58);
10611 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10612 ins_pipe(pipe_slow);
10613 %}
10614
10615 instruct addD_mem(regD dst, memory src)
10616 %{
10617 match(Set dst (AddD dst (LoadD src)));
10618
10619 format %{ "addsd $dst, $src" %}
10620 ins_cost(150); // XXX
10621 opcode(0xF2, 0x0F, 0x58);
10622 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10623 ins_pipe(pipe_slow);
10624 %}
10625
10626 instruct addD_imm(regD dst, immD con) %{
10627 match(Set dst (AddD dst con));
10628 format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10629 ins_cost(150); // XXX
10630 ins_encode %{
10631 __ addsd($dst$$XMMRegister, $constantaddress($con));
10632 %}
10633 ins_pipe(pipe_slow);
10634 %}
10635
10636 instruct subF_reg(regF dst, regF src)
10637 %{
10638 match(Set dst (SubF dst src));
10639
10640 format %{ "subss $dst, $src" %}
10641 ins_cost(150); // XXX
10642 opcode(0xF3, 0x0F, 0x5C);
10643 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10644 ins_pipe(pipe_slow);
10645 %}
10646
10647 instruct subF_mem(regF dst, memory src)
10648 %{
10649 match(Set dst (SubF dst (LoadF src)));
10650
10651 format %{ "subss $dst, $src" %}
10652 ins_cost(150); // XXX
10653 opcode(0xF3, 0x0F, 0x5C);
10654 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10655 ins_pipe(pipe_slow);
10656 %}
10657
10658 instruct subF_imm(regF dst, immF con) %{
10659 match(Set dst (SubF dst con));
10660 format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10661 ins_cost(150); // XXX
10662 ins_encode %{
10663 __ subss($dst$$XMMRegister, $constantaddress($con));
10664 %}
10665 ins_pipe(pipe_slow);
10666 %}
10667
10668 instruct subD_reg(regD dst, regD src)
10669 %{
10670 match(Set dst (SubD dst src));
10671
10672 format %{ "subsd $dst, $src" %}
10673 ins_cost(150); // XXX
10674 opcode(0xF2, 0x0F, 0x5C);
10675 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10676 ins_pipe(pipe_slow);
10677 %}
10678
10679 instruct subD_mem(regD dst, memory src)
10680 %{
10681 match(Set dst (SubD dst (LoadD src)));
10682
10683 format %{ "subsd $dst, $src" %}
10684 ins_cost(150); // XXX
10685 opcode(0xF2, 0x0F, 0x5C);
10686 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10687 ins_pipe(pipe_slow);
10688 %}
10689
10690 instruct subD_imm(regD dst, immD con) %{
10691 match(Set dst (SubD dst con));
10692 format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10693 ins_cost(150); // XXX
10694 ins_encode %{
10695 __ subsd($dst$$XMMRegister, $constantaddress($con));
10696 %}
10697 ins_pipe(pipe_slow);
10698 %}
10699
10700 instruct mulF_reg(regF dst, regF src)
10701 %{
10702 match(Set dst (MulF dst src));
10703
10704 format %{ "mulss $dst, $src" %}
10705 ins_cost(150); // XXX
10706 opcode(0xF3, 0x0F, 0x59);
10707 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10708 ins_pipe(pipe_slow);
10709 %}
10710
10711 instruct mulF_mem(regF dst, memory src)
10712 %{
10713 match(Set dst (MulF dst (LoadF src)));
10714
10715 format %{ "mulss $dst, $src" %}
10716 ins_cost(150); // XXX
10717 opcode(0xF3, 0x0F, 0x59);
10718 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10719 ins_pipe(pipe_slow);
10720 %}
10721
10722 instruct mulF_imm(regF dst, immF con) %{
10723 match(Set dst (MulF dst con));
10724 format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10725 ins_cost(150); // XXX
10726 ins_encode %{
10727 __ mulss($dst$$XMMRegister, $constantaddress($con));
10728 %}
10729 ins_pipe(pipe_slow);
10730 %}
10731
10732 instruct mulD_reg(regD dst, regD src)
10733 %{
10734 match(Set dst (MulD dst src));
10735
10736 format %{ "mulsd $dst, $src" %}
10737 ins_cost(150); // XXX
10738 opcode(0xF2, 0x0F, 0x59);
10739 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10740 ins_pipe(pipe_slow);
10741 %}
10742
10743 instruct mulD_mem(regD dst, memory src)
10744 %{
10745 match(Set dst (MulD dst (LoadD src)));
10746
10747 format %{ "mulsd $dst, $src" %}
10748 ins_cost(150); // XXX
10749 opcode(0xF2, 0x0F, 0x59);
10750 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10751 ins_pipe(pipe_slow);
10752 %}
10753
10754 instruct mulD_imm(regD dst, immD con) %{
10755 match(Set dst (MulD dst con));
10756 format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10757 ins_cost(150); // XXX
10758 ins_encode %{
10759 __ mulsd($dst$$XMMRegister, $constantaddress($con));
10760 %}
10761 ins_pipe(pipe_slow);
10762 %}
10763
10764 instruct divF_reg(regF dst, regF src)
10765 %{
10766 match(Set dst (DivF dst src));
10767
10768 format %{ "divss $dst, $src" %}
10769 ins_cost(150); // XXX
10770 opcode(0xF3, 0x0F, 0x5E);
10771 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10772 ins_pipe(pipe_slow);
10773 %}
10774
10775 instruct divF_mem(regF dst, memory src)
10776 %{
10777 match(Set dst (DivF dst (LoadF src)));
10778
10779 format %{ "divss $dst, $src" %}
10780 ins_cost(150); // XXX
10781 opcode(0xF3, 0x0F, 0x5E);
10782 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10783 ins_pipe(pipe_slow);
10784 %}
10785
10786 instruct divF_imm(regF dst, immF con) %{
10787 match(Set dst (DivF dst con));
10788 format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10789 ins_cost(150); // XXX
10790 ins_encode %{
10791 __ divss($dst$$XMMRegister, $constantaddress($con));
10792 %}
10793 ins_pipe(pipe_slow);
10794 %}
10795
10796 instruct divD_reg(regD dst, regD src)
10797 %{
10798 match(Set dst (DivD dst src));
10799
10800 format %{ "divsd $dst, $src" %}
10801 ins_cost(150); // XXX
10802 opcode(0xF2, 0x0F, 0x5E);
10803 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10804 ins_pipe(pipe_slow);
10805 %}
10806
10807 instruct divD_mem(regD dst, memory src)
10808 %{
10809 match(Set dst (DivD dst (LoadD src)));
10810
10811 format %{ "divsd $dst, $src" %}
10812 ins_cost(150); // XXX
10813 opcode(0xF2, 0x0F, 0x5E);
10814 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10815 ins_pipe(pipe_slow);
10816 %}
10817
10818 instruct divD_imm(regD dst, immD con) %{
10819 match(Set dst (DivD dst con));
10820 format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10821 ins_cost(150); // XXX
10822 ins_encode %{
10823 __ divsd($dst$$XMMRegister, $constantaddress($con));
10824 %}
10825 ins_pipe(pipe_slow);
10826 %}
10827
10828 instruct sqrtF_reg(regF dst, regF src)
10829 %{
10830 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10831
10832 format %{ "sqrtss $dst, $src" %}
10833 ins_cost(150); // XXX
10834 opcode(0xF3, 0x0F, 0x51);
10835 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10836 ins_pipe(pipe_slow);
10837 %}
10838
10839 instruct sqrtF_mem(regF dst, memory src)
10840 %{
10841 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
10842
10843 format %{ "sqrtss $dst, $src" %}
10844 ins_cost(150); // XXX
10845 opcode(0xF3, 0x0F, 0x51);
10846 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10847 ins_pipe(pipe_slow);
10848 %}
10849
10850 instruct sqrtF_imm(regF dst, immF con) %{
10851 match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
10852 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10853 ins_cost(150); // XXX
10854 ins_encode %{
10855 __ sqrtss($dst$$XMMRegister, $constantaddress($con));
10856 %}
10857 ins_pipe(pipe_slow);
10858 %}
10859
10860 instruct sqrtD_reg(regD dst, regD src)
10861 %{
10862 match(Set dst (SqrtD src));
10863
10864 format %{ "sqrtsd $dst, $src" %}
10865 ins_cost(150); // XXX
10866 opcode(0xF2, 0x0F, 0x51);
10867 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10868 ins_pipe(pipe_slow);
10869 %}
10870
10871 instruct sqrtD_mem(regD dst, memory src)
10872 %{
10873 match(Set dst (SqrtD (LoadD src)));
10874
10875 format %{ "sqrtsd $dst, $src" %}
10876 ins_cost(150); // XXX
10877 opcode(0xF2, 0x0F, 0x51);
10878 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10879 ins_pipe(pipe_slow);
10880 %}
10881
10882 instruct sqrtD_imm(regD dst, immD con) %{
10883 match(Set dst (SqrtD con));
10884 format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10885 ins_cost(150); // XXX
10886 ins_encode %{
10887 __ sqrtsd($dst$$XMMRegister, $constantaddress($con));
10888 %}
10889 ins_pipe(pipe_slow);
10890 %}
10891
10892 instruct absF_reg(regF dst)
10893 %{
10894 match(Set dst (AbsF dst));
10895
10896 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
10897 ins_encode(absF_encoding(dst));
10898 ins_pipe(pipe_slow);
10899 %}
10900
10901 instruct absD_reg(regD dst)
10902 %{
10903 match(Set dst (AbsD dst));
10904
10905 format %{ "andpd $dst, [0x7fffffffffffffff]\t"
10906 "# abs double by sign masking" %}
10907 ins_encode(absD_encoding(dst));
10908 ins_pipe(pipe_slow);
|