hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
changeset 35146 9ebfec283f56
parent 35094 1e623555b98d
child 35540 e001ad24dcdb
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Dec 23 16:24:19 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Dec 23 21:09:50 2015 -0800
@@ -810,7 +810,8 @@
 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
   assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
 
-  if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog) {
+  if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||
+      x->id() == vmIntrinsics::_dpow) {
     do_LibmIntrinsic(x);
     return;
   }
@@ -824,7 +825,6 @@
       case vmIntrinsics::_dcos:
       case vmIntrinsics::_dtan:
       case vmIntrinsics::_dlog10:
-      case vmIntrinsics::_dpow:
         use_fpu = true;
     }
   } else {
@@ -874,7 +874,6 @@
     case vmIntrinsics::_dcos:   __ cos  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1);                    break;
-    case vmIntrinsics::_dpow:   __ pow  (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
     default:                    ShouldNotReachHere();
   }
 
@@ -890,11 +889,25 @@
   LIR_Opr calc_result = rlock_result(x);
   LIR_Opr result_reg = result_register_for(x->type());
 
-  BasicTypeList signature(1);
-  signature.append(T_DOUBLE);
-  CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+  CallingConvention* cc = NULL;
+
+  if (x->id() == vmIntrinsics::_dpow) {
+    LIRItem value1(x->argument_at(1), this);
+
+    value1.set_destroys_register();
 
-  value.load_item_force(cc->at(0));
+    BasicTypeList signature(2);
+    signature.append(T_DOUBLE);
+    signature.append(T_DOUBLE);
+    cc = frame_map()->c_calling_convention(&signature);
+    value.load_item_force(cc->at(0));
+    value1.load_item_force(cc->at(1));
+  } else {
+    BasicTypeList signature(1);
+    signature.append(T_DOUBLE);
+    cc = frame_map()->c_calling_convention(&signature);
+    value.load_item_force(cc->at(0));
+  }
 
 #ifndef _LP64
   LIR_Opr tmp = FrameMap::fpu0_double_opr;
@@ -915,6 +928,14 @@
         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
       }
       break;
+    case vmIntrinsics::_dpow:
+      if (VM_Version::supports_sse2()) {
+        __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
+      }
+      else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args());
+      }
+      break;
     default:  ShouldNotReachHere();
   }
 #else
@@ -925,6 +946,9 @@
     case vmIntrinsics::_dlog:
       __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
       break;
+    case vmIntrinsics::_dpow:
+      __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
+      break;
   }
 #endif
   __ move(result_reg, calc_result);