[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