diff options
author | Victor Khimenko <khim@google.com> | 2023-04-20 21:00:45 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-20 21:00:45 +0000 |
commit | 0d40e871dcc724c9601ed1b667008bc6505f22e0 (patch) | |
tree | 342a1c0ab81d7dc6f1e08b222c92052d80dbaeda | |
parent | 15879cbdf05df529cdf1ff825fded8b85a6607c7 (diff) | |
parent | 9fb7ea80ec752459b4c273748aba2d61f716349d (diff) | |
download | binary_translation-0d40e871dcc724c9601ed1b667008bc6505f22e0.tar.gz |
Merge similar compressed instructions am: 447a9c00ca am: 8d717e2886 am: 0f3c1486c6 am: 9fb7ea80ec
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2548211
Change-Id: I0f34386c745cba49641ce4b4508cd75f986cbcc9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | decoder/include/berberis/decoder/riscv64/decoder.h | 28 | ||||
-rw-r--r-- | interpreter/riscv64/interpreter_test.cc | 62 |
2 files changed, 26 insertions, 64 deletions
diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h index dc8303d1..e91ee18f 100644 --- a/decoder/include/berberis/decoder/riscv64/decoder.h +++ b/decoder/include/berberis/decoder/riscv64/decoder.h @@ -430,13 +430,13 @@ class Decoder { DecodeCAddi(); break; case CompressedOpcode::kFld: - DecodeCFld(); + DecodeCLoadStore<LoadFpArgs, LoadFpOpcode::kFld, &InsnConsumer::Load>(); break; case CompressedOpcode::kLw: DecodeCLw(); break; case CompressedOpcode::kLd: - DecodeCLd(); + DecodeCLoadStore<LoadArgs, LoadOpcode::kLd, &InsnConsumer::Load>(); break; default: insn_consumer_->Unimplemented(); @@ -444,19 +444,20 @@ class Decoder { return 2; } - void DecodeCLd() { + template <typename Args, auto opcode, void (InsnConsumer::*Op)(const Args&)> + 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 LoadArgs args = { - .opcode = LoadOpcode::kLd, + const Args args = { + .opcode = opcode, .dst = uint8_t(8 + rd), .src = uint8_t(8 + rs), .offset = imm, }; - insn_consumer_->Load(args); + (insn_consumer_->*Op)(args); } void DecodeCLw() { @@ -475,21 +476,6 @@ class Decoder { insn_consumer_->Load(args); } - 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 e35b58f3..c3d2b5f1 100644 --- a/interpreter/riscv64/interpreter_test.cc +++ b/interpreter/riscv64/interpreter_test.cc @@ -35,28 +35,28 @@ namespace { class Riscv64InterpreterTest : public ::testing::Test { public: - void InterpretCLd(uint16_t insn_bytes, uint64_t offset) { + 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(GetXReg<8>(state_.cpu), kDataToLoad); + EXPECT_EQ(GetFReg<8>(state_.cpu), kDataToLoad); } - void InterpretCLw(uint16_t insn_bytes, uint64_t offset) { + void InterpretCLd(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))); + EXPECT_EQ(GetXReg<8>(state_.cpu), kDataToLoad); } - void InterpretCFld(uint16_t insn_bytes, uint64_t offset) { + 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(GetFReg<8>(state_.cpu), kDataToLoad); + EXPECT_EQ(GetXReg<8>(state_.cpu), uint64_t(int32_t(kDataToLoad))); } void InterpretCAddi4spn(uint16_t insn_bytes, uint64_t expected_offset) { @@ -224,38 +224,6 @@ class Riscv64InterpreterTest : public ::testing::Test { ThreadState state_; }; -TEST_F(Riscv64InterpreterTest, CLd) { - 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 = 0b011, - }; - InterpretCLd(o_bits.parcel, offset); - } -} - TEST_F(Riscv64InterpreterTest, CLw) { union { uint16_t offset; @@ -291,7 +259,8 @@ TEST_F(Riscv64InterpreterTest, CLw) { } } -TEST_F(Riscv64InterpreterTest, CFld) { +template <uint16_t opcode, auto execute_instruction_func> +void TestCompressedLoadOrStore(Riscv64InterpreterTest* that) { union { uint16_t offset; struct { @@ -303,26 +272,33 @@ TEST_F(Riscv64InterpreterTest, CFld) { for (offset = int16_t{0}; offset < int16_t{256}; offset += 8) { union { int16_t parcel; - struct { + struct [[gnu::packed]] { 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, + .high_opcode = 0b000, }; - InterpretCFld(o_bits.parcel, offset); + (that->*execute_instruction_func)(o_bits.parcel | opcode, offset); } } +TEST_F(Riscv64InterpreterTest, CompressedLoadAndStores) { + // c.Fld + TestCompressedLoadOrStore<0b001'000'000'00'000'00, &Riscv64InterpreterTest::InterpretCFld>(this); + // c.Ld + TestCompressedLoadOrStore<0b011'000'000'00'000'00, &Riscv64InterpreterTest::InterpretCLd>(this); +} + TEST_F(Riscv64InterpreterTest, CAddi) { union { int8_t offset; |