From 5d31766c2a4676404c7d77d42a9587b00b7072d5 Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Sun, 16 Apr 2023 00:58:53 +0530 Subject: interp: Add c.fld compressed instruction. Bug: 265372622 Test: berberis_host_tests/berberis_host_tests Change-Id: I8b8002527401c26206869ba841d233138a155430 --- decoder/include/berberis/decoder/riscv64/decoder.h | 18 ++++++++++ interpreter/riscv64/interpreter_test.cc | 40 ++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h index de0b9d44..677e715e 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -394,12 +394,30 @@ class Decoder { case CompressedOpcode::kAddi: DecodeCAddi(); break; + case CompressedOpcode::kFld: + DecodeCFld(); + break; default: insn_consumer_->Unimplemented(); } return 2; } + void DecodeCFld() { + uint8_t low_imm = GetBits(); + uint8_t high_imm = GetBits(); + uint8_t imm = (low_imm << 6 | high_imm << 3); + uint8_t rd = GetBits(); + uint8_t rs = GetBits(); + const LoadFpArgs args = { + .opcode = LoadFpOpcode::kFld, + .dst = uint8_t(8 + rd), + .src = uint8_t(8 + rs), + .offset = imm, + }; + insn_consumer_->Load(args); + } + void DecodeCAddi() { uint8_t low_imm = GetBits(); uint8_t high_imm = GetBits(); diff --git a/interpreter/riscv64/interpreter_test.cc b/interpreter/riscv64/interpreter_test.cc index b82a2dfa..299b6e46 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 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(&kDataToLoad) - offset)); + InterpretInsn(&state_); + EXPECT_EQ(GetFReg<8>(state_.cpu), kDataToLoad); + } + void InterpretCAddi4spn(uint16_t insn_bytes, uint64_t expected_offset) { auto code_start = ToGuestAddr(&insn_bytes); state_.cpu.insn_addr = code_start; @@ -190,6 +198,38 @@ class Riscv64InterpreterTest : public ::testing::Test { ThreadState state_; }; +TEST_F(Riscv64InterpreterTest, CFld) { + 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 = 0b001, + }; + InterpretCFld(o_bits.parcel, offset); + } +} + TEST_F(Riscv64InterpreterTest, CAddi) { union { int8_t offset; -- cgit v1.2.3