aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Khimenko <khim@google.com>2023-04-19 22:46:25 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-04-19 22:46:25 +0000
commitea57f6c32bbf10c613f14dc957cb130df07147b9 (patch)
tree4bc11d07a61278e78f12cbc3d4090c6a4c45f150
parentdf06b0c26d542b88e2cb9e6be7aecc05eea18b80 (diff)
parent724a0aa6ab64041798378eb5a40ff87b9ca3f974 (diff)
downloadbinary_translation-ea57f6c32bbf10c613f14dc957cb130df07147b9.tar.gz
Merge "interp: Add c.Lw compressed instruction." am: 724a0aa6ab
Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/binary_translation/+/2548171 Change-Id: I91a11875739509323469d2e0fbee31aa719f1e25 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--decoder/include/berberis/decoder/riscv64/decoder.h19
-rw-r--r--interpreter/riscv64/interpreter_test.cc43
2 files changed, 62 insertions, 0 deletions
diff --git a/decoder/include/berberis/decoder/riscv64/decoder.h b/decoder/include/berberis/decoder/riscv64/decoder.h
index 4041b417..fd1389a4 100644
--- a/decoder/include/berberis/decoder/riscv64/decoder.h
+++ b/decoder/include/berberis/decoder/riscv64/decoder.h
@@ -432,12 +432,31 @@ class Decoder {
case CompressedOpcode::kFld:
DecodeCFld();
break;
+ case CompressedOpcode::kLw:
+ DecodeCLw();
+ break;
default:
insn_consumer_->Unimplemented();
}
return 2;
}
+ void DecodeCLw() {
+ constexpr uint8_t kLwLow[4] = {0x0, 0x40, 0x04, 0x44};
+ uint8_t low_imm = GetBits<uint8_t, 5, 2>();
+ uint8_t high_imm = GetBits<uint8_t, 10, 3>();
+ uint8_t imm = (kLwLow[low_imm] | high_imm << 3);
+ uint8_t rd = GetBits<uint8_t, 2, 3>();
+ uint8_t rs = GetBits<uint8_t, 7, 3>();
+ const LoadArgs args = {
+ .opcode = LoadOpcode::kLw,
+ .dst = uint8_t(8 + rd),
+ .src = uint8_t(8 + rs),
+ .offset = imm,
+ };
+ insn_consumer_->Load(args);
+ }
+
void DecodeCFld() {
uint8_t low_imm = GetBits<uint8_t, 5, 2>();
uint8_t high_imm = GetBits<uint8_t, 10, 3>();
diff --git a/interpreter/riscv64/interpreter_test.cc b/interpreter/riscv64/interpreter_test.cc
index cc4a3e3f..1e4034e2 100644
--- a/interpreter/riscv64/interpreter_test.cc
+++ b/interpreter/riscv64/interpreter_test.cc
@@ -35,6 +35,14 @@ namespace {
class Riscv64InterpreterTest : public ::testing::Test {
public:
+ 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(GetXReg<8>(state_.cpu), uint64_t(int32_t(kDataToLoad)));
+ }
+
void InterpretCFld(uint16_t insn_bytes, uint64_t offset) {
auto code_start = ToGuestAddr(&insn_bytes);
state_.cpu.insn_addr = code_start;
@@ -208,6 +216,41 @@ class Riscv64InterpreterTest : public ::testing::Test {
ThreadState state_;
};
+TEST_F(Riscv64InterpreterTest, CLw) {
+ union {
+ uint16_t offset;
+ struct {
+ uint8_t : 2;
+ uint8_t i2 : 1;
+ uint8_t i3_i5 : 3;
+ uint8_t i6 : 1;
+ } i_bits;
+ };
+ for (offset = uint8_t{0}; offset < uint8_t{128}; offset += 4) {
+ union {
+ int16_t parcel;
+ struct {
+ uint8_t low_opcode : 2;
+ uint8_t rd : 3;
+ uint8_t i6 : 1;
+ uint8_t i2 : 1;
+ uint8_t rs : 3;
+ uint8_t i3_i5 : 3;
+ uint8_t high_opcode : 3;
+ } __attribute__((__packed__));
+ } o_bits = {
+ .low_opcode = 0b00,
+ .rd = 0,
+ .i6 = i_bits.i6,
+ .i2 = i_bits.i2,
+ .rs = 0,
+ .i3_i5 = i_bits.i3_i5,
+ .high_opcode = 0b010,
+ };
+ InterpretCLw(o_bits.parcel, offset);
+ }
+}
+
TEST_F(Riscv64InterpreterTest, CFld) {
union {
uint16_t offset;