hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
changeset 12739 09f26b73ae66
parent 10562 7d59afed6699
child 12957 f3cc386f349e
equal deleted inserted replaced
12623:09fcb0dc71ad 12739:09f26b73ae66
   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());