808 |
808 |
809 |
809 |
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) { |
814 do_LibmIntrinsic(x); |
815 do_LibmIntrinsic(x); |
815 return; |
816 return; |
816 } |
817 } |
817 |
818 |
818 LIRItem value(x->argument_at(0), this); |
819 LIRItem value(x->argument_at(0), this); |
822 switch(x->id()) { |
823 switch(x->id()) { |
823 case vmIntrinsics::_dsin: |
824 case vmIntrinsics::_dsin: |
824 case vmIntrinsics::_dcos: |
825 case vmIntrinsics::_dcos: |
825 case vmIntrinsics::_dtan: |
826 case vmIntrinsics::_dtan: |
826 case vmIntrinsics::_dlog10: |
827 case vmIntrinsics::_dlog10: |
827 case vmIntrinsics::_dpow: |
|
828 use_fpu = true; |
828 use_fpu = true; |
829 } |
829 } |
830 } else { |
830 } else { |
831 value.set_destroys_register(); |
831 value.set_destroys_register(); |
832 } |
832 } |
872 case vmIntrinsics::_dsqrt: __ sqrt (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; |
873 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; |
874 case vmIntrinsics::_dcos: __ cos (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; |
875 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; |
876 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; |
876 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; |
877 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; |
|
878 default: ShouldNotReachHere(); |
877 default: ShouldNotReachHere(); |
879 } |
878 } |
880 |
879 |
881 if (use_fpu) { |
880 if (use_fpu) { |
882 __ move(calc_result, x->operand()); |
881 __ move(calc_result, x->operand()); |
888 value.set_destroys_register(); |
887 value.set_destroys_register(); |
889 |
888 |
890 LIR_Opr calc_result = rlock_result(x); |
889 LIR_Opr calc_result = rlock_result(x); |
891 LIR_Opr result_reg = result_register_for(x->type()); |
890 LIR_Opr result_reg = result_register_for(x->type()); |
892 |
891 |
893 BasicTypeList signature(1); |
892 CallingConvention* cc = NULL; |
894 signature.append(T_DOUBLE); |
893 |
895 CallingConvention* cc = frame_map()->c_calling_convention(&signature); |
894 if (x->id() == vmIntrinsics::_dpow) { |
896 |
895 LIRItem value1(x->argument_at(1), this); |
897 value.load_item_force(cc->at(0)); |
896 |
|
897 value1.set_destroys_register(); |
|
898 |
|
899 BasicTypeList signature(2); |
|
900 signature.append(T_DOUBLE); |
|
901 signature.append(T_DOUBLE); |
|
902 cc = frame_map()->c_calling_convention(&signature); |
|
903 value.load_item_force(cc->at(0)); |
|
904 value1.load_item_force(cc->at(1)); |
|
905 } else { |
|
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 } |
898 |
911 |
899 #ifndef _LP64 |
912 #ifndef _LP64 |
900 LIR_Opr tmp = FrameMap::fpu0_double_opr; |
913 LIR_Opr tmp = FrameMap::fpu0_double_opr; |
901 result_reg = tmp; |
914 result_reg = tmp; |
902 switch(x->id()) { |
915 switch(x->id()) { |
913 } |
926 } |
914 else { |
927 else { |
915 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); |
928 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); |
916 } |
929 } |
917 break; |
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; |
918 default: ShouldNotReachHere(); |
939 default: ShouldNotReachHere(); |
919 } |
940 } |
920 #else |
941 #else |
921 switch (x->id()) { |
942 switch (x->id()) { |
922 case vmIntrinsics::_dexp: |
943 case vmIntrinsics::_dexp: |
923 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); |
944 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); |
924 break; |
945 break; |
925 case vmIntrinsics::_dlog: |
946 case vmIntrinsics::_dlog: |
926 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); |
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()); |
927 break; |
951 break; |
928 } |
952 } |
929 #endif |
953 #endif |
930 __ move(result_reg, calc_result); |
954 __ move(result_reg, calc_result); |
931 } |
955 } |