[LLDB][RISCV] Add RV64F instruction support for EmulateInstructionRISCV
authorEmmmer <yjhdandan@163.com>
Sat, 3 Dec 2022 13:49:50 +0000 (21:49 +0800)
committerEmmmer <yjhdandan@163.com>
Mon, 5 Dec 2022 14:54:08 +0000 (22:54 +0800)
Reviewed By: DavidSpickett

Differential Revision: https://reviews.llvm.org/D139294

lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h
lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp

index d44864e..7e6ce70 100644 (file)
@@ -538,22 +538,28 @@ static const InstrPattern PATTERNS[] = {
     {"FSUB_S", 0xFE00007F, 0x8000053, DecodeRType<FSUB_S>},
     {"FMUL_S", 0xFE00007F, 0x10000053, DecodeRType<FMUL_S>},
     {"FDIV_S", 0xFE00007F, 0x18000053, DecodeRType<FDIV_S>},
-    {"FSQRT_S", 0xFFF0007F, 0x58000053, DecodeRType<FSQRT_S>},
+    {"FSQRT_S", 0xFFF0007F, 0x58000053, DecodeIType<FSQRT_S>},
     {"FSGNJ_S", 0xFE00707F, 0x20000053, DecodeRType<FSGNJ_S>},
     {"FSGNJN_S", 0xFE00707F, 0x20001053, DecodeRType<FSGNJN_S>},
     {"FSGNJX_S", 0xFE00707F, 0x20002053, DecodeRType<FSGNJX_S>},
     {"FMIN_S", 0xFE00707F, 0x28000053, DecodeRType<FMIN_S>},
     {"FMAX_S", 0xFE00707F, 0x28001053, DecodeRType<FMAX_S>},
-    {"FCVT_W_S", 0xFFF0007F, 0xC0000053, DecodeRType<FCVT_W_S>},
-    {"FCVT_WU_S", 0xFFF0007F, 0xC0100053, DecodeRType<FCVT_WU_S>},
-    {"FMV_X_W", 0xFFF0707F, 0xE0000053, DecodeRType<FMV_X_W>},
+    {"FCVT_W_S", 0xFFF0007F, 0xC0000053, DecodeIType<FCVT_W_S>},
+    {"FCVT_WU_S", 0xFFF0007F, 0xC0100053, DecodeIType<FCVT_WU_S>},
+    {"FMV_X_W", 0xFFF0707F, 0xE0000053, DecodeIType<FMV_X_W>},
     {"FEQ_S", 0xFE00707F, 0xA2002053, DecodeRType<FEQ_S>},
     {"FLT_S", 0xFE00707F, 0xA2001053, DecodeRType<FLT_S>},
     {"FLE_S", 0xFE00707F, 0xA2000053, DecodeRType<FLE_S>},
-    {"FCLASS_S", 0xFFF0707F, 0xE0001053, DecodeRType<FCLASS_S>},
-    {"FCVT_S_W", 0xFFF0007F, 0xD0000053, DecodeRType<FCVT_S_W>},
-    {"FCVT_S_WU", 0xFFF0007F, 0xD0100053, DecodeRType<FCVT_S_WU>},
-    {"FMV_W_X", 0xFFF0707F, 0xF0000053, DecodeRType<FMV_W_X>},
+    {"FCLASS_S", 0xFFF0707F, 0xE0001053, DecodeIType<FCLASS_S>},
+    {"FCVT_S_W", 0xFFF0007F, 0xD0000053, DecodeIType<FCVT_S_W>},
+    {"FCVT_S_WU", 0xFFF0007F, 0xD0100053, DecodeIType<FCVT_S_WU>},
+    {"FMV_W_X", 0xFFF0707F, 0xF0000053, DecodeIType<FMV_W_X>},
+
+    // RV64F (Extension for Single-Precision Floating-Point) //
+    {"FCVT_L_S", 0xFFF0007F, 0xC0200053, DecodeIType<FCVT_L_S>},
+    {"FCVT_LU_S", 0xFFF0007F, 0xC0300053, DecodeIType<FCVT_LU_S>},
+    {"FCVT_S_L", 0xFFF0007F, 0xD0200053, DecodeIType<FCVT_S_L>},
+    {"FCVT_S_LU", 0xFFF0007F, 0xD0300053, DecodeIType<FCVT_S_LU>},
 };
 
 llvm::Optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) {
@@ -1428,6 +1434,38 @@ public:
         })
         .value_or(false);
   }
+  bool operator()(FCVT_L_S inst) {
+    return inst.rs1.ReadAPFloat(m_emu, false)
+        .transform([&](auto &&rs1) {
+          int64_t res = rs1.convertToFloat();
+          return inst.rd.Write(m_emu, uint64_t(res));
+        })
+        .value_or(false);
+  }
+  bool operator()(FCVT_LU_S inst) {
+    return inst.rs1.ReadAPFloat(m_emu, false)
+        .transform([&](auto &&rs1) {
+          uint64_t res = rs1.convertToFloat();
+          return inst.rd.Write(m_emu, res);
+        })
+        .value_or(false);
+  }
+  bool operator()(FCVT_S_L inst) {
+    return inst.rs1.ReadI64(m_emu)
+        .transform([&](auto &&rs1) {
+          llvm::APFloat apf(llvm::APFloat::IEEEsingle(), rs1);
+          return inst.rd.WriteAPFloat(m_emu, apf);
+        })
+        .value_or(false);
+  }
+  bool operator()(FCVT_S_LU inst) {
+    return inst.rs1.Read(m_emu)
+        .transform([&](auto &&rs1) {
+          llvm::APFloat apf(llvm::APFloat::IEEEsingle(), rs1);
+          return inst.rd.WriteAPFloat(m_emu, apf);
+        })
+        .value_or(false);
+  }
   bool operator()(INVALID inst) { return false; }
   bool operator()(RESERVED inst) { return false; }
   bool operator()(EBREAK inst) { return false; }
index 3aca675..c533b75 100644 (file)
@@ -192,22 +192,28 @@ R_TYPE_INST(FADD_S);
 R_TYPE_INST(FSUB_S);
 R_TYPE_INST(FMUL_S);
 R_TYPE_INST(FDIV_S);
-R_TYPE_INST(FSQRT_S);
+I_TYPE_INST(FSQRT_S);
 R_TYPE_INST(FSGNJ_S);
 R_TYPE_INST(FSGNJN_S);
 R_TYPE_INST(FSGNJX_S);
 R_TYPE_INST(FMIN_S);
 R_TYPE_INST(FMAX_S);
-R_TYPE_INST(FCVT_W_S);
-R_TYPE_INST(FCVT_WU_S);
-R_TYPE_INST(FMV_X_W);
+I_TYPE_INST(FCVT_W_S);
+I_TYPE_INST(FCVT_WU_S);
+I_TYPE_INST(FMV_X_W);
 R_TYPE_INST(FEQ_S);
 R_TYPE_INST(FLT_S);
 R_TYPE_INST(FLE_S);
-R_TYPE_INST(FCLASS_S);
-R_TYPE_INST(FCVT_S_W);
-R_TYPE_INST(FCVT_S_WU);
-R_TYPE_INST(FMV_W_X);
+I_TYPE_INST(FCLASS_S);
+I_TYPE_INST(FCVT_S_W);
+I_TYPE_INST(FCVT_S_WU);
+I_TYPE_INST(FMV_W_X);
+
+// RV64F inst (The standard single-precision floating-point extension)
+I_TYPE_INST(FCVT_L_S);
+I_TYPE_INST(FCVT_LU_S);
+I_TYPE_INST(FCVT_S_L);
+I_TYPE_INST(FCVT_S_LU);
 
 /// Invalid and reserved instructions, the `inst` fields are used for debugging.
 INVALID_INST(INVALID);
@@ -227,7 +233,8 @@ using RISCVInst = std::variant<
     AMOMAXU_D, FLW, FSW, FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FADD_S, FSUB_S,
     FMUL_S, FDIV_S, FSQRT_S, FSGNJ_S, FSGNJN_S, FSGNJX_S, FMIN_S, FMAX_S,
     FCVT_W_S, FCVT_WU_S, FMV_X_W, FEQ_S, FLT_S, FLE_S, FCLASS_S, FCVT_S_W,
-    FCVT_S_WU, FMV_W_X, INVALID, EBREAK, RESERVED, HINT, NOP>;
+    FCVT_S_WU, FMV_W_X, FCVT_L_S, FCVT_LU_S, FCVT_S_L, FCVT_S_LU, INVALID,
+    EBREAK, RESERVED, HINT, NOP>;
 
 struct InstrPattern {
   const char *name;
index 68c2ee6..8e92b4e 100644 (file)
@@ -584,10 +584,10 @@ struct FCVTInst {
 
 TEST_F(RISCVEmulatorTester, TestFCVTInst) {
   std::vector<FCVTInst> tests = {
-      {0xC001F253, "FCVT_W_S"},
-      {0xC011F253, "FCVT_WU_S"},
-      {0xD001F253, "FCVT_S_W"},
-      {0xD011F253, "FCVT_S_WU"},
+      {0xC001F253, "FCVT_W_S"}, {0xC011F253, "FCVT_WU_S"},
+      {0xD001F253, "FCVT_S_W"}, {0xD011F253, "FCVT_S_WU"},
+      {0xC021F253, "FCVT_L_S"}, {0xC031F253, "FCVT_LU_S"},
+      {0xD021F253, "FCVT_S_L"}, {0xD031F253, "FCVT_S_LU"},
   };
   for (auto i : tests) {
     auto decode = this->Decode(i.inst);