aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Khimenko <khim@google.com>2023-04-20 18:49:09 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-04-20 18:49:09 +0000
commit0f3c1486c69bd86a17293e99cc31cedea2ad11d0 (patch)
tree342a1c0ab81d7dc6f1e08b222c92052d80dbaeda
parent111b8f6f052a49f6fe276eeeddd34548ec0419c8 (diff)
parent8d717e2886dfc4a2d2df8aeded808721c6ba0cef (diff)
downloadbinary_translation-0f3c1486c69bd86a17293e99cc31cedea2ad11d0.tar.gz
Merge similar compressed instructions am: 447a9c00ca am: 8d717e2886
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2548211 Change-Id: Icf43f5f9a7382348fd7d6a710fd0ecfe3bb2f8b4 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--decoder/include/berberis/decoder/riscv64/decoder.h28
-rw-r--r--interpreter/riscv64/interpreter_test.cc62
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;