MIPS32: Add direct calls to math intrinsics.
- cos - sin - acos - asin
- atan - atan2 - cbrt - cosh
- exp - expm1 - hypot - log
- log10 - nextAfter - sinh - tan
- tanh
Test: run-test --no-prebuild --optimizing 123-inline-execute2
Test: run-test --no-prebuild 123-inline-execute2
Test: run-test --optimizing 123-inline-execute2
Test: run-test 123-inline-execute2
Test: Booted MIPS32R2 and MIPS64R6 emulators.
Note: Ran tests under both emulators, and on CI20 hardware.
Change-Id: I4c1782d609a985ae49737f47c43caa5b0b6a10e3
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 900b00e..4297979 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -2742,6 +2742,204 @@
__ Bind(&done);
}
+static void CreateFPToFPCallLocations(ArenaAllocator* arena, HInvoke* invoke) {
+ LocationSummary* locations = new (arena) LocationSummary(invoke,
+ LocationSummary::kCallOnMainOnly,
+ kIntrinsified);
+ InvokeRuntimeCallingConvention calling_convention;
+
+ locations->SetInAt(0, Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(0)));
+ locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimDouble));
+}
+
+static void CreateFPFPToFPCallLocations(ArenaAllocator* arena, HInvoke* invoke) {
+ LocationSummary* locations = new (arena) LocationSummary(invoke,
+ LocationSummary::kCallOnMainOnly,
+ kIntrinsified);
+ InvokeRuntimeCallingConvention calling_convention;
+
+ locations->SetInAt(0, Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(0)));
+ locations->SetInAt(1, Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(1)));
+ locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimDouble));
+}
+
+static void GenFPToFPCall(HInvoke* invoke, CodeGeneratorMIPS* codegen, QuickEntrypointEnum entry) {
+ LocationSummary* locations = invoke->GetLocations();
+ FRegister in = locations->InAt(0).AsFpuRegister<FRegister>();
+ DCHECK_EQ(in, F12);
+ FRegister out = locations->Out().AsFpuRegister<FRegister>();
+ DCHECK_EQ(out, F0);
+
+ codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc());
+}
+
+static void GenFPFPToFPCall(HInvoke* invoke,
+ CodeGeneratorMIPS* codegen,
+ QuickEntrypointEnum entry) {
+ LocationSummary* locations = invoke->GetLocations();
+ FRegister in0 = locations->InAt(0).AsFpuRegister<FRegister>();
+ DCHECK_EQ(in0, F12);
+ FRegister in1 = locations->InAt(1).AsFpuRegister<FRegister>();
+ DCHECK_EQ(in1, F14);
+ FRegister out = locations->Out().AsFpuRegister<FRegister>();
+ DCHECK_EQ(out, F0);
+
+ codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc());
+}
+
+// static double java.lang.Math.cos(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathCos(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathCos(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickCos);
+}
+
+// static double java.lang.Math.sin(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathSin(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathSin(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickSin);
+}
+
+// static double java.lang.Math.acos(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathAcos(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathAcos(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickAcos);
+}
+
+// static double java.lang.Math.asin(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathAsin(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathAsin(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickAsin);
+}
+
+// static double java.lang.Math.atan(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathAtan(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathAtan(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickAtan);
+}
+
+// static double java.lang.Math.atan2(double y, double x)
+void IntrinsicLocationsBuilderMIPS::VisitMathAtan2(HInvoke* invoke) {
+ CreateFPFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathAtan2(HInvoke* invoke) {
+ GenFPFPToFPCall(invoke, codegen_, kQuickAtan2);
+}
+
+// static double java.lang.Math.cbrt(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathCbrt(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathCbrt(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickCbrt);
+}
+
+// static double java.lang.Math.cosh(double x)
+void IntrinsicLocationsBuilderMIPS::VisitMathCosh(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathCosh(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickCosh);
+}
+
+// static double java.lang.Math.exp(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathExp(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathExp(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickExp);
+}
+
+// static double java.lang.Math.expm1(double x)
+void IntrinsicLocationsBuilderMIPS::VisitMathExpm1(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathExpm1(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickExpm1);
+}
+
+// static double java.lang.Math.hypot(double x, double y)
+void IntrinsicLocationsBuilderMIPS::VisitMathHypot(HInvoke* invoke) {
+ CreateFPFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathHypot(HInvoke* invoke) {
+ GenFPFPToFPCall(invoke, codegen_, kQuickHypot);
+}
+
+// static double java.lang.Math.log(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathLog(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathLog(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickLog);
+}
+
+// static double java.lang.Math.log10(double x)
+void IntrinsicLocationsBuilderMIPS::VisitMathLog10(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathLog10(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickLog10);
+}
+
+// static double java.lang.Math.nextAfter(double start, double direction)
+void IntrinsicLocationsBuilderMIPS::VisitMathNextAfter(HInvoke* invoke) {
+ CreateFPFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathNextAfter(HInvoke* invoke) {
+ GenFPFPToFPCall(invoke, codegen_, kQuickNextAfter);
+}
+
+// static double java.lang.Math.sinh(double x)
+void IntrinsicLocationsBuilderMIPS::VisitMathSinh(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathSinh(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickSinh);
+}
+
+// static double java.lang.Math.tan(double a)
+void IntrinsicLocationsBuilderMIPS::VisitMathTan(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathTan(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickTan);
+}
+
+// static double java.lang.Math.tanh(double x)
+void IntrinsicLocationsBuilderMIPS::VisitMathTanh(HInvoke* invoke) {
+ CreateFPToFPCallLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitMathTanh(HInvoke* invoke) {
+ GenFPToFPCall(invoke, codegen_, kQuickTanh);
+}
+
// Unimplemented intrinsics.
UNIMPLEMENTED_INTRINSIC(MIPS, MathCeil)
@@ -2756,24 +2954,6 @@
UNIMPLEMENTED_INTRINSIC(MIPS, SystemArrayCopyChar)
UNIMPLEMENTED_INTRINSIC(MIPS, SystemArrayCopy)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathCos)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathSin)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathAcos)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathAsin)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathAtan)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathAtan2)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathCbrt)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathCosh)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathExp)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathExpm1)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathHypot)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathLog)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathLog10)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathNextAfter)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathSinh)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathTan)
-UNIMPLEMENTED_INTRINSIC(MIPS, MathTanh)
-
UNIMPLEMENTED_INTRINSIC(MIPS, StringStringIndexOf);
UNIMPLEMENTED_INTRINSIC(MIPS, StringStringIndexOfAfter);
UNIMPLEMENTED_INTRINSIC(MIPS, StringBufferAppend);
diff --git a/runtime/arch/mips/entrypoints_direct_mips.h b/runtime/arch/mips/entrypoints_direct_mips.h
index 937cd1e..1020781 100644
--- a/runtime/arch/mips/entrypoints_direct_mips.h
+++ b/runtime/arch/mips/entrypoints_direct_mips.h
@@ -47,7 +47,24 @@
entrypoint == kQuickCmplFloat ||
entrypoint == kQuickReadBarrierJni ||
entrypoint == kQuickReadBarrierSlow ||
- entrypoint == kQuickReadBarrierForRootSlow;
+ entrypoint == kQuickReadBarrierForRootSlow ||
+ entrypoint == kQuickCos ||
+ entrypoint == kQuickSin ||
+ entrypoint == kQuickAcos ||
+ entrypoint == kQuickAsin ||
+ entrypoint == kQuickAtan ||
+ entrypoint == kQuickAtan2 ||
+ entrypoint == kQuickCbrt ||
+ entrypoint == kQuickCosh ||
+ entrypoint == kQuickExp ||
+ entrypoint == kQuickExpm1 ||
+ entrypoint == kQuickHypot ||
+ entrypoint == kQuickLog ||
+ entrypoint == kQuickLog10 ||
+ entrypoint == kQuickNextAfter ||
+ entrypoint == kQuickSinh ||
+ entrypoint == kQuickTan ||
+ entrypoint == kQuickTanh;
}
} // namespace art
diff --git a/runtime/arch/mips/entrypoints_init_mips.cc b/runtime/arch/mips/entrypoints_init_mips.cc
index 2349620..434e33c 100644
--- a/runtime/arch/mips/entrypoints_init_mips.cc
+++ b/runtime/arch/mips/entrypoints_init_mips.cc
@@ -312,6 +312,42 @@
qpoints->pUshrLong = art_quick_ushr_long;
static_assert(!IsDirectEntrypoint(kQuickUshrLong), "Non-direct C stub marked direct.");
+ // More math.
+ qpoints->pCos = cos;
+ static_assert(IsDirectEntrypoint(kQuickCos), "Direct C stub marked non-direct.");
+ qpoints->pSin = sin;
+ static_assert(IsDirectEntrypoint(kQuickSin), "Direct C stub marked non-direct.");
+ qpoints->pAcos = acos;
+ static_assert(IsDirectEntrypoint(kQuickAcos), "Direct C stub marked non-direct.");
+ qpoints->pAsin = asin;
+ static_assert(IsDirectEntrypoint(kQuickAsin), "Direct C stub marked non-direct.");
+ qpoints->pAtan = atan;
+ static_assert(IsDirectEntrypoint(kQuickAtan), "Direct C stub marked non-direct.");
+ qpoints->pAtan2 = atan2;
+ static_assert(IsDirectEntrypoint(kQuickAtan2), "Direct C stub marked non-direct.");
+ qpoints->pCbrt = cbrt;
+ static_assert(IsDirectEntrypoint(kQuickCbrt), "Direct C stub marked non-direct.");
+ qpoints->pCosh = cosh;
+ static_assert(IsDirectEntrypoint(kQuickCosh), "Direct C stub marked non-direct.");
+ qpoints->pExp = exp;
+ static_assert(IsDirectEntrypoint(kQuickExp), "Direct C stub marked non-direct.");
+ qpoints->pExpm1 = expm1;
+ static_assert(IsDirectEntrypoint(kQuickExpm1), "Direct C stub marked non-direct.");
+ qpoints->pHypot = hypot;
+ static_assert(IsDirectEntrypoint(kQuickHypot), "Direct C stub marked non-direct.");
+ qpoints->pLog = log;
+ static_assert(IsDirectEntrypoint(kQuickLog), "Direct C stub marked non-direct.");
+ qpoints->pLog10 = log10;
+ static_assert(IsDirectEntrypoint(kQuickLog10), "Direct C stub marked non-direct.");
+ qpoints->pNextAfter = nextafter;
+ static_assert(IsDirectEntrypoint(kQuickNextAfter), "Direct C stub marked non-direct.");
+ qpoints->pSinh = sinh;
+ static_assert(IsDirectEntrypoint(kQuickSinh), "Direct C stub marked non-direct.");
+ qpoints->pTan = tan;
+ static_assert(IsDirectEntrypoint(kQuickTan), "Direct C stub marked non-direct.");
+ qpoints->pTanh = tanh;
+ static_assert(IsDirectEntrypoint(kQuickTanh), "Direct C stub marked non-direct.");
+
// Intrinsics
qpoints->pIndexOf = art_quick_indexof;
static_assert(!IsDirectEntrypoint(kQuickIndexOf), "Non-direct C stub marked direct.");