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());