diff options
author | 2023-04-24 17:14:34 +0100 | |
---|---|---|
committer | 2023-04-26 16:17:48 +0000 | |
commit | cd7d739deb401a94b02e393aecc0229e6256d792 (patch) | |
tree | 30325306a21c7bf4beaaf4f82966e9434dd9c87f | |
parent | 5150dbe9bcb1fa950f9f3155430413570aaaaf2d (diff) |
riscv64: hand-code trampoline instructions.
We don't have a macro-assembler for riscv64 yet, but we need to
generate trampolines for boot images and encode them in the .oat files.
Bug: b/271573990
Test: cuttlefish boots and uses dexpreopt artifacts
$ lunch aosp_cf_riscv64_phone-userdebug && m
$ launch_cvd --gpu_mode=drm_virgl
# observe no crashes in zygote
# observe that.vdex files are used in logcat
Change-Id: I605e93374e70cde29cdf893b14210f0c60d74129
-rw-r--r-- | compiler/trampolines/trampoline_compiler.cc | 52 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer.cc | 8 |
2 files changed, 54 insertions, 6 deletions
diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc index a122d3c9d3..e542763f82 100644 --- a/compiler/trampolines/trampoline_compiler.cc +++ b/compiler/trampolines/trampoline_compiler.cc @@ -127,6 +127,54 @@ static std::unique_ptr<const std::vector<uint8_t>> CreateTrampoline( } // namespace arm64 #endif // ART_ENABLE_CODEGEN_arm64 +#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; + + return std::move(entry_stub); + } +} +} // namespace riscv64 +#endif // ART_ENABLE_CODEGEN_riscv64 + #ifdef ART_ENABLE_CODEGEN_x86 namespace x86 { static std::unique_ptr<const std::vector<uint8_t>> CreateTrampoline(ArenaAllocator* allocator, @@ -179,6 +227,10 @@ std::unique_ptr<const std::vector<uint8_t>> CreateTrampoline64(InstructionSet is case InstructionSet::kArm64: return arm64::CreateTrampoline(&allocator, abi, offset); #endif +#ifdef ART_ENABLE_CODEGEN_riscv64 + case InstructionSet::kRiscv64: + return riscv64::CreateTrampoline(&allocator, abi, offset); +#endif #ifdef ART_ENABLE_CODEGEN_x86_64 case InstructionSet::kX86_64: return x86_64::CreateTrampoline(&allocator, offset); diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index cfba522632..222a5f4a5f 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -2260,9 +2260,7 @@ size_t OatWriter::InitOatCode(size_t offset) { oat_header_->SetExecutableOffset(offset); size_executable_offset_alignment_ = offset - old_offset; InstructionSet instruction_set = compiler_options_.GetInstructionSet(); - if (GetCompilerOptions().IsBootImage() && primary_oat_file_ && - // TODO(riscv64): remove this when we have compiler support for RISC-V. - instruction_set != InstructionSet::kRiscv64) { + if (GetCompilerOptions().IsBootImage() && primary_oat_file_) { const bool generate_debug_info = GetCompilerOptions().GenerateAnyDebugInfo(); size_t adjusted_offset = offset; @@ -3068,9 +3066,7 @@ size_t OatWriter::WriteBcpBssInfo(OutputStream* out, size_t file_offset, size_t size_t OatWriter::WriteCode(OutputStream* out, size_t file_offset, size_t relative_offset) { InstructionSet instruction_set = compiler_options_.GetInstructionSet(); - if (GetCompilerOptions().IsBootImage() && primary_oat_file_ && - // TODO(riscv64): remove this when we have compiler support for RISC-V. - instruction_set != InstructionSet::kRiscv64) { + if (GetCompilerOptions().IsBootImage() && primary_oat_file_) { #define DO_TRAMPOLINE(field) \ do { \ /* Pad with at least four 0xFFs so we can do DCHECKs in OatQuickMethodHeader */ \ |