diff options
author | 2023-06-21 07:56:45 +0000 | |
---|---|---|
committer | 2023-06-22 15:18:16 +0000 | |
commit | ec64f8bff95b4f592ca04983d4d8ca3c50dfa46a (patch) | |
tree | deb94d357ef27971f7e770adeb3d2869de796617 | |
parent | 914d59c5581152f8b0cc5ec477ff926eddcce7c3 (diff) |
riscv64: Fix FP argument passing in GenericJNI.
Test: run-gtests.sh
Bug: 271573990
Change-Id: I028ac0431ef7b809a49f9b7c78c50003820329d7
-rw-r--r-- | compiler/jni/jni_compiler_test.cc | 5 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 87 |
2 files changed, 46 insertions, 46 deletions
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc index 5ebba7d497..18f86528b7 100644 --- a/compiler/jni/jni_compiler_test.cc +++ b/compiler/jni/jni_compiler_test.cc @@ -2269,11 +2269,6 @@ void Java_MyClassNatives_stackArgsFloatsFirst(JNIEnv*, jclass, jfloat f1, jfloat } void JniCompilerTest::StackArgsFloatsFirstImpl() { - if (check_generic_jni_) { - // FIXME(riscv64): Fix FP argument passing in GenericJNI. - TEST_DISABLED_FOR_RISCV64(); - } - SetUpForTest(true, "stackArgsFloatsFirst", "(FFFFFFFFFFIIIIIIIIII)V", CURRENT_JNI_WRAPPER(Java_MyClassNatives_stackArgsFloatsFirst)); diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 71fff04011..85e03f35ef 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -1341,6 +1341,7 @@ template<class T> class BuildNativeCallFrameStateMachine { public: #if defined(__arm__) static constexpr bool kNativeSoftFloatAbi = true; + static constexpr bool kNativeSoftFloatAfterHardFloat = false; static constexpr size_t kNumNativeGprArgs = 4; // 4 arguments passed in GPRs, r0-r3 static constexpr size_t kNumNativeFprArgs = 0; // 0 arguments passed in FPRs. @@ -1353,6 +1354,7 @@ template<class T> class BuildNativeCallFrameStateMachine { static constexpr bool kNaNBoxing = false; #elif defined(__aarch64__) static constexpr bool kNativeSoftFloatAbi = false; // This is a hard float ABI. + static constexpr bool kNativeSoftFloatAfterHardFloat = false; static constexpr size_t kNumNativeGprArgs = 8; // 8 arguments passed in GPRs. static constexpr size_t kNumNativeFprArgs = 8; // 8 arguments passed in FPRs. @@ -1365,6 +1367,7 @@ template<class T> class BuildNativeCallFrameStateMachine { static constexpr bool kNaNBoxing = false; #elif defined(__riscv) static constexpr bool kNativeSoftFloatAbi = false; + static constexpr bool kNativeSoftFloatAfterHardFloat = true; static constexpr size_t kNumNativeGprArgs = 8; static constexpr size_t kNumNativeFprArgs = 8; @@ -1377,6 +1380,7 @@ template<class T> class BuildNativeCallFrameStateMachine { static constexpr bool kNaNBoxing = true; #elif defined(__i386__) static constexpr bool kNativeSoftFloatAbi = false; // Not using int registers for fp + static constexpr bool kNativeSoftFloatAfterHardFloat = false; static constexpr size_t kNumNativeGprArgs = 0; // 0 arguments passed in GPRs. static constexpr size_t kNumNativeFprArgs = 0; // 0 arguments passed in FPRs. @@ -1389,6 +1393,7 @@ template<class T> class BuildNativeCallFrameStateMachine { static constexpr bool kNaNBoxing = false; #elif defined(__x86_64__) static constexpr bool kNativeSoftFloatAbi = false; // This is a hard float ABI. + static constexpr bool kNativeSoftFloatAfterHardFloat = false; static constexpr size_t kNumNativeGprArgs = 6; // 6 arguments passed in GPRs. static constexpr size_t kNumNativeFprArgs = 8; // 8 arguments passed in FPRs. @@ -1507,30 +1512,30 @@ template<class T> class BuildNativeCallFrameStateMachine { return fpr_index_ > 0; } - void AdvanceFloat(float val) { + void AdvanceFloat(uint32_t val) { if (kNativeSoftFloatAbi) { - AdvanceInt(bit_cast<uint32_t, float>(val)); - } else { - if (HaveFloatFpr()) { - fpr_index_--; - if (kRegistersNeededForDouble == 1) { - if (kNaNBoxing) { - // NaN boxing: no widening, just use the bits, but reset upper bits to 1s. - // See e.g. RISC-V manual, D extension, section "NaN Boxing of Narrower Values". - PushFpr8(0xFFFFFFFF00000000lu | static_cast<uint64_t>(bit_cast<uint32_t, float>(val))); - } else { - // No widening, just use the bits. - PushFpr8(static_cast<uint64_t>(bit_cast<uint32_t, float>(val))); - } + AdvanceInt(val); + } else if (HaveFloatFpr()) { + fpr_index_--; + if (kRegistersNeededForDouble == 1) { + if (kNaNBoxing) { + // NaN boxing: no widening, just use the bits, but reset upper bits to 1s. + // See e.g. RISC-V manual, D extension, section "NaN Boxing of Narrower Values". + PushFpr8(UINT64_C(0xFFFFFFFF00000000) | static_cast<uint64_t>(val)); } else { - PushFpr4(val); + // No widening, just use the bits. + PushFpr8(static_cast<uint64_t>(val)); } } else { - // FIXME(riscv64): Excessive FP args can be passed in available GPRs. - stack_entries_++; - PushStack(static_cast<uintptr_t>(bit_cast<uint32_t, float>(val))); - fpr_index_ = 0; + PushFpr4(val); } + } else if (kNativeSoftFloatAfterHardFloat) { + // After using FP arg registers, pass FP args in general purpose registers or on the stack. + AdvanceInt(val); + } else { + stack_entries_++; + PushStack(static_cast<uintptr_t>(val)); + fpr_index_ = 0; } } @@ -1553,30 +1558,30 @@ template<class T> class BuildNativeCallFrameStateMachine { void AdvanceDouble(uint64_t val) { if (kNativeSoftFloatAbi) { AdvanceLong(val); + } else if (HaveDoubleFpr()) { + if (DoubleFprNeedsPadding()) { + PushFpr4(0); + fpr_index_--; + } + PushFpr8(val); + fpr_index_ -= kRegistersNeededForDouble; + } else if (kNativeSoftFloatAfterHardFloat) { + // After using FP arg registers, pass FP args in general purpose registers or on the stack. + AdvanceLong(val); } else { - if (HaveDoubleFpr()) { - if (DoubleFprNeedsPadding()) { - PushFpr4(0); - fpr_index_--; - } - PushFpr8(val); - fpr_index_ -= kRegistersNeededForDouble; + if (DoubleStackNeedsPadding()) { + PushStack(0); + stack_entries_++; + } + if (kRegistersNeededForDouble == 1) { + PushStack(static_cast<uintptr_t>(val)); + stack_entries_++; } else { - // FIXME(riscv64): Excessive FP args can be passed in available GPRs. - if (DoubleStackNeedsPadding()) { - PushStack(0); - stack_entries_++; - } - if (kRegistersNeededForDouble == 1) { - PushStack(static_cast<uintptr_t>(val)); - stack_entries_++; - } else { - PushStack(static_cast<uintptr_t>(val & 0xFFFFFFFF)); - PushStack(static_cast<uintptr_t>((val >> 32) & 0xFFFFFFFF)); - stack_entries_ += 2; - } - fpr_index_ = 0; + PushStack(static_cast<uintptr_t>(val & 0xFFFFFFFF)); + PushStack(static_cast<uintptr_t>((val >> 32) & 0xFFFFFFFF)); + stack_entries_ += 2; } + fpr_index_ = 0; } } @@ -1915,7 +1920,7 @@ void BuildGenericJniFrameVisitor::Visit() { break; } case Primitive::kPrimFloat: - sm_.AdvanceFloat(*reinterpret_cast<float*>(GetParamAddress())); + sm_.AdvanceFloat(*reinterpret_cast<uint32_t*>(GetParamAddress())); current_vreg_ += 1u; break; case Primitive::kPrimBoolean: // Fall-through. |