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 849 // two temporary operands 850 LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0); 851 LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1); 852 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) { 893 LIRItem value1(x->argument_at(1), this); 894 895 value1.set_destroys_register(); 896 897 BasicTypeList signature(2); 898 signature.append(T_DOUBLE); 899 signature.append(T_DOUBLE); 900 cc = frame_map()->c_calling_convention(&signature); 901 value.load_item_force(cc->at(0)); 902 value1.load_item_force(cc->at(1)); 903 } else { 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 | 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 || x->id() == vmIntrinsics::_dtan || 816 x->id() == vmIntrinsics::_dlog10) { 817 do_LibmIntrinsic(x); 818 return; 819 } 820 821 LIRItem value(x->argument_at(0), this); 822 823 bool use_fpu = false; 824 if (UseSSE < 2) { 825 value.set_destroys_register(); 826 } 827 value.load_item(); 828 829 LIR_Opr calc_input = value.result(); 830 LIR_Opr calc_result = rlock_result(x); 831 832 switch(x->id()) { 833 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 834 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 835 default: ShouldNotReachHere(); 836 } 837 838 if (use_fpu) { 839 __ move(calc_result, x->operand()); 840 } 841 } 842 843 void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { 844 LIRItem value(x->argument_at(0), this); 845 value.set_destroys_register(); 846 847 LIR_Opr calc_result = rlock_result(x); 848 LIR_Opr result_reg = result_register_for(x->type()); 849 850 CallingConvention* cc = NULL; 851 852 if (x->id() == vmIntrinsics::_dpow) { 853 LIRItem value1(x->argument_at(1), this); 854 855 value1.set_destroys_register(); 856 857 BasicTypeList signature(2); 858 signature.append(T_DOUBLE); 859 signature.append(T_DOUBLE); 860 cc = frame_map()->c_calling_convention(&signature); 861 value.load_item_force(cc->at(0)); 862 value1.load_item_force(cc->at(1)); 863 } else { 864 BasicTypeList signature(1); 865 signature.append(T_DOUBLE); 866 cc = frame_map()->c_calling_convention(&signature); 867 value.load_item_force(cc->at(0)); 868 } 869 870 #ifndef _LP64 871 LIR_Opr tmp = FrameMap::fpu0_double_opr; 872 result_reg = tmp; 873 switch(x->id()) { 874 case vmIntrinsics::_dexp: 875 if (StubRoutines::dexp() != NULL) { 876 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 877 } else { 878 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); 879 } 880 break; 881 case vmIntrinsics::_dlog: 882 if (StubRoutines::dlog() != NULL) { 883 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 884 } else { 885 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); 886 } 887 break; 888 case vmIntrinsics::_dlog10: 889 if (StubRoutines::dlog10() != NULL) { 890 __ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args()); 891 } else { 892 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args()); 893 } 894 break; 895 case vmIntrinsics::_dpow: 896 if (StubRoutines::dpow() != NULL) { 897 __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); 898 } else { 899 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); 900 } 901 break; 902 case vmIntrinsics::_dsin: 903 if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) { 904 __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); 905 } else { 906 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args()); 907 } 908 break; 909 case vmIntrinsics::_dcos: 910 if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) { 911 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); 912 } else { 913 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); 914 } 915 break; 916 case vmIntrinsics::_dtan: 917 if (StubRoutines::dtan() != NULL) { 918 __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args()); 919 } else { 920 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args()); 921 } 922 break; 923 default: ShouldNotReachHere(); 924 } 925 #else 926 switch (x->id()) { 927 case vmIntrinsics::_dexp: 928 if (StubRoutines::dexp() != NULL) { 929 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 930 } else { 931 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); 932 } 933 break; 934 case vmIntrinsics::_dlog: 935 if (StubRoutines::dlog() != NULL) { 936 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 937 } else { 938 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); 939 } 940 break; 941 case vmIntrinsics::_dlog10: 942 if (StubRoutines::dlog10() != NULL) { 943 __ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args()); 944 } else { 945 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args()); 946 } 947 break; 948 case vmIntrinsics::_dpow: 949 if (StubRoutines::dpow() != NULL) { 950 __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); 951 } else { 952 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); 953 } 954 break; 955 case vmIntrinsics::_dsin: 956 if (StubRoutines::dsin() != NULL) { 957 __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); 958 } else { 959 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args()); 960 } 961 break; 962 case vmIntrinsics::_dcos: 963 if (StubRoutines::dcos() != NULL) { 964 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); 965 } else { 966 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); 967 } 968 break; 969 case vmIntrinsics::_dtan: 970 if (StubRoutines::dtan() != NULL) { 971 __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args()); 972 } else { 973 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), 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 |