changeset 51389:680d04ae76e9

8204289: AARCH64: enable math intrinsics usage in interpreter and C1 Reviewed-by: aph, dsamersoff
author dpochepk
date Mon, 25 Jun 2018 16:31:18 +0300
parents ccb8aa083958
children 7ad092f40454
files src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
diffstat 3 files changed, 140 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp	Mon Jun 25 16:30:49 2018 +0300
+++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp	Mon Jun 25 16:31:18 2018 +0300
@@ -745,6 +745,14 @@
 }
 
 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 ||
+      x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos ||
+      x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan ||
+      x->id() == vmIntrinsics::_dlog10) {
+    do_LibmIntrinsic(x);
+    return;
+  }
   switch (x->id()) {
     case vmIntrinsics::_dabs:
     case vmIntrinsics::_dsqrt: {
@@ -754,61 +762,100 @@
       LIR_Opr dst = rlock_result(x);
 
       switch (x->id()) {
-      case vmIntrinsics::_dsqrt: {
-        __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
-        break;
-      }
-      case vmIntrinsics::_dabs: {
-        __ abs(value.result(), dst, LIR_OprFact::illegalOpr);
-        break;
-      }
+        case vmIntrinsics::_dsqrt: {
+          __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
+          break;
+        }
+        case vmIntrinsics::_dabs: {
+          __ abs(value.result(), dst, LIR_OprFact::illegalOpr);
+          break;
+        }
       }
       break;
     }
-    case vmIntrinsics::_dlog10: // fall through
-    case vmIntrinsics::_dlog: // fall through
-    case vmIntrinsics::_dsin: // fall through
-    case vmIntrinsics::_dtan: // fall through
-    case vmIntrinsics::_dcos: // fall through
-    case vmIntrinsics::_dexp: {
-      assert(x->number_of_arguments() == 1, "wrong type");
+  }
+}
 
-      address runtime_entry = NULL;
-      switch (x->id()) {
-      case vmIntrinsics::_dsin:
-        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
-        break;
-      case vmIntrinsics::_dcos:
-        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
-        break;
-      case vmIntrinsics::_dtan:
-        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
-        break;
-      case vmIntrinsics::_dlog:
-        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
-        break;
-      case vmIntrinsics::_dlog10:
-        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
-        break;
-      case vmIntrinsics::_dexp:
-        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
-        break;
-      default:
-        ShouldNotReachHere();
+void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {
+  LIRItem value(x->argument_at(0), this);
+  value.set_destroys_register();
+
+  LIR_Opr calc_result = rlock_result(x);
+  LIR_Opr result_reg = result_register_for(x->type());
+
+  CallingConvention* cc = NULL;
+
+  if (x->id() == vmIntrinsics::_dpow) {
+    LIRItem value1(x->argument_at(1), this);
+
+    value1.set_destroys_register();
+
+    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));
+  }
+
+  switch (x->id()) {
+    case vmIntrinsics::_dexp:
+      if (StubRoutines::dexp() != NULL) {
+        __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
+      } else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
       }
-
-      LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL);
-      set_result(x, result);
       break;
-    }
-    case vmIntrinsics::_dpow: {
-      assert(x->number_of_arguments() == 2, "wrong type");
-      address runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
-      LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), NULL);
-      set_result(x, result);
+    case vmIntrinsics::_dlog:
+      if (StubRoutines::dlog() != NULL) {
+        __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
+      } else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
+      }
       break;
-    }
+    case vmIntrinsics::_dlog10:
+      if (StubRoutines::dlog10() != NULL) {
+        __ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args());
+      } else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args());
+      }
+      break;
+    case vmIntrinsics::_dpow:
+      if (StubRoutines::dpow() != NULL) {
+        __ 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;
+    case vmIntrinsics::_dsin:
+      if (StubRoutines::dsin() != NULL) {
+        __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
+      } else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
+      }
+      break;
+    case vmIntrinsics::_dcos:
+      if (StubRoutines::dcos() != NULL) {
+        __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
+      } else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
+      }
+      break;
+    case vmIntrinsics::_dtan:
+      if (StubRoutines::dtan() != NULL) {
+        __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args());
+      } else {
+        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args());
+      }
+      break;
+    default:  ShouldNotReachHere();
   }
+  __ move(result_reg, calc_result);
 }
 
 
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Mon Jun 25 16:30:49 2018 +0300
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Mon Jun 25 16:31:18 2018 +0300
@@ -5068,9 +5068,17 @@
       StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
     }
 
-    StubRoutines::_dlog = generate_dlog();
-    StubRoutines::_dsin = generate_dsin_dcos(/* isCos = */ false);
-    StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
+    if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
+      StubRoutines::_dlog = generate_dlog();
+    }
+
+    if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
+      StubRoutines::_dsin = generate_dsin_dcos(/* isCos = */ false);
+    }
+
+    if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
+      StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
+    }
   }
 
   void generate_all() {
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Mon Jun 25 16:30:49 2018 +0300
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Mon Jun 25 16:31:18 2018 +0300
@@ -247,26 +247,54 @@
   address fn;
   switch (kind) {
   case Interpreter::java_lang_math_sin :
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
+    if (StubRoutines::dsin() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dsin());
+    }
     break;
   case Interpreter::java_lang_math_cos :
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
+    if (StubRoutines::dcos() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dcos());
+    }
     break;
   case Interpreter::java_lang_math_tan :
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
+    if (StubRoutines::dtan() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dtan());
+    }
     break;
   case Interpreter::java_lang_math_log :
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
+    if (StubRoutines::dlog() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog());
+    }
     break;
   case Interpreter::java_lang_math_log10 :
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
+    if (StubRoutines::dlog10() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog10());
+    }
     break;
   case Interpreter::java_lang_math_exp :
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
+    if (StubRoutines::dexp() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dexp());
+    }
     break;
   case Interpreter::java_lang_math_pow :
     fpargs = 2;
-    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
+    if (StubRoutines::dpow() == NULL) {
+      fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
+    } else {
+      fn = CAST_FROM_FN_PTR(address, StubRoutines::dpow());
+    }
     break;
   default:
     ShouldNotReachHere();