diff options
author | Victor Khimenko <khim@google.com> | 2023-04-19 22:47:15 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-19 22:47:15 +0000 |
commit | ecd1d77d081136e2eb9d4fa246abb62ad5ebb0e1 (patch) | |
tree | 10ed290d78eccee51aa23bf4e625aad1282f8f87 | |
parent | ea57f6c32bbf10c613f14dc957cb130df07147b9 (diff) | |
parent | b1638618edcbc01ccf5661cd33d410e1c071d813 (diff) | |
download | binary_translation-ecd1d77d081136e2eb9d4fa246abb62ad5ebb0e1.tar.gz |
Merge "interp: Add c.Ld compressed instruction." am: b1638618ed
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2548410
Change-Id: Id5fac4e9d812f8b6dabb4616a51ee19982da55b4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/decoder.h | 18 | ||||
-rw-r--r-- | interpreter/riscv64/interpreter_test.cc | 40 |
2 files changed, 58 insertions, 0 deletions
diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h index fd1389a4..dc8303d1 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -435,12 +435,30 @@ class Decoder { case CompressedOpcode::kLw: DecodeCLw(); break; + case CompressedOpcode::kLd: + DecodeCLd(); + break; default: insn_consumer_->Unimplemented(); } return 2; } + void DecodeCLd() { + uint8_t low_imm = GetBits<uint8_t, 5, 2>(); + uint8_t high_imm = GetBits<uint8_t, 10, 3>(); + uint8_t imm = (low_imm << 6 | high_imm << 3); + uint8_t rd = GetBits<uint8_t, 2, 3>(); + uint8_t rs = GetBits<uint8_t, 7, 3>(); + const LoadArgs args = { + .opcode = LoadOpcode::kLd, + .dst = uint8_t(8 + rd), + .src = uint8_t(8 + rs), + .offset = imm, + }; + insn_consumer_->Load(args); + } + void DecodeCLw() { constexpr uint8_t kLwLow[4] = {0x0, 0x40, 0x04, 0x44}; uint8_t low_imm = GetBits<uint8_t, 5, 2>(); diff --git a/interpreter/riscv64/interpreter_test.cc b/interpreter/riscv64/interpreter_test.cc index 1e4034e2..e35b58f3 100644 --- a/interpreter/riscv64/interpreter_test.cc +++ b/interpreter/riscv64/interpreter_test.cc @@ -35,6 +35,14 @@ namespace { class Riscv64InterpreterTest : public ::testing::Test { public: + void InterpretCLd(uint16_t insn_bytes, uint64_t offset) { + auto code_start = ToGuestAddr(&insn_bytes); + state_.cpu.insn_addr = code_start; + SetXReg<8>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&kDataToLoad) - offset)); + InterpretInsn(&state_); + EXPECT_EQ(GetXReg<8>(state_.cpu), kDataToLoad); + } + void InterpretCLw(uint16_t insn_bytes, uint64_t offset) { auto code_start = ToGuestAddr(&insn_bytes); state_.cpu.insn_addr = code_start; @@ -216,6 +224,38 @@ class Riscv64InterpreterTest : public ::testing::Test { ThreadState state_; }; +TEST_F(Riscv64InterpreterTest, CLd) { + union { + uint16_t offset; + struct { + uint8_t : 3; + uint8_t i3_i5 : 3; + uint8_t i6_i7 : 2; + } i_bits; + }; + for (offset = int16_t{0}; offset < int16_t{256}; offset += 8) { + union { + int16_t parcel; + struct { + uint8_t low_opcode : 2; + uint8_t rd : 3; + uint8_t i6_i7 : 2; + uint8_t rs : 3; + uint8_t i3_i5 : 3; + uint8_t high_opcode : 3; + } __attribute__((__packed__)); + } o_bits = { + .low_opcode = 0b00, + .rd = 0, + .i6_i7 = i_bits.i6_i7, + .rs = 0, + .i3_i5 = i_bits.i3_i5, + .high_opcode = 0b011, + }; + InterpretCLd(o_bits.parcel, offset); + } +} + TEST_F(Riscv64InterpreterTest, CLw) { union { uint16_t offset; |