diff options
author | Gaurav Kumar <gauravroy2599@gmail.com> | 2023-04-21 00:10:05 +0530 |
---|---|---|
committer | Gaurav Kumar <gauravroy2599@gmail.com> | 2023-04-21 00:37:14 +0530 |
commit | 7358ad077e6046160d27b1dc9096e9d8689ad3b7 (patch) | |
tree | 73501fbae4ac0470dbd64a5fc73691f3b9c43e0d | |
parent | 447a9c00cad71c90e76bb476276ac0edc74cf758 (diff) | |
download | binary_translation-7358ad077e6046160d27b1dc9096e9d8689ad3b7.tar.gz |
interp: Add c.Fsd and c.Sd compressed instruction.
Bug: 265372622
Test: berberis_host_tests/berberis_host_test
Change-Id: I3c9bec244db31ea1330144deb4f0815d68cf8fbc
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/decoder.h | 36 | ||||
-rw-r--r-- | interpreter/riscv64/interpreter_test.cc | 30 |
2 files changed, 53 insertions, 13 deletions
diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h index e91ee18f..ec51fe37 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -430,13 +430,19 @@ class Decoder { DecodeCAddi(); break; case CompressedOpcode::kFld: - DecodeCLoadStore<LoadFpArgs, LoadFpOpcode::kFld, &InsnConsumer::Load>(); + DecodeCLoadStore<LoadFpArgs, LoadFpOpcode::kFld, false>(); break; case CompressedOpcode::kLw: DecodeCLw(); break; case CompressedOpcode::kLd: - DecodeCLoadStore<LoadArgs, LoadOpcode::kLd, &InsnConsumer::Load>(); + DecodeCLoadStore<LoadArgs, LoadOpcode::kLd, false>(); + break; + case CompressedOpcode::kFsd: + DecodeCLoadStore<StoreFpArgs, StoreFpOpcode::kFsd, true>(); + break; + case CompressedOpcode::kSd: + DecodeCLoadStore<StoreArgs, StoreOpcode::kSd, true>(); break; default: insn_consumer_->Unimplemented(); @@ -444,20 +450,30 @@ class Decoder { return 2; } - template <typename Args, auto opcode, void (InsnConsumer::*Op)(const Args&)> + template <typename Args, auto opcode, bool kStore> void DecodeCLoadStore() { 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 Args args = { - .opcode = opcode, - .dst = uint8_t(8 + rd), - .src = uint8_t(8 + rs), - .offset = imm, - }; - (insn_consumer_->*Op)(args); + if constexpr (kStore) { + const Args args = { + .opcode = opcode, + .src = uint8_t(8 + rs), + .offset = imm, + .data = uint8_t(8 + rd), + }; + insn_consumer_->Store(args); + } else { + const Args args = { + .opcode = opcode, + .dst = uint8_t(8 + rd), + .src = uint8_t(8 + rs), + .offset = imm, + }; + insn_consumer_->Load(args); + } } void DecodeCLw() { diff --git a/interpreter/riscv64/interpreter_test.cc b/interpreter/riscv64/interpreter_test.cc index c3d2b5f1..742cf028 100644 --- a/interpreter/riscv64/interpreter_test.cc +++ b/interpreter/riscv64/interpreter_test.cc @@ -35,12 +35,32 @@ namespace { class Riscv64InterpreterTest : public ::testing::Test { public: + void InterpretCSd(uint16_t insn_bytes, uint64_t offset) { + auto code_start = ToGuestAddr(&insn_bytes); + state_.cpu.insn_addr = code_start; + store_area_ = 0; + SetXReg<8>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&store_area_) - offset)); + SetXReg<9>(state_.cpu, kDataToLoad); + InterpretInsn(&state_); + EXPECT_EQ(store_area_, kDataToLoad); + } + + void InterpretCFsd(uint16_t insn_bytes, uint64_t offset) { + auto code_start = ToGuestAddr(&insn_bytes); + state_.cpu.insn_addr = code_start; + store_area_ = 0; + SetXReg<8>(state_.cpu, ToGuestAddr(bit_cast<uint8_t*>(&store_area_) - offset)); + SetFReg<9>(state_.cpu, kDataToLoad); + InterpretInsn(&state_); + EXPECT_EQ(store_area_, kDataToLoad); + } + void InterpretCFld(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(GetFReg<8>(state_.cpu), kDataToLoad); + EXPECT_EQ(GetFReg<9>(state_.cpu), kDataToLoad); } void InterpretCLd(uint16_t insn_bytes, uint64_t offset) { @@ -48,7 +68,7 @@ class Riscv64InterpreterTest : public ::testing::Test { 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); + EXPECT_EQ(GetXReg<9>(state_.cpu), kDataToLoad); } void InterpretCLw(uint16_t insn_bytes, uint64_t offset) { @@ -282,7 +302,7 @@ void TestCompressedLoadOrStore(Riscv64InterpreterTest* that) { }; } o_bits = { .low_opcode = 0b00, - .rd = 0, + .rd = 1, .i6_i7 = i_bits.i6_i7, .rs = 0, .i3_i5 = i_bits.i3_i5, @@ -297,6 +317,10 @@ TEST_F(Riscv64InterpreterTest, CompressedLoadAndStores) { TestCompressedLoadOrStore<0b001'000'000'00'000'00, &Riscv64InterpreterTest::InterpretCFld>(this); // c.Ld TestCompressedLoadOrStore<0b011'000'000'00'000'00, &Riscv64InterpreterTest::InterpretCLd>(this); + // c.Fsd + TestCompressedLoadOrStore<0b101'000'000'00'000'00, &Riscv64InterpreterTest::InterpretCFsd>(this); + // c.Sd + TestCompressedLoadOrStore<0b111'000'000'00'000'00, &Riscv64InterpreterTest::InterpretCSd>(this); } TEST_F(Riscv64InterpreterTest, CAddi) { |