810 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { |
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"); |
811 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); |
812 |
812 |
813 if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog || |
813 if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog || |
814 x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos || |
814 x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos || |
815 x->id() == vmIntrinsics::_dsin) { |
815 x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan || |
|
816 x->id() == vmIntrinsics::_dlog10) { |
816 do_LibmIntrinsic(x); |
817 do_LibmIntrinsic(x); |
817 return; |
818 return; |
818 } |
819 } |
819 |
820 |
820 LIRItem value(x->argument_at(0), this); |
821 LIRItem value(x->argument_at(0), this); |
821 |
822 |
822 bool use_fpu = false; |
823 bool use_fpu = false; |
823 if (UseSSE >= 2) { |
824 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(); |
825 value.set_destroys_register(); |
832 } |
826 } |
833 |
|
834 value.load_item(); |
827 value.load_item(); |
835 |
828 |
836 LIR_Opr calc_input = value.result(); |
829 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); |
830 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 |
831 |
870 switch(x->id()) { |
832 switch(x->id()) { |
871 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; |
833 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; |
834 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(); |
835 default: ShouldNotReachHere(); |
876 } |
836 } |
877 |
837 |
878 if (use_fpu) { |
838 if (use_fpu) { |
879 __ move(calc_result, x->operand()); |
839 __ move(calc_result, x->operand()); |
910 #ifndef _LP64 |
870 #ifndef _LP64 |
911 LIR_Opr tmp = FrameMap::fpu0_double_opr; |
871 LIR_Opr tmp = FrameMap::fpu0_double_opr; |
912 result_reg = tmp; |
872 result_reg = tmp; |
913 switch(x->id()) { |
873 switch(x->id()) { |
914 case vmIntrinsics::_dexp: |
874 case vmIntrinsics::_dexp: |
915 if (VM_Version::supports_sse2()) { |
875 if (StubRoutines::dexp() != NULL) { |
916 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); |
876 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); |
917 } else { |
877 } else { |
918 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); |
878 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); |
919 } |
879 } |
920 break; |
880 break; |
921 case vmIntrinsics::_dlog: |
881 case vmIntrinsics::_dlog: |
922 if (VM_Version::supports_sse2()) { |
882 if (StubRoutines::dlog() != NULL) { |
923 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); |
883 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); |
924 } else { |
884 } else { |
925 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); |
885 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); |
926 } |
886 } |
927 break; |
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; |
928 case vmIntrinsics::_dpow: |
895 case vmIntrinsics::_dpow: |
929 if (VM_Version::supports_sse2()) { |
896 if (StubRoutines::dpow() != NULL) { |
930 __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); |
897 __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); |
931 } else { |
898 } else { |
932 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); |
899 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); |
933 } |
900 } |
934 break; |
901 break; |
944 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); |
911 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); |
945 } else { |
912 } else { |
946 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); |
913 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); |
947 } |
914 } |
948 break; |
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; |
949 default: ShouldNotReachHere(); |
923 default: ShouldNotReachHere(); |
950 } |
924 } |
951 #else |
925 #else |
952 switch (x->id()) { |
926 switch (x->id()) { |
953 case vmIntrinsics::_dexp: |
927 case vmIntrinsics::_dexp: |
954 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); |
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 } |
955 break; |
933 break; |
956 case vmIntrinsics::_dlog: |
934 case vmIntrinsics::_dlog: |
|
935 if (StubRoutines::dlog() != NULL) { |
957 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); |
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 } |
958 break; |
947 break; |
959 case vmIntrinsics::_dpow: |
948 case vmIntrinsics::_dpow: |
|
949 if (StubRoutines::dpow() != NULL) { |
960 __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); |
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 } |
961 break; |
954 break; |
962 case vmIntrinsics::_dsin: |
955 case vmIntrinsics::_dsin: |
963 if (StubRoutines::dsin() != NULL) { |
956 if (StubRoutines::dsin() != NULL) { |
964 __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); |
957 __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); |
965 } else { |
958 } else { |
969 case vmIntrinsics::_dcos: |
962 case vmIntrinsics::_dcos: |
970 if (StubRoutines::dcos() != NULL) { |
963 if (StubRoutines::dcos() != NULL) { |
971 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); |
964 __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); |
972 } else { |
965 } else { |
973 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); |
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 } |
974 } |
975 break; |
975 break; |
976 default: ShouldNotReachHere(); |
976 default: ShouldNotReachHere(); |
977 } |
977 } |
978 #endif // _LP64 |
978 #endif // _LP64 |