diff options
author | Lazar Trsic <Lazar.Trsic@imgtec.com> | 2015-06-24 16:30:21 +0200 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-06-24 22:16:54 -0700 |
commit | 559b1cc279deb9299414ddd46595bb8bca7fa090 (patch) | |
tree | c9e11fb2c491522f16674719926ed2d69a392787 /compiler | |
parent | 2eb85431142f5f45f5f5b3dd67dad42bb1dc4a8a (diff) | |
download | art-559b1cc279deb9299414ddd46595bb8bca7fa090.zip art-559b1cc279deb9299414ddd46595bb8bca7fa090.tar.gz art-559b1cc279deb9299414ddd46595bb8bca7fa090.tar.bz2 |
[MIPS64] JNI Compiler: Sign-extend int function arguments
MIPS n64 ABI differs from arm64. Arguments smaller than the 8B stack
slot need to be sign-extended.
Use combination (lw,sd), instead of (lw,sw) for 4B values.
Change fixes software keyboard crash on mips64.
Bug: 21555893
(cherry picked from commit f652d605753f1387e7797461b47116c5dcdf928d)
Change-Id: I7574d37f6039e9e8c9e0047254be71d28d4c829a
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/jni/jni_compiler_test.cc | 46 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.cc | 8 |
2 files changed, 50 insertions, 4 deletions
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc index e98e572..f3bda2f 100644 --- a/compiler/jni/jni_compiler_test.cc +++ b/compiler/jni/jni_compiler_test.cc @@ -165,6 +165,7 @@ class JniCompilerTest : public CommonCompilerTest { void StackArgsIntsFirstImpl(); void StackArgsFloatsFirstImpl(); void StackArgsMixedImpl(); + void StackArgsSignExtendedMips64Impl(); JNIEnv* env_; jmethodID jmethod_; @@ -1715,4 +1716,49 @@ void JniCompilerTest::StackArgsMixedImpl() { JNI_TEST(StackArgsMixed) +void Java_MyClassNatives_stackArgsSignExtendedMips64(JNIEnv*, jclass, jint i1, jint i2, jint i3, + jint i4, jint i5, jint i6, jint i7, jint i8) { + EXPECT_EQ(i1, 1); + EXPECT_EQ(i2, 2); + EXPECT_EQ(i3, 3); + EXPECT_EQ(i4, 4); + EXPECT_EQ(i5, 5); + EXPECT_EQ(i6, 6); + EXPECT_EQ(i7, 7); + EXPECT_EQ(i8, -8); + +#if defined(__mips__) && defined(__LP64__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + // Mips64 ABI requires that arguments passed through stack be sign-extended 8B slots. + // First 8 arguments are passed through registers, check i7 and i8. + uint32_t stack1_high = *(&i7 + 1); + uint32_t stack2_high = *(&i8 + 1); + + EXPECT_EQ(stack1_high, static_cast<uint32_t>(0)); + EXPECT_EQ(stack2_high, static_cast<uint32_t>(0xffffffff)); +#else + LOG(INFO) << "Skipping stackArgsSignExtendedMips64 as there is nothing to be done on " + << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping stackArgsSignExtendedMips64 as there is nothing to be done on " + << kRuntimeISA << std::endl; +#endif +} + +void JniCompilerTest::StackArgsSignExtendedMips64Impl() { + SetUpForTest(true, "stackArgsSignExtendedMips64", "(IIIIIIII)V", + reinterpret_cast<void*>(&Java_MyClassNatives_stackArgsSignExtendedMips64)); + jint i1 = 1; + jint i2 = 2; + jint i3 = 3; + jint i4 = 4; + jint i5 = 5; + jint i6 = 6; + jint i7 = 7; + jint i8 = -8; + + env_->CallStaticVoidMethod(jklass_, jmethod_, i1, i2, i3, i4, i5, i6, i7, i8); +} + +JNI_TEST(StackArgsSignExtendedMips64) + } // namespace art diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index a8b55d1..5e49b93 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -839,7 +839,7 @@ void Mips64Assembler::Copy(FrameOffset dest, FrameOffset src, CHECK(size == 4 || size == 8) << size; if (size == 4) { LoadFromOffset(kLoadWord, scratch.AsGpuRegister(), SP, src.Int32Value()); - StoreToOffset(kStoreWord, scratch.AsGpuRegister(), SP, dest.Int32Value()); + StoreToOffset(kStoreDoubleword, scratch.AsGpuRegister(), SP, dest.Int32Value()); } else if (size == 8) { LoadFromOffset(kLoadDoubleword, scratch.AsGpuRegister(), SP, src.Int32Value()); StoreToOffset(kStoreDoubleword, scratch.AsGpuRegister(), SP, dest.Int32Value()); @@ -855,7 +855,7 @@ void Mips64Assembler::Copy(FrameOffset dest, ManagedRegister src_base, Offset sr if (size == 4) { LoadFromOffset(kLoadWord, scratch, src_base.AsMips64().AsGpuRegister(), src_offset.Int32Value()); - StoreToOffset(kStoreWord, scratch, SP, dest.Int32Value()); + StoreToOffset(kStoreDoubleword, scratch, SP, dest.Int32Value()); } else if (size == 8) { LoadFromOffset(kLoadDoubleword, scratch, src_base.AsMips64().AsGpuRegister(), src_offset.Int32Value()); @@ -871,7 +871,7 @@ void Mips64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameO CHECK(size == 4 || size == 8) << size; if (size == 4) { LoadFromOffset(kLoadWord, scratch, SP, src.Int32Value()); - StoreToOffset(kStoreWord, scratch, dest_base.AsMips64().AsGpuRegister(), + StoreToOffset(kStoreDoubleword, scratch, dest_base.AsMips64().AsGpuRegister(), dest_offset.Int32Value()); } else if (size == 8) { LoadFromOffset(kLoadDoubleword, scratch, SP, src.Int32Value()); @@ -894,7 +894,7 @@ void Mips64Assembler::Copy(ManagedRegister dest, Offset dest_offset, CHECK(size == 4 || size == 8) << size; if (size == 4) { LoadFromOffset(kLoadWord, scratch, src.AsMips64().AsGpuRegister(), src_offset.Int32Value()); - StoreToOffset(kStoreWord, scratch, dest.AsMips64().AsGpuRegister(), dest_offset.Int32Value()); + StoreToOffset(kStoreDoubleword, scratch, dest.AsMips64().AsGpuRegister(), dest_offset.Int32Value()); } else if (size == 8) { LoadFromOffset(kLoadDoubleword, scratch, src.AsMips64().AsGpuRegister(), src_offset.Int32Value()); |