[llvm] 0d3eee3 - [RISCV] Add support for custom CSRs for Sifive S76.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 14 09:51:25 PDT 2023


Author: Garvit Gupta
Date: 2023-07-14T09:51:15-07:00
New Revision: 0d3eee33f262402562a1ff28106dbb2f59031bdb

URL: https://github.com/llvm/llvm-project/commit/0d3eee33f262402562a1ff28106dbb2f59031bdb
DIFF: https://github.com/llvm/llvm-project/commit/0d3eee33f262402562a1ff28106dbb2f59031bdb.diff

LOG: [RISCV] Add support for custom CSRs for Sifive S76.

Support for below CSRs is addeed -
1. Branch Prediction Mode CSR
2. Feature Disable CSR
3. Power Dial CSR
4. RNMI CSRs

spec:https://sifive.cdn.prismic.io/sifive/767804da-53b2-4893-97d5-b7c030ae0a94_s76mc_core_complex_manual_21G3.pdf

This patch removes AltName field from SysReg class because we are now using
separate class for custom vendor CSRs. Also, all use of AltName have been changed
to DeprecatedName because both were interchangeably used for old names which are
not in use in latest RISCV spec.

Reviewed By: craig.topper

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
    llvm/lib/Target/RISCV/RISCVSystemOperands.td
    llvm/test/MC/RISCV/machine-csr-names.s
    llvm/test/MC/RISCV/xsfcie-invalid.s
    llvm/test/MC/RISCV/xsfcie-valid.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b53498097b855f..47540e402859df 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1803,18 +1803,57 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
     if (getParser().parseIdentifier(Identifier))
       return ParseStatus::Failure;
 
+    // Check for CSR names conflicts.
+    // Custom CSR names might conflict with CSR names in privileged spec.
+    // E.g. - SiFive mnscratch(0x350) and privileged spec mnscratch(0x740).
+    auto CheckCSRNameConflict = [&]() {
+      if (!(RISCVSysReg::lookupSysRegByName(Identifier))) {
+        Error(S, "system register use requires an option to be enabled");
+        return true;
+      }
+      return false;
+    };
+
+    // First check for vendor specific CSRs.
+    auto SiFiveReg = RISCVSysReg::lookupSiFiveRegByName(Identifier);
+    if (SiFiveReg) {
+      if (SiFiveReg->haveVendorRequiredFeatures(getSTI().getFeatureBits())) {
+        Operands.push_back(
+            RISCVOperand::createSysReg(Identifier, S, SiFiveReg->Encoding));
+        return ParseStatus::Success;
+      }
+      if (CheckCSRNameConflict())
+        return ParseStatus::Failure;
+    }
+
     auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
-    if (!SysReg)
-      SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
     if (!SysReg)
       if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
         Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
                        SysReg->Name + "'");
 
-    // Accept a named Sys Reg if the required features are present.
+    // Check for CSR encoding conflicts.
+    // Custom CSR encoding might conflict with CSR encoding in privileged spec.
+    // E.g. - SiFive mnscratch(0x350) and privileged spec miselect(0x350).
+    auto CheckCSREncodingConflict = [&]() {
+      auto Reg = RISCVSysReg::lookupSiFiveRegByEncoding(SysReg->Encoding);
+      if (Reg && Reg->haveVendorRequiredFeatures(getSTI().getFeatureBits())) {
+        Warning(S, "'" + Identifier + "' CSR is not available on the current " +
+                       "subtarget. Instead '" + Reg->Name +
+                       "' CSR will be used.");
+        Operands.push_back(
+            RISCVOperand::createSysReg(Reg->Name, S, Reg->Encoding));
+        return true;
+      }
+      return false;
+    };
+
+    // Accept a named SysReg if the required features are present.
     if (SysReg) {
       if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
         return Error(S, "system register use requires an option to be enabled");
+      if (CheckCSREncodingConflict())
+        return ParseStatus::Success;
       Operands.push_back(
           RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
       return ParseStatus::Success;

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
index 2307d4a8e7092a..0a42c6faee2900 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -27,6 +27,7 @@ extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
 
 namespace RISCVSysReg {
 #define GET_SysRegsList_IMPL
+#define GET_SiFiveRegsList_IMPL
 #include "RISCVGenSearchableTables.inc"
 } // namespace RISCVSysReg
 

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 7269f95a4816d0..f86419319dd3a4 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -363,7 +363,6 @@ int getLoadFPImm(APFloat FPImm);
 namespace RISCVSysReg {
 struct SysReg {
   const char *Name;
-  const char *AltName;
   const char *DeprecatedName;
   unsigned Encoding;
   // FIXME: add these additional fields when needed.
@@ -387,9 +386,22 @@ struct SysReg {
       return true;
     return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
   }
+
+  bool haveVendorRequiredFeatures(const FeatureBitset &ActiveFeatures) const {
+    // Not in 32-bit mode.
+    if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit])
+      return false;
+    // No required feature associated with the system register.
+    if (FeaturesRequired.none())
+      return false;
+    return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
+  }
 };
 
+struct SiFiveReg : SysReg {};
+
 #define GET_SysRegsList_DECL
+#define GET_SiFiveRegsList_DECL
 #include "RISCVGenSearchableTables.inc"
 } // end namespace RISCVSysReg
 

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index e54d288eee7b42..8e98abd65aab7b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -120,8 +120,11 @@ void RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
   unsigned Imm = MI->getOperand(OpNo).getImm();
+  auto SiFiveReg = RISCVSysReg::lookupSiFiveRegByEncoding(Imm);
   auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
-  if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits()))
+  if (SiFiveReg && SiFiveReg->haveVendorRequiredFeatures(STI.getFeatureBits()))
+    O << SiFiveReg->Name;
+  else if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits()))
     O << SysReg->Name;
   else
     O << Imm;

diff  --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td
index 43475e825b46fb..953df7b15e2f6c 100644
--- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td
+++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td
@@ -19,11 +19,9 @@ include "llvm/TableGen/SearchableTable.td"
 
 class SysReg<string name, bits<12> op> {
   string Name = name;
-  // A maximum of one alias is supported right now.
-  string AltName = name;
-  // A maximum of one deprecated name is supported right now.  Unlike the
-  // `AltName` alias, a `DeprecatedName` generates a diagnostic when the name is
-  // used to encourage software to migrate away from the name.
+  // A maximum of one deprecated name is supported right now. It generates a
+  // diagnostic when the name is used to encourage software to migrate away from
+  // the name.
   string DeprecatedName = "";
   bits<12> Encoding = op;
   // FIXME: add these additional fields when needed.
@@ -43,7 +41,7 @@ def SysRegsList : GenericTable {
   let FilterClass = "SysReg";
   // FIXME: add "ReadWrite", "Mode", "Extra", "Number" fields when needed.
   let Fields = [
-    "Name", "AltName", "DeprecatedName", "Encoding", "FeaturesRequired",
+    "Name", "DeprecatedName", "Encoding", "FeaturesRequired",
     "isRV32Only",
   ];
 
@@ -56,13 +54,32 @@ def lookupSysRegByName : SearchIndex {
   let Key = [ "Name" ];
 }
 
-def lookupSysRegByAltName : SearchIndex {
+def lookupSysRegByDeprecatedName : SearchIndex {
   let Table = SysRegsList;
-  let Key = [ "AltName" ];
+  let Key = [ "DeprecatedName" ];
 }
 
-def lookupSysRegByDeprecatedName : SearchIndex {
-  let Table = SysRegsList;
+class SiFiveReg<string name, bits<12> op> : SysReg<name, op>;
+
+def SiFiveRegsList : GenericTable {
+  let FilterClass = "SiFiveReg";
+  // FIXME: add "ReadWrite", "Mode", "Extra", "Number" fields when needed.
+  let Fields = [
+    "Name", "DeprecatedName", "Encoding", "FeaturesRequired",
+    "isRV32Only",
+  ];
+
+  let PrimaryKey = [ "Encoding" ];
+  let PrimaryKeyName = "lookupSiFiveRegByEncoding";
+}
+
+def lookupSiFiveRegByName : SearchIndex {
+  let Table = SiFiveRegsList;
+  let Key = [ "Name" ];
+}
+
+def lookupSiFiveRegByDeprecatedName : SearchIndex {
+  let Table = SiFiveRegsList;
   let Key = [ "DeprecatedName" ];
 }
 
@@ -292,7 +309,7 @@ foreach i = 3...31 in
 //===----------------------------------------------------------------------===//
 // Machine Counter Setup
 //===----------------------------------------------------------------------===//
-let AltName = "mucounteren" in // Privileged spec v1.9.1 Name
+let DeprecatedName = "mucounteren" in // Privileged spec v1.9.1 Name
 def : SysReg<"mcountinhibit", 0x320>;
 
 // mhpmevent3-mhpmevent31 at 0x323-0x33F.
@@ -305,6 +322,20 @@ foreach i = 3...31 in {
   def : SysReg<"mhpmevent"#i#"h", !add(0x723, !sub(i, 3))>;
 }
 
+//===----------------------------------------------------------------------===//
+// SiFive Custom Machine Mode Registers
+//===----------------------------------------------------------------------===//
+
+let FeaturesRequired = [{ {RISCV::FeatureVendorXSfcie} }] in {
+def : SiFiveReg<"mnscratch", 0x350>;
+def : SiFiveReg<"mnepc", 0x351>;
+def : SiFiveReg<"mncause", 0x352>;
+def : SiFiveReg<"mnstatus", 0x353>;
+def : SiFiveReg<"mbpm", 0x7C0>;
+def : SiFiveReg<"mfd", 0x7C1>;
+def : SiFiveReg<"mpd", 0x7C8>;
+}
+
 //===----------------------------------------------------------------------===//
 // Debug/ Trace Registers (shared with Debug Mode)
 //===----------------------------------------------------------------------===//
@@ -322,7 +353,7 @@ def : SysReg<"dpc", 0x7B1>;
 
 // "dscratch" is an alternative name for "dscratch0" which appeared in earlier
 // drafts of the RISC-V debug spec
-let AltName = "dscratch" in
+let DeprecatedName = "dscratch" in
 def : SysReg<"dscratch0", 0x7B2>;
 def : SysReg<"dscratch1", 0x7B3>;
 

diff  --git a/llvm/test/MC/RISCV/machine-csr-names.s b/llvm/test/MC/RISCV/machine-csr-names.s
index 3b6d73b5118bed..664cf0301eff91 100644
--- a/llvm/test/MC/RISCV/machine-csr-names.s
+++ b/llvm/test/MC/RISCV/machine-csr-names.s
@@ -9,6 +9,9 @@
 # RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
 # RUN:     | llvm-objdump -d - \
 # RUN:     | FileCheck -check-prefix=CHECK-INST-ALIAS %s
+#
+# RUN: llvm-mc -triple riscv32 %s 2>&1 | FileCheck -check-prefix CHECK-WARN %s
+# RUN: llvm-mc -triple riscv64 %s 2>&1 | FileCheck -check-prefix CHECK-WARN %s
 
 ##################################
 # Machine Information Registers
@@ -1492,6 +1495,8 @@ csrrs t1, dscratch, zero
 # uimm12
 csrrs t2, 0x7B2, zero
 
+# CHECK-WARN: warning: 'dscratch' is a deprecated alias for 'dscratch0'
+
 # dscratch1
 # name
 # CHECK-INST: csrrs t1, dscratch1, zero
@@ -1944,6 +1949,8 @@ csrrs t1, mucounteren, zero
 # uimm12
 csrrs t2, 0x320, zero
 
+# CHECK-WARN: warning: 'mucounteren' is a deprecated alias for 'mcountinhibit'
+
 # mhpmevent3
 # name
 # CHECK-INST: csrrs t1, mhpmevent3, zero

diff  --git a/llvm/test/MC/RISCV/xsfcie-invalid.s b/llvm/test/MC/RISCV/xsfcie-invalid.s
index 8d0456684a7891..a84ffeeaa054eb 100644
--- a/llvm/test/MC/RISCV/xsfcie-invalid.s
+++ b/llvm/test/MC/RISCV/xsfcie-invalid.s
@@ -23,3 +23,17 @@ cease x1 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
 cease 0x10 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction
 
 cease # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'XSfcie' (SiFive Custom Instruction Extension SCIE.)
+
+csrr t1, mbpm # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled
+
+csrr t1, mfd # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled
+
+csrr t1, mpd # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled
+
+csrr t1, mnscratch # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled
+
+csrr t1, mnepc # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled
+
+csrr t1, mncause # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled
+
+csrr t1, mnstatus # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled

diff  --git a/llvm/test/MC/RISCV/xsfcie-valid.s b/llvm/test/MC/RISCV/xsfcie-valid.s
index 05f5c611ec51e9..25f743f5ed7976 100644
--- a/llvm/test/MC/RISCV/xsfcie-valid.s
+++ b/llvm/test/MC/RISCV/xsfcie-valid.s
@@ -3,6 +3,10 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
 # RUN: llvm-mc %s -triple=riscv64 -mattr=+xsfcie -riscv-no-aliases -show-encoding \
 # RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+xsfcie -riscv-no-aliases -show-encoding 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK-WARN %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+xsfcie -riscv-no-aliases -show-encoding 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK-WARN %s
 # RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xsfcie < %s \
 # RUN:     | llvm-objdump --mattr=+xsfcie -M no-aliases -d - \
 # RUN:     | FileCheck -check-prefix=CHECK-INST %s
@@ -11,6 +15,8 @@
 # RUN:     | FileCheck -check-prefix=CHECK-INST %s
 # RUN: llvm-mc %s -triple=riscv64 -mcpu=sifive-s76 -riscv-no-aliases -show-encoding \
 # RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv64 -mcpu=sifive-s76 -riscv-no-aliases -show-encoding 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK-WARN %s
 # RUN: llvm-mc -filetype=obj -triple riscv64 -mcpu=sifive-s76 < %s \
 # RUN:     | llvm-objdump --mcpu=sifive-s76 -M no-aliases -d - \
 # RUN:     | FileCheck -check-prefix=CHECK-INST %s
@@ -40,3 +46,91 @@ cdiscard.d.l1 x7
 # CHECK-INST: cease
 # CHECK-ENC: encoding: [0x73,0x00,0x50,0x30]
 cease
+
+# mbpm
+# name
+# CHECK-INST: csrrs t2, mbpm, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x7c]
+# uimm12
+# CHECK-INST: csrrs t2, mbpm, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x7c]
+# name
+csrrs t2, mbpm, zero
+# uimm12
+csrrs t2, 0x7C0, zero
+
+# mfd
+# name
+# CHECK-INST: csrrs t2, mfd, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x7c]
+# uimm12
+# CHECK-INST: csrrs t2, mfd, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x7c]
+# name
+csrrs t2, mfd, zero
+# uimm12
+csrrs t2, 0x7C1, zero
+
+# mpd
+# name
+# CHECK-INST: csrrs t2, mpd, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x80,0x7c]
+# uimm12
+# CHECK-INST: csrrs t2, mpd, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x80,0x7c]
+# name
+csrrs t2, mpd, zero
+# uimm12
+csrrs t2, 0x7C8, zero
+
+# mnscratch
+# name
+# CHECK-INST: csrrs t1, mnscratch, zero
+# CHECK-ENC: encoding: [0x73,0x23,0x00,0x35]
+# CHECK-WARN: warning: 'miselect' CSR is not available on the current subtarget. Instead 'mnscratch' CSR will be used.
+# uimm12
+# CHECK-INST: csrrs t2, mnscratch, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x35]
+# name
+csrrs t1, mnscratch, zero
+csrrs t1, miselect, zero
+# uimm12
+csrrs t2, 0x350, zero
+
+# mnepc
+# name
+# CHECK-INST: csrrs t1, mnepc, zero
+# CHECK-ENC: encoding: [0x73,0x23,0x10,0x35]
+# CHECK-WARN: warning: 'mireg' CSR is not available on the current subtarget. Instead 'mnepc' CSR will be used.
+# uimm12
+# CHECK-INST: csrrs t2, mnepc, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x35]
+# name
+csrrs t1, mnepc, zero
+csrrs t1, mireg, zero
+# uimm12
+csrrs t2, 0x351, zero
+
+# mncause
+# name
+# CHECK-INST: csrrs t1, mncause, zero
+# CHECK-ENC: encoding: [0x73,0x23,0x20,0x35]
+# uimm12
+# CHECK-INST: csrrs t2, mncause, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x20,0x35]
+# name
+csrrs t1, mncause, zero
+# uimm12
+csrrs t2, 0x352, zero
+
+# mnstatus
+# name
+# CHECK-INST: csrrs t1, mnstatus, zero
+# CHECK-ENC: encoding: [0x73,0x23,0x30,0x35]
+# uimm12
+# CHECK-INST: csrrs t2, mnstatus, zero
+# CHECK-ENC: encoding: [0xf3,0x23,0x30,0x35]
+# name
+csrrs t1, mnstatus, zero
+# uimm12
+csrrs t2, 0x353, zero


        


More information about the llvm-commits mailing list