From 39cead71ef235f6fb6fc0a67a385234f1d182a06 Mon Sep 17 00:00:00 2001
From: "max.ma" <max.ma@starfivetech.com>
Date: Sun, 7 Nov 2021 23:01:41 -0800
Subject: [PATCH 2/6] add pref instruction

---
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 18 ++++++++++++
 .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h |  2 ++
 llvm/lib/Target/RISCV/RISCVInstrFormats.td    | 16 +++++++++++
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       | 28 +++++++++++++++++++
 4 files changed, 64 insertions(+)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 2954f9d1a1f6..93f43e1ed7cc 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -573,6 +573,15 @@ public:
     return IsConstantImm && isUInt<3>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isUImm4() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    if (!isImm())
+      return false;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isUInt<4>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm5() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -629,6 +638,15 @@ public:
            VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isSImm8() const {
+    if (!isImm())
+      return false;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    int64_t Imm;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isInt<8>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isCLUIImm() const {
     if (!isImm())
       return false;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 5826a2c2a4ef..32f54111e413 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -197,9 +197,11 @@ enum OperandType : unsigned {
   OPERAND_UIMM2 = OPERAND_FIRST_RISCV_IMM,
   OPERAND_UIMM3,
   OPERAND_UIMM4,
+  OPERAND_UIMM4_PREF,
   OPERAND_UIMM5,
   OPERAND_UIMM7,
   OPERAND_UIMM12,
+  OPERAND_SIMM8,
   OPERAND_SIMM12,
   OPERAND_UIMM20,
   OPERAND_UIMMLOG2XLEN,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index 18b3844b1e10..1c4b3f553d82 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -359,6 +359,22 @@ class RVInstCache<bits<12> cache, RISCVOpcode opcode, dag outs, dag ins,
   let Opcode = opcode.Value;
 }
 
+class RVInstPref<RISCVOpcode opcode, dag outs, dag ins,
+                   string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
+
+  bits<8> imm8;
+  bits<4> imm4;
+  bits<5> rs1;
+
+  let Inst{31-24} = imm8;
+  let Inst{23-20} = imm4;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = 2;
+  let Inst{11-7} = 0;
+  let Opcode = opcode.Value;
+}
+
 class RVInstIShift<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
                    dag outs, dag ins, string opcodestr, string argstr>
     : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index a185926db5fe..1b7ba7f05e2e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -180,6 +180,18 @@ def uimm3 : Operand<XLenVT> {
   let OperandNamespace = "RISCVOp";
 }
 
+def uimm4_pref : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<4>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<4>;
+  let DecoderMethod = "decodeUImmOperand<4>";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (MCOp.evaluateAsConstantImm(Imm))
+      return isUInt<4>(Imm) && (imm == 0 || imm == 1 || imm == 2 || imm == 4 || imm == 8);
+  }];
+  let OperandType = "OPERAND_UIMM4_PREF";
+  let OperandNamespace = "RISCVOp";
+}
+
 def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<5>;
   let DecoderMethod = "decodeUImmOperand<5>";
@@ -208,6 +220,14 @@ def uimm7 : Operand<XLenVT> {
   let OperandNamespace = "RISCVOp";
 }
 
+def simm8 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<8>(Imm);}]> {
+  let ParserMatchClass = SImmAsmOperand<8>;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeSImmOperand<8>";
+  let OperandType = "OPERAND_SIMM8";
+  let OperandNamespace = "RISCVOp";
+}
+
 def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
   let ParserMatchClass = SImmAsmOperand<12>;
   let EncoderMethod = "getImmOpValue";
@@ -529,6 +549,12 @@ class CSR_cache<bits<12> cache, string opcodestr>
     : RVInstCache<cache, OPC_SYSTEM, (outs), (ins GPR:$rs1),
               opcodestr, "$rs1">, Sched<[WriteCSR, ReadCSR]>;
 
+let hasNoSchedulingInfo = 1,
+    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class PREF_iir<string opcodestr>
+    : RVInstPref<OPC_OP_IMM, (outs), (ins uimm4_pref:$imm4, simm8:$imm8, GPR:$rs1),
+              opcodestr, "$imm4, ${imm8}(${rs1})">;
+
 let hasNoSchedulingInfo = 1,
     hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
 class CSR_ii<bits<3> funct3, string opcodestr>
@@ -683,6 +709,8 @@ def CFLUSH_D_L1   : CSR_cache<0b111111000000, "cflush.d.l1">;
 def CDISCARD_D_L1 : CSR_cache<0b111111000010, "cdiscard.d.l1">;
 def CFLUSH_D_L2   : CSR_cache<0b111111000100, "cflush.d.l2">;
 def CDISCARD_D_L2 : CSR_cache<0b111111000110, "cdiscard.d.l2">;
+def PREF          : PREF_iir<"pref">;
+
 /* End */
 
 def CSRRW : CSR_ir<0b001, "csrrw">;
-- 
2.25.1

