diff options
author | Gaurav Kumar <gauravroy2599@gmail.com> | 2023-04-19 23:06:23 +0530 |
---|---|---|
committer | Gaurav Kumar <gauravroy2599@gmail.com> | 2023-04-19 23:08:50 +0530 |
commit | 0577b0fd425be123a5004d0cb4278e90f3d6e56b (patch) | |
tree | 08e70648a19837c9c426a24a89b7110346175211 | |
parent | 5d31766c2a4676404c7d77d42a9587b00b7072d5 (diff) | |
download | binary_translation-0577b0fd425be123a5004d0cb4278e90f3d6e56b.tar.gz |
interp: Add c.Lw compressed instruction.
Bug: 265372622
Test: berberis_host_tests/berberis_host_test
Change-Id: I0fdbde5761b7eca34badf8be10261ad281ba6a90
-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 677e715e..0e75d425 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -397,12 +397,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 299b6e46..e041fdab 100644 --- a/interpreter/riscv64/interpreter_test.cc +++ b/interpreter/riscv64/interpreter_test.cc @@ -34,6 +34,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; @@ -198,6 +206,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; |