792 else if (type == longType) 793 __ cas_long(addr, cmp.result(), val.result(), ill, ill); 794 else { 795 ShouldNotReachHere(); 796 } 797 798 // generate conditional move of boolean result 799 LIR_Opr result = rlock_result(x); 800 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), 801 result, as_BasicType(type)); 802 if (type == objectType) { // Write-barrier needed for Object fields. 803 // Seems to be precise 804 post_barrier(addr, val.result()); 805 } 806 } 807 808 809 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { 810 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); 811 812 if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog) { 813 do_LibmIntrinsic(x); 814 return; 815 } 816 817 LIRItem value(x->argument_at(0), this); 818 819 bool use_fpu = false; 820 if (UseSSE >= 2) { 821 switch(x->id()) { 822 case vmIntrinsics::_dsin: 823 case vmIntrinsics::_dcos: 824 case vmIntrinsics::_dtan: 825 case vmIntrinsics::_dlog10: 826 case vmIntrinsics::_dpow: 827 use_fpu = true; 828 } 829 } else { 830 value.set_destroys_register(); 831 } 832 833 value.load_item(); 834 835 LIR_Opr calc_input = value.result(); 836 LIR_Opr calc_input2 = NULL; 837 if (x->id() == vmIntrinsics::_dpow) { 838 LIRItem extra_arg(x->argument_at(1), this); 839 if (UseSSE < 2) { 840 extra_arg.set_destroys_register(); 841 } 842 extra_arg.load_item(); 843 calc_input2 = extra_arg.result(); 844 } 845 LIR_Opr calc_result = rlock_result(x); 846 847 // sin, cos, pow and exp need two free fpu stack slots, so register 852 if (use_fpu) { 853 LIR_Opr tmp = FrameMap::fpu0_double_opr; 854 int tmp_start = 1; 855 if (calc_input2 != NULL) { 856 __ move(calc_input2, tmp); 857 tmp_start = 2; 858 calc_input2 = tmp; 859 } 860 __ move(calc_input, tmp); 861 862 calc_input = tmp; 863 calc_result = tmp; 864 865 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start); 866 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1); 867 } 868 869 switch(x->id()) { 870 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 871 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 872 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; 873 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break; 874 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; 875 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; 876 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; 877 default: ShouldNotReachHere(); 878 } 879 880 if (use_fpu) { 881 __ move(calc_result, x->operand()); 882 } 883 } 884 885 void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { 886 LIRItem value(x->argument_at(0), this); 887 value.set_destroys_register(); 888 889 LIR_Opr calc_result = rlock_result(x); 890 LIR_Opr result_reg = result_register_for(x->type()); 891 892 BasicTypeList signature(1); 893 signature.append(T_DOUBLE); 894 CallingConvention* cc = frame_map()->c_calling_convention(&signature); 895 896 value.load_item_force(cc->at(0)); 897 898 #ifndef _LP64 899 LIR_Opr tmp = FrameMap::fpu0_double_opr; 900 result_reg = tmp; 901 switch(x->id()) { 902 case vmIntrinsics::_dexp: 903 if (VM_Version::supports_sse2()) { 904 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 905 } else { 906 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); 907 } 908 break; 909 case vmIntrinsics::_dlog: 910 if (VM_Version::supports_sse2()) { 911 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 912 } 913 else { 914 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); 915 } 916 break; 917 default: ShouldNotReachHere(); 918 } 919 #else 920 switch (x->id()) { 921 case vmIntrinsics::_dexp: 922 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 923 break; 924 case vmIntrinsics::_dlog: 925 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 926 break; 927 } 928 #endif 929 __ move(result_reg, calc_result); 930 } 931 932 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { 933 assert(x->number_of_arguments() == 5, "wrong type"); 934 935 // Make all state_for calls early since they can emit code 936 CodeEmitInfo* info = state_for(x, x->state()); 937 938 LIRItem src(x->argument_at(0), this); 939 LIRItem src_pos(x->argument_at(1), this); 940 LIRItem dst(x->argument_at(2), this); 941 LIRItem dst_pos(x->argument_at(3), this); 942 LIRItem length(x->argument_at(4), this); 943 944 // operands for arraycopy must use fixed registers, otherwise 945 // LinearScan will fail allocation (because arraycopy always needs a | 792 else if (type == longType) 793 __ cas_long(addr, cmp.result(), val.result(), ill, ill); 794 else { 795 ShouldNotReachHere(); 796 } 797 798 // generate conditional move of boolean result 799 LIR_Opr result = rlock_result(x); 800 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), 801 result, as_BasicType(type)); 802 if (type == objectType) { // Write-barrier needed for Object fields. 803 // Seems to be precise 804 post_barrier(addr, val.result()); 805 } 806 } 807 808 809 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { 810 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); 811 812 if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog || 813 x->id() == vmIntrinsics::_dcos || x->id() == vmIntrinsics::_dsin) { 814 do_LibmIntrinsic(x); 815 return; 816 } 817 818 LIRItem value(x->argument_at(0), this); 819 820 bool use_fpu = false; 821 if (UseSSE >= 2) { 822 switch (x->id()) { 823 case vmIntrinsics::_dtan: 824 case vmIntrinsics::_dlog10: 825 case vmIntrinsics::_dpow: 826 use_fpu = true; 827 break; 828 } 829 } else { 830 value.set_destroys_register(); 831 } 832 833 value.load_item(); 834 835 LIR_Opr calc_input = value.result(); 836 LIR_Opr calc_input2 = NULL; 837 if (x->id() == vmIntrinsics::_dpow) { 838 LIRItem extra_arg(x->argument_at(1), this); 839 if (UseSSE < 2) { 840 extra_arg.set_destroys_register(); 841 } 842 extra_arg.load_item(); 843 calc_input2 = extra_arg.result(); 844 } 845 LIR_Opr calc_result = rlock_result(x); 846 847 // sin, cos, pow and exp need two free fpu stack slots, so register 852 if (use_fpu) { 853 LIR_Opr tmp = FrameMap::fpu0_double_opr; 854 int tmp_start = 1; 855 if (calc_input2 != NULL) { 856 __ move(calc_input2, tmp); 857 tmp_start = 2; 858 calc_input2 = tmp; 859 } 860 __ move(calc_input, tmp); 861 862 calc_input = tmp; 863 calc_result = tmp; 864 865 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start); 866 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1); 867 } 868 869 switch(x->id()) { 870 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 871 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 872 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; 873 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; 874 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; 875 default: ShouldNotReachHere(); 876 } 877 878 if (use_fpu) { 879 __ move(calc_result, x->operand()); 880 } 881 } 882 883 void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { 884 LIRItem value(x->argument_at(0), this); 885 value.set_destroys_register(); 886 887 LIR_Opr calc_result = rlock_result(x); 888 LIR_Opr result_reg = result_register_for(x->type()); 889 890 BasicTypeList signature(1); 891 signature.append(T_DOUBLE); 892 CallingConvention* cc = frame_map()->c_calling_convention(&signature); 893 894 value.load_item_force(cc->at(0)); 895 896 #ifndef _LP64 897 LIR_Opr tmp = FrameMap::fpu0_double_opr; 898 result_reg = tmp; 899 switch(x->id()) { 900 case vmIntrinsics::_dexp: 901 if (VM_Version::supports_sse2()) { 902 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 903 } else { 904 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); 905 } 906 break; 907 case vmIntrinsics::_dlog: 908 if (VM_Version::supports_sse2()) { 909 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 910 } else { 911 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); 912 } 913 break; 914 case vmIntrinsics::_dsin: 915 if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) { 916 __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); 917 } else { 918 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args()); 919 } 920 break; 921 case vmIntrinsics::_dcos: 922 if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) { 923 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); 924 } else { 925 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); 926 } 927 break; 928 default: ShouldNotReachHere(); 929 } 930 #else 931 switch (x->id()) { 932 case vmIntrinsics::_dexp: 933 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 934 break; 935 case vmIntrinsics::_dlog: 936 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 937 break; 938 case vmIntrinsics::_dsin: 939 if (StubRoutines::dsin() != NULL) { 940 __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); 941 } else { 942 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args()); 943 } 944 break; 945 case vmIntrinsics::_dcos: 946 if (StubRoutines::dcos() != NULL) { 947 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); 948 } else { 949 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); 950 } 951 break; 952 } 953 #endif 954 __ move(result_reg, calc_result); 955 } 956 957 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { 958 assert(x->number_of_arguments() == 5, "wrong type"); 959 960 // Make all state_for calls early since they can emit code 961 CodeEmitInfo* info = state_for(x, x->state()); 962 963 LIRItem src(x->argument_at(0), this); 964 LIRItem src_pos(x->argument_at(1), this); 965 LIRItem dst(x->argument_at(2), this); 966 LIRItem dst_pos(x->argument_at(3), this); 967 LIRItem length(x->argument_at(4), this); 968 969 // operands for arraycopy must use fixed registers, otherwise 970 // LinearScan will fail allocation (because arraycopy always needs a |