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