diff options
author | 2023-06-13 15:41:26 +0100 | |
---|---|---|
committer | 2023-06-15 11:24:27 +0000 | |
commit | d0918409aad47edaf912e1c3d0e8e8258836ab8b (patch) | |
tree | fb85268d4cdb9991d2009cb9c442c43503ab550b | |
parent | 30313798f5c1153dea3204183acc8f10b1a9665d (diff) |
riscv64: rewrite `CreateTrampoline` using assembler to generate code.
Previously we did not have an assembler for RISC-V, so the instructions
were hardcoded manually. This commit does not change the generated
instructions (aside from using a different temporary register).
Also, fix a clang-tidy error triggered by this commit (add noexcept to
constructor).
Bug: 283082089
Test: boot cuttlefish, observe no crashes in zygote:
$ lunch aosp_cf_riscv64_phone-userdebug && m
$ launch_cvd --gpu_mode=drm_virgl
Test: lunch aosp_arm64-userdebug && m art-tidy
Change-Id: I512a1d408ee3837a4a7631cad6e5da6244b402d4
-rw-r--r-- | compiler/trampolines/trampoline_compiler.cc | 69 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.h | 2 |
2 files changed, 30 insertions, 41 deletions
diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc index e542763f82..3821399e61 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,33 @@ 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*. + __ Loadd(TMP, TR, offset.Int32Value()); + __ Jr(TMP); + 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()); + __ FinalizeInstructions(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 d94433f184..9cb6519601 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: |