diff options
author | Victor Khimenko <khim@google.com> | 2023-04-15 22:49:33 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-15 22:49:33 +0000 |
commit | 1fb1f81d7c18a6a0c923c54aed7cbbc08671d9a2 (patch) | |
tree | cf9c4f673f3fd415c226006bd6d57f7e7c67f2c2 | |
parent | a8d10321cb14a274e92838dc3f30462d213bdb32 (diff) | |
parent | 7520df1208096c2a3d410a48316fe680f46ca34e (diff) | |
download | binary_translation-1fb1f81d7c18a6a0c923c54aed7cbbc08671d9a2.tar.gz |
Merge "interp: Add c.fld compressed instruction." am: 57a120cf65 am: d3178b15d9 am: 7520df1208
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2539370
Change-Id: I30eba954d0ed7bc64a9e1e63ce68d0f92a02f6b8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/decoder.h | 18 | ||||
-rw-r--r-- | interpreter/riscv64/interpreter_test.cc | 40 |
2 files changed, 58 insertions, 0 deletions
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, 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 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, 2, 5>(); uint8_t high_imm = GetBits<uint8_t, 12, 1>(); 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<uint8_t*>(&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; |