[Lldb-commits] [lldb] d362882 - [LLDB][RISCV] Add RV32FC instruction support for EmulateInstructionRISCV
via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 6 06:26:59 PST 2022
Author: Emmmer
Date: 2022-12-06T22:26:51+08:00
New Revision: d3628823c96f2d29ef8cea28f3b1b60ec670f318
URL: https://github.com/llvm/llvm-project/commit/d3628823c96f2d29ef8cea28f3b1b60ec670f318
DIFF: https://github.com/llvm/llvm-project/commit/d3628823c96f2d29ef8cea28f3b1b60ec670f318.diff
LOG: [LLDB][RISCV] Add RV32FC instruction support for EmulateInstructionRISCV
Reviewed By: DavidSpickett
Differential Revision: https://reviews.llvm.org/D139390
Added:
Modified:
lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
lldb/source/Plugins/Instruction/RISCV/RISCVCInstructions.h
lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h
lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
index 7e6ce707cc41c..96d2c3fc1b004 100644
--- a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
+++ b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
@@ -497,13 +497,13 @@ static const InstrPattern PATTERNS[] = {
// RVC (Compressed Instructions) //
{"C_LWSP", 0xE003, 0x4002, DecodeC_LWSP},
- {"C_LDSP", 0xE003, 0x6002, DecodeC_LDSP},
+ {"C_LDSP", 0xE003, 0x6002, DecodeC_LDSP, RV64 | RV128},
{"C_SWSP", 0xE003, 0xC002, DecodeC_SWSP},
- {"C_SDSP", 0xE003, 0xE002, DecodeC_SDSP},
+ {"C_SDSP", 0xE003, 0xE002, DecodeC_SDSP, RV64 | RV128},
{"C_LW", 0xE003, 0x4000, DecodeC_LW},
- {"C_LD", 0xE003, 0x6000, DecodeC_LD},
+ {"C_LD", 0xE003, 0x6000, DecodeC_LD, RV64 | RV128},
{"C_SW", 0xE003, 0xC000, DecodeC_SW},
- {"C_SD", 0xE003, 0xE000, DecodeC_SD},
+ {"C_SD", 0xE003, 0xE000, DecodeC_SD, RV64 | RV128},
{"C_J", 0xE003, 0xA001, DecodeC_J},
{"C_JR", 0xF07F, 0x8002, DecodeC_JR},
{"C_JALR", 0xF07F, 0x9002, DecodeC_JALR},
@@ -512,11 +512,11 @@ static const InstrPattern PATTERNS[] = {
{"C_LI", 0xE003, 0x4001, DecodeC_LI},
{"C_LUI_ADDI16SP", 0xE003, 0x6001, DecodeC_LUI_ADDI16SP},
{"C_ADDI", 0xE003, 0x1, DecodeC_ADDI},
- {"C_ADDIW", 0xE003, 0x2001, DecodeC_ADDIW},
+ {"C_ADDIW", 0xE003, 0x2001, DecodeC_ADDIW, RV64 | RV128},
{"C_ADDI4SPN", 0xE003, 0x0, DecodeC_ADDI4SPN},
- {"C_SLLI", 0xE003, 0x2, DecodeC_SLLI},
- {"C_SRLI", 0xEC03, 0x8001, DecodeC_SRLI},
- {"C_SRAI", 0xEC03, 0x8401, DecodeC_SRAI},
+ {"C_SLLI", 0xE003, 0x2, DecodeC_SLLI, RV64 | RV128},
+ {"C_SRLI", 0xEC03, 0x8001, DecodeC_SRLI, RV64 | RV128},
+ {"C_SRAI", 0xEC03, 0x8401, DecodeC_SRAI, RV64 | RV128},
{"C_ANDI", 0xEC03, 0x8801, DecodeC_ANDI},
{"C_MV", 0xF003, 0x8002, DecodeC_MV},
{"C_ADD", 0xF003, 0x9002, DecodeC_ADD},
@@ -524,8 +524,13 @@ static const InstrPattern PATTERNS[] = {
{"C_OR", 0xFC63, 0x8C41, DecodeC_OR},
{"C_XOR", 0xFC63, 0x8C21, DecodeC_XOR},
{"C_SUB", 0xFC63, 0x8C01, DecodeC_SUB},
- {"C_SUBW", 0xFC63, 0x9C01, DecodeC_SUBW},
- {"C_ADDW", 0xFC63, 0x9C21, DecodeC_ADDW},
+ {"C_SUBW", 0xFC63, 0x9C01, DecodeC_SUBW, RV64 | RV128},
+ {"C_ADDW", 0xFC63, 0x9C21, DecodeC_ADDW, RV64 | RV128},
+ // RV32FC //
+ {"FLW", 0xE003, 0x6000, DecodeC_FLW, RV32},
+ {"FSW", 0xE003, 0xE000, DecodeC_FSW, RV32},
+ {"FLWSP", 0xE003, 0x6002, DecodeC_FLWSP, RV32},
+ {"FSWSP", 0xE003, 0xE002, DecodeC_FSWSP, RV32},
// RV32F (Extension for Single-Precision Floating-Point) //
{"FLW", 0x707F, 0x2007, DecodeIType<FLW>},
@@ -569,9 +574,16 @@ llvm::Optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) {
// check whether the compressed encode could be valid
uint16_t mask = try_rvc & 0b11;
bool is_rvc = try_rvc != 0 && mask != 3;
+ uint8_t inst_type = RV64;
+
+ // if we have ArchSpec::eCore_riscv128 in the future,
+ // we also need to check it here
+ if (m_arch.GetCore() == ArchSpec::eCore_riscv32)
+ inst_type = RV32;
for (const InstrPattern &pat : PATTERNS) {
- if ((inst & pat.type_mask) == pat.eigen) {
+ if ((inst & pat.type_mask) == pat.eigen &&
+ (inst_type & pat.inst_type) != 0) {
LLDB_LOGF(
log, "EmulateInstructionRISCV::%s: inst(%x at %lx) was decoded to %s",
__FUNCTION__, inst, m_addr, pat.name);
diff --git a/lldb/source/Plugins/Instruction/RISCV/RISCVCInstructions.h b/lldb/source/Plugins/Instruction/RISCV/RISCVCInstructions.h
index 83542109415b8..1f1d2853ab36d 100644
--- a/lldb/source/Plugins/Instruction/RISCV/RISCVCInstructions.h
+++ b/lldb/source/Plugins/Instruction/RISCV/RISCVCInstructions.h
@@ -299,6 +299,33 @@ RISCVInst DecodeC_ADDW(uint32_t inst) {
auto rd = DecodeCA_RD(inst);
return ADDW{rd, rd, DecodeCA_RS2(inst)};
}
+RISCVInst DecodeC_FLW(uint32_t inst) {
+ uint16_t offset = ((inst << 1) & 0x40) // imm[6]
+ | ((inst >> 7) & 0x38) // imm[5:3]
+ | ((inst >> 4) & 0x4); // imm[2]
+ return FLW{DecodeCL_RD(inst), DecodeCL_RS1(inst), uint32_t(offset)};
+}
+
+RISCVInst DecodeC_FSW(uint32_t inst) {
+ uint16_t offset = ((inst << 1) & 0x40) // imm[6]
+ | ((inst >> 7) & 0x38) // imm[5:3]
+ | ((inst >> 4) & 0x4); // imm[2]
+ return FSW{DecodeCS_RS1(inst), DecodeCS_RS2(inst), uint32_t(offset)};
+}
+
+RISCVInst DecodeC_FLWSP(uint32_t inst) {
+ auto rd = DecodeCI_RD(inst);
+ uint16_t offset = ((inst << 4) & 0xc0) // offset[7:6]
+ | ((inst >> 7) & 0x20) // offset[5]
+ | ((inst >> 2) & 0x1c); // offset[4:2]
+ return FLW{rd, Rs{gpr_sp_riscv}, uint32_t(offset)};
+}
+
+RISCVInst DecodeC_FSWSP(uint32_t inst) {
+ uint16_t offset = ((inst >> 1) & 0xc0) // offset[7:6]
+ | ((inst >> 7) & 0x3c); // offset[5:2]
+ return FSW{Rs{gpr_sp_riscv}, DecodeCSS_RS2(inst), uint32_t(offset)};
+}
} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H
diff --git a/lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h b/lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h
index c533b7538fc79..431c2be30d136 100644
--- a/lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h
+++ b/lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h
@@ -236,6 +236,10 @@ using RISCVInst = std::variant<
FCVT_S_WU, FMV_W_X, FCVT_L_S, FCVT_LU_S, FCVT_S_L, FCVT_S_LU, INVALID,
EBREAK, RESERVED, HINT, NOP>;
+constexpr uint8_t RV32 = 1;
+constexpr uint8_t RV64 = 2;
+constexpr uint8_t RV128 = 4;
+
struct InstrPattern {
const char *name;
/// Bit mask to check the type of a instruction (B-Type, I-Type, J-Type, etc.)
@@ -243,6 +247,8 @@ struct InstrPattern {
/// Characteristic value after bitwise-and with type_mask.
uint32_t eigen;
RISCVInst (*decode)(uint32_t inst);
+ /// If not specified, the inst will be supported by all RV versions.
+ uint8_t inst_type = RV32 | RV64 | RV128;
};
struct DecodeResult {
diff --git a/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp b/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
index 8e92b4e522aec..164a0d7391042 100644
--- a/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
+++ b/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
@@ -27,8 +27,8 @@ struct RISCVEmulatorTester : public EmulateInstructionRISCV, testing::Test {
RegisterInfoPOSIX_riscv64::FPR fpr;
uint8_t memory[1024] = {0};
- RISCVEmulatorTester()
- : EmulateInstructionRISCV(ArchSpec("riscv64-unknown-linux-gnu")) {
+ RISCVEmulatorTester(std::string triple = "riscv64-unknown-linux-gnu")
+ : EmulateInstructionRISCV(ArchSpec(triple)) {
EmulateInstruction::SetReadRegCallback(ReadRegisterCallback);
EmulateInstruction::SetWriteRegCallback(WriteRegisterCallback);
EmulateInstruction::SetReadMemCallback(ReadMemoryCallback);
@@ -356,6 +356,26 @@ TEST_F(RISCVEmulatorTester, TestCDecode) {
}
}
+class RISCVEmulatorTester32 : public RISCVEmulatorTester {
+public:
+ RISCVEmulatorTester32() : RISCVEmulatorTester("riscv32-unknown-linux-gnu") {}
+};
+
+TEST_F(RISCVEmulatorTester32, TestCDecodeRV32) {
+ std::vector<TestDecode> tests = {
+ {0x6002, FLW{Rd{0}, Rs{2}, 0}},
+ {0xE006, FSW{Rs{2}, Rs{1}, 0}},
+ {0x6000, FLW{Rd{8}, Rs{8}, 0}},
+ {0xE000, FSW{Rs{8}, Rs{8}, 0}},
+ };
+
+ for (auto i : tests) {
+ auto decode = this->Decode(i.inst);
+ ASSERT_TRUE(decode.has_value());
+ ASSERT_TRUE(compareInst(decode->decoded, i.inst_type));
+ }
+}
+
// GEN_BRANCH_TEST(opcode, imm1, imm2, imm3):
// It should branch for instruction `opcode imm1, imm2`
// It should do nothing for instruction `opcode imm1, imm3`
More information about the lldb-commits
mailing list