Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 6084:6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
Summary: use x87 instructions to implement exp() and pow() in interpreter/c1/c2.
Reviewed-by: kvn, never, twisti
author | roland |
---|---|
date | Tue, 15 May 2012 10:10:23 +0200 |
parents | 5cceda753a4a |
children | 8b0a4867acf0 |
comparison
equal
deleted
inserted
replaced
6057:8f972594effc | 6084:6759698e3140 |
---|---|
821 } | 821 } |
822 } | 822 } |
823 | 823 |
824 | 824 |
825 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { | 825 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { |
826 assert(x->number_of_arguments() == 1, "wrong type"); | 826 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); |
827 LIRItem value(x->argument_at(0), this); | 827 LIRItem value(x->argument_at(0), this); |
828 | 828 |
829 bool use_fpu = false; | 829 bool use_fpu = false; |
830 if (UseSSE >= 2) { | 830 if (UseSSE >= 2) { |
831 switch(x->id()) { | 831 switch(x->id()) { |
832 case vmIntrinsics::_dsin: | 832 case vmIntrinsics::_dsin: |
833 case vmIntrinsics::_dcos: | 833 case vmIntrinsics::_dcos: |
834 case vmIntrinsics::_dtan: | 834 case vmIntrinsics::_dtan: |
835 case vmIntrinsics::_dlog: | 835 case vmIntrinsics::_dlog: |
836 case vmIntrinsics::_dlog10: | 836 case vmIntrinsics::_dlog10: |
837 case vmIntrinsics::_dexp: | |
838 case vmIntrinsics::_dpow: | |
837 use_fpu = true; | 839 use_fpu = true; |
838 } | 840 } |
839 } else { | 841 } else { |
840 value.set_destroys_register(); | 842 value.set_destroys_register(); |
841 } | 843 } |
842 | 844 |
843 value.load_item(); | 845 value.load_item(); |
844 | 846 |
845 LIR_Opr calc_input = value.result(); | 847 LIR_Opr calc_input = value.result(); |
848 LIR_Opr calc_input2 = NULL; | |
849 if (x->id() == vmIntrinsics::_dpow) { | |
850 LIRItem extra_arg(x->argument_at(1), this); | |
851 if (UseSSE < 2) { | |
852 extra_arg.set_destroys_register(); | |
853 } | |
854 extra_arg.load_item(); | |
855 calc_input2 = extra_arg.result(); | |
856 } | |
846 LIR_Opr calc_result = rlock_result(x); | 857 LIR_Opr calc_result = rlock_result(x); |
847 | 858 |
848 // sin and cos need two free fpu stack slots, so register two temporary operands | 859 // sin, cos, pow and exp need two free fpu stack slots, so register |
860 // two temporary operands | |
849 LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0); | 861 LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0); |
850 LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1); | 862 LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1); |
851 | 863 |
852 if (use_fpu) { | 864 if (use_fpu) { |
853 LIR_Opr tmp = FrameMap::fpu0_double_opr; | 865 LIR_Opr tmp = FrameMap::fpu0_double_opr; |
866 int tmp_start = 1; | |
867 if (calc_input2 != NULL) { | |
868 __ move(calc_input2, tmp); | |
869 tmp_start = 2; | |
870 calc_input2 = tmp; | |
871 } | |
854 __ move(calc_input, tmp); | 872 __ move(calc_input, tmp); |
855 | 873 |
856 calc_input = tmp; | 874 calc_input = tmp; |
857 calc_result = tmp; | 875 calc_result = tmp; |
858 tmp1 = FrameMap::caller_save_fpu_reg_at(1); | 876 |
859 tmp2 = FrameMap::caller_save_fpu_reg_at(2); | 877 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start); |
878 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1); | |
860 } | 879 } |
861 | 880 |
862 switch(x->id()) { | 881 switch(x->id()) { |
863 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; | 882 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; |
864 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; | 883 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; |
865 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; | 884 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; |
866 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break; | 885 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break; |
867 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; | 886 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; |
868 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break; | 887 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break; |
869 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; | 888 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; |
889 case vmIntrinsics::_dexp: __ exp (calc_input, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; | |
890 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; | |
870 default: ShouldNotReachHere(); | 891 default: ShouldNotReachHere(); |
871 } | 892 } |
872 | 893 |
873 if (use_fpu) { | 894 if (use_fpu) { |
874 __ move(calc_result, x->operand()); | 895 __ move(calc_result, x->operand()); |