diff options
author | 2023-06-19 07:37:59 +0000 | |
---|---|---|
committer | 2023-06-21 08:30:35 +0000 | |
commit | 4bf7a0e4e4ba1a8d8dafbf2495c4d3515660777a (patch) | |
tree | 7873eda307d8670c3684bcdb4fa5f6d221aa99de | |
parent | 70bba9c9f5fbba03c62a4542411e1d938375f14e (diff) |
Reland "riscv64: rewrite `CreateTrampoline` using assembler to generate code."
This reverts commit 112c70b6700a042d7152b0c2bf5094464a158931.
Reason for revert: Reland but keep using T0 for `kQuickAbi`
instead of TMP which clashes with the current usage.
Bug: 283082089
Test: run-gtests.sh
Change-Id: Iee28d4010b2bcdaef70f97e745b4a196401e8984
-rw-r--r-- | compiler/trampolines/trampoline_compiler.cc | 70 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.h | 2 |
2 files changed, 31 insertions, 41 deletions
diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc index d128a9eff1..c3b9dbe492 100644 --- a/compiler/trampolines/trampoline_compiler.cc +++ b/compiler/trampolines/trampoline_compiler.cc @@ -28,6 +28,10 @@ #include "utils/arm64/assembler_arm64.h" #endif +#ifdef ART_ENABLE_CODEGEN_riscv64 +#include "utils/riscv64/assembler_riscv64.h" +#endif + #ifdef ART_ENABLE_CODEGEN_x86 #include "utils/x86/assembler_x86.h" #endif @@ -129,48 +133,34 @@ static std::unique_ptr<const std::vector<uint8_t>> CreateTrampoline( #ifdef ART_ENABLE_CODEGEN_riscv64 namespace riscv64 { -static std::unique_ptr<const std::vector<uint8_t>> CreateTrampoline( - ArenaAllocator* /*allocator*/, EntryPointCallingConvention abi, ThreadOffset64 offset) { - if (abi == kJniAbi) { - // TODO(riscv64): implement this properly once we have macro-assembler for RISC-V. - std::unique_ptr<std::vector<uint8_t>> entry_stub(new std::vector<uint8_t>(2)); - uint8_t* bytes = entry_stub->data(); - - // 0000 unimp - bytes[0] = 0x00; - bytes[1] = 0x00; - - return std::move(entry_stub); - } else { - CHECK_LE(offset.Int32Value(), 0x7ff); - uint8_t offset_hi = (offset.Int32Value() & 0x7ff) >> 4; - uint8_t offset_lo = (offset.Int32Value() & 0xf) << 4; - - std::unique_ptr<std::vector<uint8_t>> entry_stub(new std::vector<uint8_t>(6)); - uint8_t* bytes = entry_stub->data(); - - if (abi == kInterpreterAbi) { - // Thread* is first argument (A0) in interpreter ABI. - // xxx53283 ld t0, xxx(a0) - bytes[0] = 0x83; - bytes[1] = 0x32; - bytes[2] = offset_lo | 0x05; - bytes[3] = offset_hi; - } else { - // abi == kQuickAbi: TR holds Thread*. - // xxx4b283 ld t0, xxx(s1) - bytes[0] = 0x83; - bytes[1] = 0xb2; - bytes[2] = offset_lo | 0x04; - bytes[3] = offset_hi; - } - - // 8282 jr t0 - bytes[4] = 0x82; - bytes[5] = 0x82; +static std::unique_ptr<const std::vector<uint8_t>> CreateTrampoline(ArenaAllocator* allocator, + EntryPointCallingConvention abi, + ThreadOffset64 offset) { + Riscv64Assembler assembler(allocator); - return std::move(entry_stub); + switch (abi) { + case kInterpreterAbi: // Thread* is first argument (A0) in interpreter ABI. + __ Loadd(TMP, A0, offset.Int32Value()); + __ Jr(TMP); + break; + case kJniAbi: // Load via Thread* held in JNIEnv* in first argument (A0). + // TODO(riscv64): implement this. + __ Unimp(); + break; + case kQuickAbi: // TR holds Thread*. + // FIXME(riscv64): Do not clobber the hidden arg T0, see the JNI calling convention. + __ Loadd(T0, TR, offset.Int32Value()); + __ Jr(T0); + break; } + + __ FinalizeCode(); + size_t cs = __ CodeSize(); + std::unique_ptr<std::vector<uint8_t>> entry_stub(new std::vector<uint8_t>(cs)); + MemoryRegion code(entry_stub->data(), entry_stub->size()); + __ CopyInstructions(code); + + return std::move(entry_stub); } } // namespace riscv64 #endif // ART_ENABLE_CODEGEN_riscv64 diff --git a/compiler/utils/riscv64/assembler_riscv64.h b/compiler/utils/riscv64/assembler_riscv64.h index fc0b44232b..e7a8701494 100644 --- a/compiler/utils/riscv64/assembler_riscv64.h +++ b/compiler/utils/riscv64/assembler_riscv64.h @@ -66,7 +66,7 @@ class Riscv64Label : public Label { public: Riscv64Label() : prev_branch_id_(kNoPrevBranchId) {} - Riscv64Label(Riscv64Label&& src) + Riscv64Label(Riscv64Label&& src) noexcept : Label(std::move(src)), prev_branch_id_(src.prev_branch_id_) {} private: |