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