diff options
| -rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 16 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime_list.h | 3 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime_test.cc | 60 |
3 files changed, 79 insertions, 0 deletions
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 6d00ce1c56..1f473e404c 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -834,6 +834,22 @@ void UnstartedRuntime::UnstartedMathFloor( result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset))); } +void UnstartedRuntime::UnstartedMathSin( + Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { + result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset))); +} + +void UnstartedRuntime::UnstartedMathCos( + Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { + result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset))); +} + +void UnstartedRuntime::UnstartedMathPow( + Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { + result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset), + shadow_frame->GetVRegDouble(arg_offset + 2))); +} + void UnstartedRuntime::UnstartedObjectHashCode( Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset); diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h index 379d76012c..b8553b5771 100644 --- a/runtime/interpreter/unstarted_runtime_list.h +++ b/runtime/interpreter/unstarted_runtime_list.h @@ -43,6 +43,9 @@ V(ThreadLocalGet, "java.lang.Object java.lang.ThreadLocal.get()") \ V(MathCeil, "double java.lang.Math.ceil(double)") \ V(MathFloor, "double java.lang.Math.floor(double)") \ + V(MathSin, "double java.lang.Math.sin(double)") \ + V(MathCos, "double java.lang.Math.cos(double)") \ + V(MathPow, "double java.lang.Math.pow(double, double)") \ V(ObjectHashCode, "int java.lang.Object.hashCode()") \ V(DoubleDoubleToRawLongBits, "long java.lang.Double.doubleToRawLongBits(double)") \ V(DexCacheGetDexNative, "com.android.dex.Dex java.lang.DexCache.getDexNative()") \ diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc index 100a44626b..b26635c854 100644 --- a/runtime/interpreter/unstarted_runtime_test.cc +++ b/runtime/interpreter/unstarted_runtime_test.cc @@ -802,5 +802,65 @@ TEST_F(UnstartedRuntimeTest, ToLowerUpper) { 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 |