ART: Add Math cutouts

Add sin, cos and pow to unstarted runtime. Add tests for some
very specific values that are seen.

Allows to compile-time initialize:
* android.graphics.drawable.RippleForeground
* android.widget.EdgeEffect

Bug: 27265238

(cherry picked from commit 8c5889a3bdefd7dc84494ec824d495913f2362a9)

Change-Id: I0360a078e7dc9d2a176ec1cf2d8dbb242da1c83e
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 100a446..b26635c 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -802,5 +802,65 @@
   ShadowFrame::DeleteDeoptimizedFrame(tmp);
 }
 
+TEST_F(UnstartedRuntimeTest, Sin) {
+  Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
+
+  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
+
+  // Test an important value, PI/6. That's the one we see in practice.
+  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
+  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
+
+  JValue result;
+  UnstartedMathSin(self, tmp, &result, 0);
+
+  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
+  EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
+
+  ShadowFrame::DeleteDeoptimizedFrame(tmp);
+}
+
+TEST_F(UnstartedRuntimeTest, Cos) {
+  Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
+
+  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
+
+  // Test an important value, PI/6. That's the one we see in practice.
+  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
+  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
+
+  JValue result;
+  UnstartedMathCos(self, tmp, &result, 0);
+
+  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
+  EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
+
+  ShadowFrame::DeleteDeoptimizedFrame(tmp);
+}
+
+TEST_F(UnstartedRuntimeTest, Pow) {
+  Thread* self = Thread::Current();
+  ScopedObjectAccess soa(self);
+
+  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
+
+  // Test an important pair.
+  constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
+  constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
+
+  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
+  tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
+
+  JValue result;
+  UnstartedMathPow(self, tmp, &result, 0);
+
+  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
+  EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
+
+  ShadowFrame::DeleteDeoptimizedFrame(tmp);
+}
+
 }  // namespace interpreter
 }  // namespace art