diff options
author | Victor Khimenko <khim@google.com> | 2023-04-19 22:46:25 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-19 22:46:25 +0000 |
commit | ea57f6c32bbf10c613f14dc957cb130df07147b9 (patch) | |
tree | 4bc11d07a61278e78f12cbc3d4090c6a4c45f150 | |
parent | df06b0c26d542b88e2cb9e6be7aecc05eea18b80 (diff) | |
parent | 724a0aa6ab64041798378eb5a40ff87b9ca3f974 (diff) | |
download | binary_translation-ea57f6c32bbf10c613f14dc957cb130df07147b9.tar.gz |
Merge "interp: Add c.Lw compressed instruction." am: 724a0aa6ab
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2548171
Change-Id: I91a11875739509323469d2e0fbee31aa719f1e25
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/decoder.h | 19 | ||||
-rw-r--r-- | interpreter/riscv64/interpreter_test.cc | 43 |
2 files changed, 62 insertions, 0 deletions
diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h index 4041b417..fd1389a4 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -432,12 +432,31 @@ class Decoder { case CompressedOpcode::kFld: DecodeCFld(); break; + case CompressedOpcode::kLw: + DecodeCLw(); + break; default: insn_consumer_->Unimplemented(); } return 2; } + void DecodeCLw() { + constexpr uint8_t kLwLow[4] = {0x0, 0x40, 0x04, 0x44}; + uint8_t low_imm = GetBits<uint8_t, 5, 2>(); + uint8_t high_imm = GetBits<uint8_t, 10, 3>(); + uint8_t imm = (kLwLow[low_imm] | high_imm << 3); + uint8_t rd = GetBits<uint8_t, 2, 3>(); + uint8_t rs = GetBits<uint8_t, 7, 3>(); + const LoadArgs args = { + .opcode = LoadOpcode::kLw, + .dst = uint8_t(8 + rd), + .src = uint8_t(8 + rs), + .offset = imm, + }; + insn_consumer_->Load(args); + } + void DecodeCFld() { uint8_t low_imm = GetBits<uint8_t, 5, 2>(); uint8_t high_imm = GetBits<uint8_t, 10, 3>(); diff --git a/interpreter/riscv64/interpreter_test.cc b/interpreter/riscv64/interpreter_test.cc index cc4a3e3f..1e4034e2 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 InterpretCLw(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), uint64_t(int32_t(kDataToLoad))); + } + void InterpretCFld(uint16_t insn_bytes, uint64_t offset) { auto code_start = ToGuestAddr(&insn_bytes); state_.cpu.insn_addr = code_start; @@ -208,6 +216,41 @@ class Riscv64InterpreterTest : public ::testing::Test { ThreadState state_; }; +TEST_F(Riscv64InterpreterTest, CLw) { + union { + uint16_t offset; + struct { + uint8_t : 2; + uint8_t i2 : 1; + uint8_t i3_i5 : 3; + uint8_t i6 : 1; + } i_bits; + }; + for (offset = uint8_t{0}; offset < uint8_t{128}; offset += 4) { + union { + int16_t parcel; + struct { + uint8_t low_opcode : 2; + uint8_t rd : 3; + uint8_t i6 : 1; + uint8_t i2 : 1; + uint8_t rs : 3; + uint8_t i3_i5 : 3; + uint8_t high_opcode : 3; + } __attribute__((__packed__)); + } o_bits = { + .low_opcode = 0b00, + .rd = 0, + .i6 = i_bits.i6, + .i2 = i_bits.i2, + .rs = 0, + .i3_i5 = i_bits.i3_i5, + .high_opcode = 0b010, + }; + InterpretCLw(o_bits.parcel, offset); + } +} + TEST_F(Riscv64InterpreterTest, CFld) { union { uint16_t offset; |