[llvm] r308456 - [ARM] Unify handling of M-Class system registers

Javed Absar via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 19 05:57:16 PDT 2017


Author: javed.absar
Date: Wed Jul 19 05:57:16 2017
New Revision: 308456

URL: http://llvm.org/viewvc/llvm-project?rev=308456&view=rev
Log:
[ARM] Unify handling of M-Class system registers

This patch cleans up and fixes issues in the M-Class system register handling:

1. It defines the system registers and the encoding (SYSm values) in one place:
   a new ARMSystemRegister.td using SearchableTable, thereby removing the
   hand-coded values which existed in multiple places.

2. Some system registers e.g. BASEPRI_MAX_NS which do not exist were being allowed!
   Ref: ARMv6/7/8M architecture reference manual.

Reviewed by: @t.p.northover, @olist01, @john.brawn
Differential Revision: https://reviews.llvm.org/D35209


Added:
    llvm/trunk/lib/Target/ARM/ARMSystemRegister.td
    llvm/trunk/lib/Target/ARM/Utils/
    llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.cpp
    llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.h
    llvm/trunk/lib/Target/ARM/Utils/CMakeLists.txt
    llvm/trunk/lib/Target/ARM/Utils/LLVMBuild.txt
Modified:
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/AsmParser/LLVMBuild.txt
    llvm/trunk/lib/Target/ARM/CMakeLists.txt
    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
    llvm/trunk/lib/Target/ARM/InstPrinter/LLVMBuild.txt
    llvm/trunk/lib/Target/ARM/LLVMBuild.txt
    llvm/trunk/test/CodeGen/ARM/special-reg-v8m-main.ll
    llvm/trunk/test/MC/ARM/thumbv8m.s

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed Jul 19 05:57:16 2017
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARM.h"
+#include "Utils/ARMBaseInfo.h"
 #include "ARMBaseInstrInfo.h"
 #include "ARMTargetMachine.h"
 #include "MCTargetDesc/ARMAddressingModes.h"
@@ -3801,31 +3802,6 @@ static inline int getBankedRegisterMask(
           .Default(-1);
 }
 
-// Maps a MClass special register string to its value for use in the
-// t2MRS_M / t2MSR_M instruction nodes as the SYSm value operand.
-// Returns -1 to signify that the string was invalid.
-static inline int getMClassRegisterSYSmValueMask(StringRef RegString) {
-  return StringSwitch<int>(RegString.lower())
-          .Case("apsr", 0x0)
-          .Case("iapsr", 0x1)
-          .Case("eapsr", 0x2)
-          .Case("xpsr", 0x3)
-          .Case("ipsr", 0x5)
-          .Case("epsr", 0x6)
-          .Case("iepsr", 0x7)
-          .Case("msp", 0x8)
-          .Case("psp", 0x9)
-          .Case("primask", 0x10)
-          .Case("basepri", 0x11)
-          .Case("basepri_max", 0x12)
-          .Case("faultmask", 0x13)
-          .Case("control", 0x14)
-          .Case("msplim", 0x0a)
-          .Case("psplim", 0x0b)
-          .Case("sp", 0x18)
-          .Default(-1);
-}
-
 // The flags here are common to those allowed for apsr in the A class cores and
 // those allowed for the special registers in the M class cores. Returns a
 // value representing which flags were present, -1 if invalid.
@@ -3839,58 +3815,15 @@ static inline int getMClassFlagsMask(Str
           .Default(-1);
 }
 
-static int getMClassRegisterMask(StringRef Reg, StringRef Flags, bool IsRead,
-                                 const ARMSubtarget *Subtarget) {
-  // Ensure that the register (without flags) was a valid M Class special
-  // register.
-  int SYSmvalue = getMClassRegisterSYSmValueMask(Reg);
-  if (SYSmvalue == -1)
-    return -1;
-
-  // basepri, basepri_max and faultmask are only valid for V7m.
-  if (!Subtarget->hasV7Ops() && SYSmvalue >= 0x11 && SYSmvalue <= 0x13)
-    return -1;
-
-  if (Subtarget->has8MSecExt() && Flags.lower() == "ns") {
-    Flags = "";
-    SYSmvalue |= 0x80;
-  }
-
-  if (!Subtarget->has8MSecExt() &&
-      (SYSmvalue == 0xa || SYSmvalue == 0xb || SYSmvalue > 0x14))
-    return -1;
-
-  if (!Subtarget->hasV8MMainlineOps() &&
-      (SYSmvalue == 0x8a || SYSmvalue == 0x8b || SYSmvalue == 0x91 ||
-       SYSmvalue == 0x93))
-    return -1;
-
-  // If it was a read then we won't be expecting flags and so at this point
-  // we can return the mask.
-  if (IsRead) {
-    if (Flags.empty())
-      return SYSmvalue;
-    else
-      return -1;
-  }
-
-  // We know we are now handling a write so need to get the mask for the flags.
-  int Mask = getMClassFlagsMask(Flags);
-
-  // Only apsr, iapsr, eapsr, xpsr can have flags. The other register values
-  // shouldn't have flags present.
-  if ((SYSmvalue < 0x4 && Mask == -1) || (SYSmvalue > 0x4 && !Flags.empty()))
-    return -1;
-
-  // The _g and _nzcvqg versions are only valid if the DSP extension is
-  // available.
-  if (!Subtarget->hasDSP() && (Mask & 0x1))
+// Maps MClass special registers string to its value for use in the
+// t2MRS_M/t2MSR_M instruction nodes as the SYSm value operand.
+// Returns -1 to signify that the string was invalid.
+static int getMClassRegisterMask(StringRef Reg, const ARMSubtarget *Subtarget) {
+  auto TheReg = ARMSysReg::lookupMClassSysRegByName(Reg);
+  const FeatureBitset &FeatureBits = Subtarget->getFeatureBits();
+  if (!TheReg || !TheReg->hasRequiredFeatures(FeatureBits))
     return -1;
-
-  // The register was valid so need to put the mask in the correct place
-  // (the flags need to be in bits 11-10) and combine with the SYSmvalue to
-  // construct the operand for the instruction node.
-  return SYSmvalue | Mask << 10;
+  return (int)(TheReg->Encoding & 0xFFF); // SYSm value
 }
 
 static int getARClassRegisterMask(StringRef Reg, StringRef Flags) {
@@ -4032,13 +3965,7 @@ bool ARMDAGToDAGISel::tryReadRegister(SD
   // is an acceptable value, so check that a mask can be constructed from the
   // string.
   if (Subtarget->isMClass()) {
-    StringRef Flags = "", Reg = SpecialReg;
-    if (Reg.endswith("_ns")) {
-      Flags = "ns";
-      Reg = Reg.drop_back(3);
-    }
-
-    int SYSmValue = getMClassRegisterMask(Reg, Flags, true, Subtarget);
+    int SYSmValue = getMClassRegisterMask(SpecialReg, Subtarget);
     if (SYSmValue == -1)
       return false;
 
@@ -4149,12 +4076,7 @@ bool ARMDAGToDAGISel::tryWriteRegister(S
   // If the target was M Class then need to validate the special register value
   // and retrieve the mask for use in the instruction node.
   if (Subtarget->isMClass()) {
-    // basepri_max gets split so need to correct Reg and Flags.
-    if (SpecialReg == "basepri_max") {
-      Reg = SpecialReg;
-      Flags = "";
-    }
-    int SYSmValue = getMClassRegisterMask(Reg, Flags, false, Subtarget);
+    int SYSmValue = getMClassRegisterMask(SpecialReg, Subtarget);
     if (SYSmValue == -1)
       return false;
 

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Wed Jul 19 05:57:16 2017
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+include "ARMSystemRegister.td"
+
 //===----------------------------------------------------------------------===//
 //  Declarations that describe the ARM register file
 //===----------------------------------------------------------------------===//

Added: llvm/trunk/lib/Target/ARM/ARMSystemRegister.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSystemRegister.td?rev=308456&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMSystemRegister.td (added)
+++ llvm/trunk/lib/Target/ARM/ARMSystemRegister.td Wed Jul 19 05:57:16 2017
@@ -0,0 +1,108 @@
+//===-- ARMSystemRegister.td - ARM Register defs -------------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/TableGen/SearchableTable.td"
+
+//===----------------------------------------------------------------------===//
+//  Declarations that describe the ARM system-registers
+//===----------------------------------------------------------------------===//
+
+// M-Class System Registers.
+// 'Mask' bits create unique keys for searches.
+//
+class MClassSysReg<bits<1> UniqMask1,
+                   bits<1> UniqMask2,
+                   bits<1> UniqMask3,
+                   bits<12> Enc12,
+                   string name> : SearchableTable {
+  let SearchableFields = ["Name", "M1Encoding12", "M2M3Encoding8", "Encoding"];
+  string Name;
+  bits<13> M1Encoding12;
+  bits<10> M2M3Encoding8;
+  bits<12> Encoding;
+
+  let Name = name;
+  let EnumValueField = "M1Encoding12";
+  let EnumValueField = "M2M3Encoding8";
+  let EnumValueField = "Encoding";
+
+  let M1Encoding12{12}    = UniqMask1;
+  let M1Encoding12{11-00} = Enc12;
+  let Encoding            = Enc12;
+
+  let M2M3Encoding8{9}    = UniqMask2;
+  let M2M3Encoding8{8}    = UniqMask3;
+  let M2M3Encoding8{7-0}  = Enc12{7-0};
+  code Requires           = [{ {} }];
+}
+
+// [|i|e|x]apsr_nzcvq has alias [|i|e|x]apsr.
+//                 Mask1 Mask2 Mask3 Enc12, Name
+let Requires = [{ {ARM::FeatureDSP} }] in {
+def : MClassSysReg<0,    0,    0,    0x400, "apsr_g">;
+def : MClassSysReg<0,    1,    1,    0xc00, "apsr_nzcvqg">;
+def : MClassSysReg<0,    0,    0,    0x401, "iapsr_g">;
+def : MClassSysReg<0,    1,    1,    0xc01, "iapsr_nzcvqg">;
+def : MClassSysReg<0,    0,    0,    0x402, "eapsr_g">;
+def : MClassSysReg<0,    1,    1,    0xc02, "eapsr_nzcvqg">;
+def : MClassSysReg<0,    0,    0,    0x403, "xpsr_g">;
+def : MClassSysReg<0,    1,    1,    0xc03, "xpsr_nzcvqg">;
+}
+
+def : MClassSysReg<0,    0,    1,    0x800, "apsr">;
+def : MClassSysReg<1,    1,    0,    0x800, "apsr_nzcvq">;
+def : MClassSysReg<0,    0,    1,    0x801, "iapsr">;
+def : MClassSysReg<1,    1,    0,    0x801, "iapsr_nzcvq">;
+def : MClassSysReg<0,    0,    1,    0x802, "eapsr">;
+def : MClassSysReg<1,    1,    0,    0x802, "eapsr_nzcvq">;
+def : MClassSysReg<0,    0,    1,    0x803, "xpsr">;
+def : MClassSysReg<1,    1,    0,    0x803, "xpsr_nzcvq">;
+
+def : MClassSysReg<0,    0,    1,    0x805, "ipsr">;
+def : MClassSysReg<0,    0,    1,    0x806, "epsr">;
+def : MClassSysReg<0,    0,    1,    0x807, "iepsr">;
+def : MClassSysReg<0,    0,    1,    0x808, "msp">;
+def : MClassSysReg<0,    0,    1,    0x809, "psp">;
+
+let Requires = [{ {ARM::HasV8MBaselineOps} }] in {
+def : MClassSysReg<0,    0,    1,    0x80a, "msplim">;
+def : MClassSysReg<0,    0,    1,    0x80b, "psplim">;
+}
+
+def : MClassSysReg<0,    0,    1,    0x810, "primask">;
+
+let Requires = [{ {ARM::HasV7Ops} }] in {
+def : MClassSysReg<0,    0,    1,    0x811, "basepri">;
+def : MClassSysReg<0,    0,    1,    0x812, "basepri_max">;
+def : MClassSysReg<0,    0,    1,    0x813, "faultmask">;
+}
+
+def : MClassSysReg<0,    0,    1,    0x814, "control">;
+
+let Requires = [{ {ARM::Feature8MSecExt} }] in {
+def : MClassSysReg<0,    0,    1,    0x888, "msp_ns">;
+def : MClassSysReg<0,    0,    1,    0x889, "psp_ns">;
+}
+
+let Requires = [{ {ARM::Feature8MSecExt, ARM::HasV8MBaselineOps} }] in {
+def : MClassSysReg<0,    0,    1,    0x88a, "msplim_ns">;
+def : MClassSysReg<0,    0,    1,    0x88b, "psplim_ns">;
+}
+
+def : MClassSysReg<0,    0,    1,    0x890, "primask_ns">;
+
+let Requires = [{ {ARM::Feature8MSecExt, ARM::HasV7Ops} }] in {
+def : MClassSysReg<0,    0,    1,    0x891, "basepri_ns">;
+def : MClassSysReg<0,    0,    1,    0x893, "faultmask_ns">;
+}
+
+let Requires = [{ {ARM::Feature8MSecExt} }] in {
+def : MClassSysReg<0,    0,    1,    0x894, "control_ns">;
+def : MClassSysReg<0,    0,    1,    0x898, "sp_ns">;
+}

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Jul 19 05:57:16 2017
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARMFeatures.h"
+#include "Utils/ARMBaseInfo.h"
 #include "MCTargetDesc/ARMAddressingModes.h"
 #include "MCTargetDesc/ARMBaseInfo.h"
 #include "MCTargetDesc/ARMMCExpr.h"
@@ -4089,81 +4090,14 @@ ARMAsmParser::parseMSRMaskOperand(Operan
   StringRef Mask = Tok.getString();
 
   if (isMClass()) {
-    // See ARMv6-M 10.1.1
-    std::string Name = Mask.lower();
-    unsigned FlagsVal = StringSwitch<unsigned>(Name)
-      // Note: in the documentation:
-      //  ARM deprecates using MSR APSR without a _<bits> qualifier as an alias
-      //  for MSR APSR_nzcvq.
-      // but we do make it an alias here.  This is so to get the "mask encoding"
-      // bits correct on MSR APSR writes.
-      //
-      // FIXME: Note the 0xc00 "mask encoding" bits version of the registers
-      // should really only be allowed when writing a special register.  Note
-      // they get dropped in the MRS instruction reading a special register as
-      // the SYSm field is only 8 bits.
-      .Case("apsr", 0x800)
-      .Case("apsr_nzcvq", 0x800)
-      .Case("apsr_g", 0x400)
-      .Case("apsr_nzcvqg", 0xc00)
-      .Case("iapsr", 0x801)
-      .Case("iapsr_nzcvq", 0x801)
-      .Case("iapsr_g", 0x401)
-      .Case("iapsr_nzcvqg", 0xc01)
-      .Case("eapsr", 0x802)
-      .Case("eapsr_nzcvq", 0x802)
-      .Case("eapsr_g", 0x402)
-      .Case("eapsr_nzcvqg", 0xc02)
-      .Case("xpsr", 0x803)
-      .Case("xpsr_nzcvq", 0x803)
-      .Case("xpsr_g", 0x403)
-      .Case("xpsr_nzcvqg", 0xc03)
-      .Case("ipsr", 0x805)
-      .Case("epsr", 0x806)
-      .Case("iepsr", 0x807)
-      .Case("msp", 0x808)
-      .Case("psp", 0x809)
-      .Case("primask", 0x810)
-      .Case("basepri", 0x811)
-      .Case("basepri_max", 0x812)
-      .Case("faultmask", 0x813)
-      .Case("control", 0x814)
-      .Case("msplim", 0x80a)
-      .Case("psplim", 0x80b)
-      .Case("msp_ns", 0x888)
-      .Case("psp_ns", 0x889)
-      .Case("msplim_ns", 0x88a)
-      .Case("psplim_ns", 0x88b)
-      .Case("primask_ns", 0x890)
-      .Case("basepri_ns", 0x891)
-      .Case("basepri_max_ns", 0x892)
-      .Case("faultmask_ns", 0x893)
-      .Case("control_ns", 0x894)
-      .Case("sp_ns", 0x898)
-      .Default(~0U);
-
-    if (FlagsVal == ~0U)
+    auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
+    if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
       return MatchOperand_NoMatch;
 
-    if (!hasDSP() && (FlagsVal & 0x400))
-      // The _g and _nzcvqg versions are only valid if the DSP extension is
-      // available.
-      return MatchOperand_NoMatch;
-
-    if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813)
-      // basepri, basepri_max and faultmask only valid for V7m.
-      return MatchOperand_NoMatch;
-
-    if (!has8MSecExt() && (FlagsVal == 0x80a || FlagsVal == 0x80b ||
-                             (FlagsVal > 0x814 && FlagsVal < 0xc00)))
-      return MatchOperand_NoMatch;
-
-    if (!hasV8MMainline() && (FlagsVal == 0x88a || FlagsVal == 0x88b ||
-                              (FlagsVal > 0x890 && FlagsVal <= 0x893)))
-      return MatchOperand_NoMatch;
+    unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
 
     Parser.Lex(); // Eat identifier token.
-    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
+    Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
     return MatchOperand_Success;
   }
 

Modified: llvm/trunk/lib/Target/ARM/AsmParser/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/LLVMBuild.txt?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/LLVMBuild.txt Wed Jul 19 05:57:16 2017
@@ -19,5 +19,5 @@
 type = Library
 name = ARMAsmParser
 parent = ARM
-required_libraries = ARMDesc ARMInfo MC MCParser Support
+required_libraries = ARMDesc ARMInfo MC MCParser Support ARMUtils
 add_to_library_groups = ARM

Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Wed Jul 19 05:57:16 2017
@@ -15,6 +15,7 @@ tablegen(LLVM ARMGenFastISel.inc -gen-fa
 tablegen(LLVM ARMGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM ARMGenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM ARMGenSystemRegister.inc -gen-searchable-tables)
 add_public_tablegen_target(ARMCommonTableGen)
 
 # Add GlobalISel files if the user wants to build it.
@@ -73,3 +74,4 @@ add_subdirectory(AsmParser)
 add_subdirectory(Disassembler)
 add_subdirectory(InstPrinter)
 add_subdirectory(MCTargetDesc)
+add_subdirectory(Utils)

Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Wed Jul 19 05:57:16 2017
@@ -12,6 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARMInstPrinter.h"
+#include "Utils/ARMBaseInfo.h"
+#include "ARMBaseRegisterInfo.h"
+#include "ARMBaseRegisterInfo.h"
 #include "MCTargetDesc/ARMAddressingModes.h"
 #include "MCTargetDesc/ARMBaseInfo.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -789,152 +792,48 @@ void ARMInstPrinter::printMSRMaskOperand
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
   const MCOperand &Op = MI->getOperand(OpNum);
-  unsigned SpecRegRBit = Op.getImm() >> 4;
-  unsigned Mask = Op.getImm() & 0xf;
   const FeatureBitset &FeatureBits = STI.getFeatureBits();
-
   if (FeatureBits[ARM::FeatureMClass]) {
-    unsigned SYSm = Op.getImm();
+
+    unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
     unsigned Opcode = MI->getOpcode();
 
     // For writes, handle extended mask bits if the DSP extension is present.
     if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
-      switch (SYSm) {
-      case 0x400:
-        O << "apsr_g";
-        return;
-      case 0xc00:
-        O << "apsr_nzcvqg";
-        return;
-      case 0x401:
-        O << "iapsr_g";
-        return;
-      case 0xc01:
-        O << "iapsr_nzcvqg";
-        return;
-      case 0x402:
-        O << "eapsr_g";
-        return;
-      case 0xc02:
-        O << "eapsr_nzcvqg";
-        return;
-      case 0x403:
-        O << "xpsr_g";
-        return;
-      case 0xc03:
-        O << "xpsr_nzcvqg";
-        return;
+      auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm);
+      if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
+          O << TheReg->Name;
+          return;
       }
     }
 
     // Handle the basic 8-bit mask.
     SYSm &= 0xff;
-
     if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
       // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
       // alias for MSR APSR_nzcvq.
-      switch (SYSm) {
-      case 0:
-        O << "apsr_nzcvq";
-        return;
-      case 1:
-        O << "iapsr_nzcvq";
-        return;
-      case 2:
-        O << "eapsr_nzcvq";
-        return;
-      case 3:
-        O << "xpsr_nzcvq";
-        return;
+      auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm);
+      if (TheReg) {
+          O << TheReg->Name;
+          return;
       }
     }
 
-    switch (SYSm) {
-    default:
-      llvm_unreachable("Unexpected mask value!");
-    case 0:
-      O << "apsr";
-      return;
-    case 1:
-      O << "iapsr";
-      return;
-    case 2:
-      O << "eapsr";
-      return;
-    case 3:
-      O << "xpsr";
-      return;
-    case 5:
-      O << "ipsr";
-      return;
-    case 6:
-      O << "epsr";
-      return;
-    case 7:
-      O << "iepsr";
-      return;
-    case 8:
-      O << "msp";
-      return;
-    case 9:
-      O << "psp";
-      return;
-    case 16:
-      O << "primask";
-      return;
-    case 17:
-      O << "basepri";
-      return;
-    case 18:
-      O << "basepri_max";
-      return;
-    case 19:
-      O << "faultmask";
-      return;
-    case 20:
-      O << "control";
-      return;
-    case 10:
-      O << "msplim";
-      return;
-    case 11:
-      O << "psplim";
-      return;
-    case 0x88:
-      O << "msp_ns";
-      return;
-    case 0x89:
-      O << "psp_ns";
-      return;
-    case 0x8a:
-      O << "msplim_ns";
-      return;
-    case 0x8b:
-      O << "psplim_ns";
-      return;
-    case 0x90:
-      O << "primask_ns";
-      return;
-    case 0x91:
-      O << "basepri_ns";
-      return;
-    case 0x92:
-      O << "basepri_max_ns";
-      return;
-    case 0x93:
-      O << "faultmask_ns";
-      return;
-    case 0x94:
-      O << "control_ns";
-      return;
-    case 0x98:
-      O << "sp_ns";
+    auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm);
+    if (TheReg) {
+      O << TheReg->Name;
       return;
     }
+
+    llvm_unreachable("Unexpected mask value!");
+    return;
   }
 
   // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
   // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
+  unsigned SpecRegRBit = Op.getImm() >> 4;
+  unsigned Mask = Op.getImm() & 0xf;
+
   if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
     O << "APSR_";
     switch (Mask) {

Modified: llvm/trunk/lib/Target/ARM/InstPrinter/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/LLVMBuild.txt?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/LLVMBuild.txt Wed Jul 19 05:57:16 2017
@@ -19,5 +19,5 @@
 type = Library
 name = ARMAsmPrinter
 parent = ARM
-required_libraries = MC Support
+required_libraries = MC Support ARMUtils
 add_to_library_groups = ARM

Modified: llvm/trunk/lib/Target/ARM/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/LLVMBuild.txt?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/ARM/LLVMBuild.txt Wed Jul 19 05:57:16 2017
@@ -16,7 +16,7 @@
 ;===------------------------------------------------------------------------===;
 
 [common]
-subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
+subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo Utils
 
 [component_0]
 type = TargetGroup
@@ -31,5 +31,5 @@ has_jit = 1
 type = Library
 name = ARMCodeGen
 parent = ARM
-required_libraries = ARMAsmPrinter ARMDesc ARMInfo Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target GlobalISel
+required_libraries = ARMAsmPrinter ARMDesc ARMInfo Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target GlobalISel ARMUtils
 add_to_library_groups = ARM

Added: llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.cpp?rev=308456&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.cpp (added)
+++ llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.cpp Wed Jul 19 05:57:16 2017
@@ -0,0 +1,44 @@
+//===-- ARMBaseInfo.cpp - ARM Base encoding information------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides basic encoding and assembly information for ARM.
+//
+//===----------------------------------------------------------------------===//
+#include "ARMBaseInfo.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Regex.h"
+
+using namespace llvm;
+namespace llvm {
+  namespace ARMSysReg {
+
+// lookup system register using 12-bit SYSm value.
+// Note: the search is uniqued using M1 mask
+const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm) {
+  return lookupMClassSysRegByM1Encoding12(SYSm);
+}
+
+// returns APSR with _<bits> qualifier.
+// Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
+const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm) {
+  return lookupMClassSysRegByM2M3Encoding8((1<<9)|(SYSm & 0xFF));
+}
+
+// lookup system registers using 8-bit SYSm value
+const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm) {
+  return ARMSysReg::lookupMClassSysRegByM2M3Encoding8((1<<8)|(SYSm & 0xFF));
+}
+
+#define GET_MCLASSSYSREG_IMPL
+#include "ARMGenSystemRegister.inc"
+
+  }
+}

Added: llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.h?rev=308456&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.h (added)
+++ llvm/trunk/lib/Target/ARM/Utils/ARMBaseInfo.h Wed Jul 19 05:57:16 2017
@@ -0,0 +1,64 @@
+//===-- ARMBaseInfo.h - Top level definitions for ARM ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains small standalone helper functions and enum definitions for
+// the ARM target useful for the compiler back-end and the MC libraries.
+// As such, it deliberately does not include references to LLVM core
+// code gen types, passes, etc..
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
+#define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "MCTargetDesc/ARMMCTargetDesc.h"
+
+namespace llvm {
+
+namespace ARMSysReg {
+  struct MClassSysReg {
+    const char *Name;
+    uint16_t M1Encoding12;
+    uint16_t M2M3Encoding8;
+    uint16_t Encoding;
+    FeatureBitset FeaturesRequired;
+
+    // return true if FeaturesRequired are all present in ActiveFeatures
+    bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
+      return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
+    }
+
+    // returns true if TestFeatures are all present in FeaturesRequired
+    bool isInRequiredFeatures(FeatureBitset TestFeatures) const {
+      return (FeaturesRequired & TestFeatures) == TestFeatures;
+    }
+  };
+
+  #define GET_MCLASSSYSREG_DECL
+  #include "ARMGenSystemRegister.inc"
+
+  // lookup system register using 12-bit SYSm value.
+  // Note: the search is uniqued using M1 mask
+  const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
+
+  // returns APSR with _<bits> qualifier.
+  // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
+  const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
+
+  // lookup system registers using 8-bit SYSm value
+  const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
+
+} // end namespace ARMSysReg
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H

Added: llvm/trunk/lib/Target/ARM/Utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Utils/CMakeLists.txt?rev=308456&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/Utils/CMakeLists.txt (added)
+++ llvm/trunk/lib/Target/ARM/Utils/CMakeLists.txt Wed Jul 19 05:57:16 2017
@@ -0,0 +1,3 @@
+add_llvm_library(LLVMARMUtils
+  ARMBaseInfo.cpp
+  )

Added: llvm/trunk/lib/Target/ARM/Utils/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Utils/LLVMBuild.txt?rev=308456&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM/Utils/LLVMBuild.txt (added)
+++ llvm/trunk/lib/Target/ARM/Utils/LLVMBuild.txt Wed Jul 19 05:57:16 2017
@@ -0,0 +1,24 @@
+;===- ./lib/Target/ARM/Utils/LLVMBuild.txt ----------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = ARMUtils
+parent = ARM
+required_libraries = Support
+add_to_library_groups = ARM
+

Modified: llvm/trunk/test/CodeGen/ARM/special-reg-v8m-main.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/special-reg-v8m-main.ll?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/special-reg-v8m-main.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/special-reg-v8m-main.ll Wed Jul 19 05:57:16 2017
@@ -1,7 +1,7 @@
 ; RUN: not llc < %s -mtriple=thumbv8m.base-none-eabi 2>&1 | FileCheck %s --check-prefix=BASELINE
 ; RUN: llc < %s -mtriple=thumbv8m.main-none-eabi -mattr=+dsp 2>&1 | FileCheck %s --check-prefix=MAINLINE
 
-; BASELINE: LLVM ERROR: Invalid register name "basepri_max_ns".
+; BASELINE: LLVM ERROR: Invalid register name "faultmask_ns".
 
 define i32 @read_mclass_registers() nounwind {
 entry:
@@ -31,7 +31,6 @@ entry:
   ; MAINLINE:   mrs r1, faultmask_ns
   ; MAINLINE:   mrs r1, control_ns
   ; MAINLINE:   mrs r1, sp_ns
-  ; MAINLINE:   mrs r1, basepri_max_ns
 
   %0 = call i32 @llvm.read_register.i32(metadata !0)
   %1 = call i32 @llvm.read_register.i32(metadata !4)
@@ -82,9 +81,7 @@ entry:
   %add23 = add i32 %add22, %23
   %24 = call i32 @llvm.read_register.i32(metadata !36)
   %add24 = add i32 %add23, %24
-  %25 = call i32 @llvm.read_register.i32(metadata !37)
-  %add25 = add i32 %add24, %25
-  ret i32 %add25
+  ret i32 %add24
 }
 
 define void @write_mclass_registers(i32 %x) nounwind {
@@ -127,7 +124,6 @@ entry:
   ; MAINLINE:   msr faultmask_ns, r0
   ; MAINLINE:   msr control_ns, r0
   ; MAINLINE:   msr sp_ns, r0
-  ; MAINLINE:   msr basepri_max_ns, r0
 
   call void @llvm.write_register.i32(metadata !0, i32 %x)
   call void @llvm.write_register.i32(metadata !1, i32 %x)
@@ -166,7 +162,6 @@ entry:
   call void @llvm.write_register.i32(metadata !34, i32 %x)
   call void @llvm.write_register.i32(metadata !35, i32 %x)
   call void @llvm.write_register.i32(metadata !36, i32 %x)
-  call void @llvm.write_register.i32(metadata !37, i32 %x)
   ret void
 }
 
@@ -210,5 +205,4 @@ declare void @llvm.write_register.i32(me
 !34 = !{!"faultmask_ns"}
 !35 = !{!"control_ns"}
 !36 = !{!"sp_ns"}
-!37 = !{!"basepri_max_ns"}
 

Modified: llvm/trunk/test/MC/ARM/thumbv8m.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumbv8m.s?rev=308456&r1=308455&r2=308456&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumbv8m.s (original)
+++ llvm/trunk/test/MC/ARM/thumbv8m.s Wed Jul 19 05:57:16 2017
@@ -215,17 +215,12 @@ MSR PSPLIM,r9
 // CHECK: msr psplim, r9             @ encoding: [0x89,0xf3,0x0b,0x88]
 
 MRS r10, MSPLIM_NS
-// CHECK-MAINLINE: mrs r10, msplim_ns    @ encoding: [0xef,0xf3,0x8a,0x8a]
-// UNDEF-BASELINE: error: invalid operand for instruction
+// CHECK: mrs r10, msplim_ns    @ encoding: [0xef,0xf3,0x8a,0x8a]
 MSR PSPLIM_NS, r11
-// CHECK-MAINLINE: msr psplim_ns, r11    @ encoding: [0x8b,0xf3,0x8b,0x88]
-// UNDEF-BASELINE: error: invalid operand for instruction
+// CHECK: msr psplim_ns, r11    @ encoding: [0x8b,0xf3,0x8b,0x88]
 MRS r12, BASEPRI_NS
 // CHECK-MAINLINE: mrs r12, basepri_ns   @ encoding: [0xef,0xf3,0x91,0x8c]
 // UNDEF-BASELINE: error: invalid operand for instruction
-MRS r12, BASEPRI_MAX_NS
-// CHECK-MAINLINE: mrs r12, basepri_max_ns @ encoding: [0xef,0xf3,0x92,0x8c]
-// UNDEF-BASELINE: error: invalid operand for instruction
 MSR FAULTMASK_NS, r14
 // CHECK-MAINLINE: msr faultmask_ns, lr  @ encoding: [0x8e,0xf3,0x93,0x88]
 // UNDEF-BASELINE: error: invalid operand for instruction




More information about the llvm-commits mailing list