aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaurav Kumar <gauravroy2599@gmail.com>2023-04-21 00:10:05 +0530
committerGaurav Kumar <gauravroy2599@gmail.com>2023-04-21 00:37:14 +0530
commit7358ad077e6046160d27b1dc9096e9d8689ad3b7 (patch)
tree73501fbae4ac0470dbd64a5fc73691f3b9c43e0d
parent447a9c00cad71c90e76bb476276ac0edc74cf758 (diff)
downloadbinary_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.h36
-rw-r--r--interpreter/riscv64/interpreter_test.cc30
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) {