[llvm] r205875 - [ARM64] Rework system register parsing to overcome SPSel clash in MSR variants.

Bradley Smith bradley.smith at arm.com
Wed Apr 9 07:43:06 PDT 2014


Author: brasmi01
Date: Wed Apr  9 09:43:06 2014
New Revision: 205875

URL: http://llvm.org/viewvc/llvm-project?rev=205875&view=rev
Log:
[ARM64] Rework system register parsing to overcome SPSel clash in MSR variants.

Added:
    llvm/trunk/test/MC/ARM64/spsel-sysreg.s   (with props)
Modified:
    llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
    llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td?rev=205875&r1=205874&r2=205875&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td Wed Apr  9 09:43:06 2014
@@ -701,9 +701,7 @@ class CRmSystemI<Operand crmtype, bits<3
 // a different subset of registers can be accessed through each instruction.
 def MRSSystemRegisterOperand : AsmOperandClass {
   let Name = "MRSSystemRegister";
-  let ParserMethod = "tryParseMRSSystemRegister";
-  let RenderMethod = "addSystemRegisterOperands";
-  let PredicateMethod = "isSystemRegister";
+  let ParserMethod = "tryParseSysReg";
 }
 // concatenation of 1, op0, op1, CRn, CRm, op2. 16-bit immediate.
 def mrs_sysreg_op : Operand<i32> {
@@ -714,9 +712,7 @@ def mrs_sysreg_op : Operand<i32> {
 
 def MSRSystemRegisterOperand : AsmOperandClass {
   let Name = "MSRSystemRegister";
-  let ParserMethod = "tryParseMSRSystemRegister";
-  let RenderMethod = "addSystemRegisterOperands";
-  let PredicateMethod = "isSystemRegister";
+  let ParserMethod = "tryParseSysReg";
 }
 def msr_sysreg_op : Operand<i32> {
   let ParserMatchClass = MSRSystemRegisterOperand;
@@ -743,7 +739,7 @@ class MSRI : RtSystemI<0, (outs), (ins m
 
 def SystemCPSRFieldOperand : AsmOperandClass {
   let Name = "SystemCPSRField";
-  let ParserMethod = "tryParseCPSRField";
+  let ParserMethod = "tryParseSysReg";
 }
 def cpsrfield_op : Operand<i32> {
   let ParserMatchClass = SystemCPSRFieldOperand;

Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=205875&r1=205874&r2=205875&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Wed Apr  9 09:43:06 2014
@@ -89,8 +89,7 @@ private:
   OperandMatchResultTy tryParseNoIndexMemory(OperandVector &Operands);
   OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
   OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
-  OperandMatchResultTy tryParseMSRSystemRegister(OperandVector &Operands);
-  OperandMatchResultTy tryParseCPSRField(OperandVector &Operands);
+  OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
   OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
   OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
   OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
@@ -142,14 +141,13 @@ private:
     k_VectorList,
     k_VectorIndex,
     k_Token,
+    k_SysReg,
     k_SysCR,
     k_Prefetch,
     k_Shifter,
     k_Extend,
     k_FPImm,
-    k_Barrier,
-    k_SystemRegister,
-    k_CPSRField
+    k_Barrier
   } Kind;
 
   SMLoc StartLoc, EndLoc, OffsetLoc;
@@ -188,14 +186,9 @@ private:
     unsigned Val; // Not the enum since not all values have names.
   };
 
-  struct SystemRegisterOp {
-    // 16-bit immediate, usually from the ARM64SysReg::SysRegValues enum
-    // but not limited to those values.
-    uint16_t Val;
-  };
-
-  struct CPSRFieldOp {
-    ARM64PState::PStateValues Field;
+  struct SysRegOp {
+    const char *Data;
+    unsigned Length;
   };
 
   struct SysCRImmOp {
@@ -232,8 +225,7 @@ private:
     struct ImmOp Imm;
     struct FPImmOp FPImm;
     struct BarrierOp Barrier;
-    struct SystemRegisterOp SystemRegister;
-    struct CPSRFieldOp CPSRField;
+    struct SysRegOp SysReg;
     struct SysCRImmOp SysCRImm;
     struct PrefetchOp Prefetch;
     struct ShifterOp Shifter;
@@ -266,12 +258,6 @@ public:
     case k_Barrier:
       Barrier = o.Barrier;
       break;
-    case k_SystemRegister:
-      SystemRegister = o.SystemRegister;
-      break;
-    case k_CPSRField:
-      CPSRField = o.CPSRField;
-      break;
     case k_Register:
       Reg = o.Reg;
       break;
@@ -281,6 +267,9 @@ public:
     case k_VectorIndex:
       VectorIndex = o.VectorIndex;
       break;
+    case k_SysReg:
+      SysReg = o.SysReg;
+      break;
     case k_SysCR:
       SysCRImm = o.SysCRImm;
       break;
@@ -331,16 +320,6 @@ public:
     return Barrier.Val;
   }
 
-  uint16_t getSystemRegister() const {
-    assert(Kind == k_SystemRegister && "Invalid access!");
-    return SystemRegister.Val;
-  }
-
-  ARM64PState::PStateValues getCPSRField() const {
-    assert(Kind == k_CPSRField && "Invalid access!");
-    return CPSRField.Field;
-  }
-
   unsigned getReg() const {
     assert(Kind == k_Register && "Invalid access!");
     return Reg.RegNum;
@@ -361,6 +340,11 @@ public:
     return VectorIndex.Val;
   }
 
+  StringRef getSysReg() const {
+    assert(Kind == k_SysReg && "Invalid access!");
+    return StringRef(SysReg.Data, SysReg.Length);
+  }
+
   unsigned getSysCR() const {
     assert(Kind == k_SysCR && "Invalid access!");
     return SysCRImm.Val;
@@ -665,14 +649,31 @@ public:
 
   bool isFPImm() const { return Kind == k_FPImm; }
   bool isBarrier() const { return Kind == k_Barrier; }
-  bool isSystemRegister() const {
-    if (Kind == k_SystemRegister)
-      return true;
-    // SPSel is legal for both the system register and the CPSR-field
-    // variants of MSR, so special case that. Fugly.
-    return (Kind == k_CPSRField && getCPSRField() == ARM64PState::SPSel);
+  bool isSysReg() const { return Kind == k_SysReg; }
+  bool isMRSSystemRegister() const {
+    if (!isSysReg()) return false;
+
+    bool IsKnownRegister;
+    ARM64SysReg::MRSMapper().fromString(getSysReg(), IsKnownRegister);
+
+    return IsKnownRegister;
+  }
+  bool isMSRSystemRegister() const {
+    if (!isSysReg()) return false;
+
+    bool IsKnownRegister;
+    ARM64SysReg::MSRMapper().fromString(getSysReg(), IsKnownRegister);
+
+    return IsKnownRegister;
+  }
+  bool isSystemCPSRField() const {
+    if (!isSysReg()) return false;
+
+    bool IsKnownRegister;
+    ARM64PState::PStateMapper().fromString(getSysReg(), IsKnownRegister);
+
+    return IsKnownRegister;
   }
-  bool isSystemCPSRField() const { return Kind == k_CPSRField; }
   bool isReg() const { return Kind == k_Register && !Reg.isVector; }
   bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
 
@@ -1280,19 +1281,31 @@ public:
     Inst.addOperand(MCOperand::CreateImm(getBarrier()));
   }
 
-  void addSystemRegisterOperands(MCInst &Inst, unsigned N) const {
+  void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
-    if (Kind == k_SystemRegister)
-      Inst.addOperand(MCOperand::CreateImm(getSystemRegister()));
-    else {
-      assert(Kind == k_CPSRField && getCPSRField() == ARM64PState::SPSel);
-      Inst.addOperand(MCOperand::CreateImm(ARM64SysReg::SPSel));
-    }
+
+    bool Valid;
+    uint32_t Bits = ARM64SysReg::MRSMapper().fromString(getSysReg(), Valid);
+
+    Inst.addOperand(MCOperand::CreateImm(Bits));
+  }
+
+  void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+
+    bool Valid;
+    uint32_t Bits = ARM64SysReg::MSRMapper().fromString(getSysReg(), Valid);
+
+    Inst.addOperand(MCOperand::CreateImm(Bits));
   }
 
   void addSystemCPSRFieldOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
-    Inst.addOperand(MCOperand::CreateImm(getCPSRField()));
+
+    bool Valid;
+    uint32_t Bits = ARM64PState::PStateMapper().fromString(getSysReg(), Valid);
+
+    Inst.addOperand(MCOperand::CreateImm(Bits));
   }
 
   void addSysCROperands(MCInst &Inst, unsigned N) const {
@@ -1606,19 +1619,10 @@ public:
     return Op;
   }
 
-  static ARM64Operand *CreateSystemRegister(uint16_t Val, SMLoc S,
-                                            MCContext &Ctx) {
-    ARM64Operand *Op = new ARM64Operand(k_SystemRegister, Ctx);
-    Op->SystemRegister.Val = Val;
-    Op->StartLoc = S;
-    Op->EndLoc = S;
-    return Op;
-  }
-
-  static ARM64Operand *CreateCPSRField(ARM64PState::PStateValues Field, SMLoc S,
-                                       MCContext &Ctx) {
-    ARM64Operand *Op = new ARM64Operand(k_CPSRField, Ctx);
-    Op->CPSRField.Field = Field;
+  static ARM64Operand *CreateSysReg(StringRef Str, SMLoc S, MCContext &Ctx) {
+    ARM64Operand *Op = new ARM64Operand(k_SysReg, Ctx);
+    Op->SysReg.Data = Str.data();
+    Op->SysReg.Length = Str.size();
     Op->StartLoc = S;
     Op->EndLoc = S;
     return Op;
@@ -1708,27 +1712,7 @@ void ARM64Operand::print(raw_ostream &OS
     if (Valid)
       OS << "<barrier " << Name << ">";
     else
-      OS << "<barrier invalid #" << getCPSRField() << ">";
-    break;
-  }
-  case k_SystemRegister: {
-    bool Valid;
-    StringRef Name = ARM64SysReg::MRSMapper().toString(getSystemRegister(), Valid);
-    if (!Valid)
-      Name = ARM64SysReg::MSRMapper().toString(getSystemRegister(), Valid);
-    if (Valid)
-      OS << "<systemreg " << Name << ">";
-    else
-      OS << "<systemreg invalid #" << getSystemRegister() << ">";
-    break;
-  }
-  case k_CPSRField: {
-    bool Valid;
-    StringRef Name = ARM64PState::PStateMapper().toString(getCPSRField(), Valid);
-    if (Valid)
-      OS << "<cpsrfield " << Name << ">";
-    else
-      OS << "<cpsrfield invalid #" << getCPSRField() << ">";
+      OS << "<barrier invalid #" << getBarrier() << ">";
     break;
   }
   case k_Immediate:
@@ -1751,6 +1735,9 @@ void ARM64Operand::print(raw_ostream &OS
   case k_VectorIndex:
     OS << "<vectorindex " << getVectorIndex() << ">";
     break;
+  case k_SysReg:
+    OS << "<sysreg: " << getSysReg() << '>';
+    break;
   case k_Token:
     OS << "'" << getToken() << "'";
     break;
@@ -2612,65 +2599,15 @@ ARM64AsmParser::tryParseBarrierOperand(O
 }
 
 ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseMRSSystemRegister(OperandVector &Operands) {
+ARM64AsmParser::tryParseSysReg(OperandVector &Operands) {
   const AsmToken &Tok = Parser.getTok();
 
   if (Tok.isNot(AsmToken::Identifier))
     return MatchOperand_NoMatch;
 
-  bool Valid;
-  auto Mapper = ARM64SysReg::MRSMapper();
-  uint32_t Reg = Mapper.fromString(Tok.getString(), Valid);
-  
-  if (Valid) {
-    Operands.push_back(
-      ARM64Operand::CreateSystemRegister((uint16_t)Reg, getLoc(),
-                                         getContext()));
-    Parser.Lex(); // Consume the register name.
-    return MatchOperand_Success;
-  }
-
-  return MatchOperand_NoMatch;
-}
-
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseMSRSystemRegister(OperandVector &Operands) {
-  const AsmToken &Tok = Parser.getTok();
-
-  if (Tok.isNot(AsmToken::Identifier))
-    return MatchOperand_NoMatch;
-
-  bool Valid;
-  auto Mapper = ARM64SysReg::MSRMapper();
-  uint32_t Reg = Mapper.fromString(Tok.getString(), Valid);
-  
-  if (Valid) {
-    Operands.push_back(
-      ARM64Operand::CreateSystemRegister((uint16_t)Reg, getLoc(),
-                                         getContext()));
-    Parser.Lex(); // Consume the register name.
-    return MatchOperand_Success;
-  }
-
-  return MatchOperand_NoMatch;
-}
-
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseCPSRField(OperandVector &Operands) {
-  const AsmToken &Tok = Parser.getTok();
-
-  if (Tok.isNot(AsmToken::Identifier))
-    return MatchOperand_NoMatch;
-
-  bool Valid;
-  ARM64PState::PStateValues Field = (ARM64PState::PStateValues)
-    ARM64PState::PStateMapper().fromString(Tok.getString(), Valid);
-
-  if (!Valid)
-    return MatchOperand_NoMatch;
-  Operands.push_back(
-      ARM64Operand::CreateCPSRField(Field, getLoc(), getContext()));
-  Parser.Lex(); // Consume the register name.
+  Operands.push_back(ARM64Operand::CreateSysReg(Tok.getString(), getLoc(),
+                     getContext()));
+  Parser.Lex(); // Eat identifier
 
   return MatchOperand_Success;
 }

Added: llvm/trunk/test/MC/ARM64/spsel-sysreg.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/spsel-sysreg.s?rev=205875&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM64/spsel-sysreg.s (added)
+++ llvm/trunk/test/MC/ARM64/spsel-sysreg.s Wed Apr  9 09:43:06 2014
@@ -0,0 +1,24 @@
+// RUN: not llvm-mc -triple arm64 -show-encoding < %s 2>%t | FileCheck %s
+// RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
+
+msr SPSel, #0
+msr SPSel, x0
+msr DAIFSet, #0
+msr ESR_EL1, x0
+mrs x0, SPSel
+mrs x0, ESR_EL1
+
+// CHECK: msr SPSEL, #0               // encoding: [0xbf,0x40,0x00,0xd5]
+// CHECK: msr SPSEL, x0               // encoding: [0x00,0x42,0x18,0xd5]
+// CHECK: msr DAIFSET, #0             // encoding: [0xdf,0x40,0x03,0xd5]
+// CHECK: msr ESR_EL1, x0             // encoding: [0x00,0x52,0x18,0xd5]
+// CHECK: mrs x0, SPSEL               // encoding: [0x00,0x42,0x38,0xd5]
+// CHECK: mrs x0, ESR_EL1             // encoding: [0x00,0x52,0x38,0xd5]
+
+
+msr DAIFSet, x0
+msr ESR_EL1, #0
+mrs x0, DAIFSet
+// CHECK-ERRORS: error: invalid operand for instruction
+// CHECK-ERRORS: error: invalid operand for instruction
+// CHECK-ERRORS: error: invalid operand for instruction

Propchange: llvm/trunk/test/MC/ARM64/spsel-sysreg.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/test/MC/ARM64/spsel-sysreg.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id





More information about the llvm-commits mailing list