[ARM64] Conditionalize CPU specific system registers on subtarget features
authorBradley Smith <bradley.smith@arm.com>
Thu, 1 May 2014 10:25:36 +0000 (10:25 +0000)
committerBradley Smith <bradley.smith@arm.com>
Thu, 1 May 2014 10:25:36 +0000 (10:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207742 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
lib/Target/ARM64/Utils/ARM64BaseInfo.cpp
lib/Target/ARM64/Utils/ARM64BaseInfo.h
test/MC/ARM64/system-encoding.s
test/MC/ARM64/target-specific-sysreg.s [new file with mode: 0644]

index 764999b4e7b0965032933711b6d77fbc22fe8662..bad7a1ce58a2fb0289386502e67e2cd875e1f929 100644 (file)
@@ -195,6 +195,9 @@ private:
   struct SysRegOp {
     const char *Data;
     unsigned Length;
+    uint64_t FeatureBits; // We need to pass through information about which
+                          // core we are compiling for so that the SysReg
+                          // Mappers can appropriately conditionalize.
   };
 
   struct SysCRImmOp {
@@ -351,6 +354,11 @@ public:
     return StringRef(SysReg.Data, SysReg.Length);
   }
 
+  uint64_t getSysRegFeatureBits() const {
+    assert(Kind == k_SysReg && "Invalid access!");
+    return SysReg.FeatureBits;
+  }
+
   unsigned getSysCR() const {
     assert(Kind == k_SysCR && "Invalid access!");
     return SysCRImm.Val;
@@ -668,7 +676,8 @@ public:
     if (!isSysReg()) return false;
 
     bool IsKnownRegister;
-    ARM64SysReg::MRSMapper().fromString(getSysReg(), IsKnownRegister);
+    auto Mapper = ARM64SysReg::MRSMapper(getSysRegFeatureBits());
+    Mapper.fromString(getSysReg(), IsKnownRegister);
 
     return IsKnownRegister;
   }
@@ -676,7 +685,8 @@ public:
     if (!isSysReg()) return false;
 
     bool IsKnownRegister;
-    ARM64SysReg::MSRMapper().fromString(getSysReg(), IsKnownRegister);
+    auto Mapper = ARM64SysReg::MSRMapper(getSysRegFeatureBits());
+    Mapper.fromString(getSysReg(), IsKnownRegister);
 
     return IsKnownRegister;
   }
@@ -1332,7 +1342,8 @@ public:
     assert(N == 1 && "Invalid number of operands!");
 
     bool Valid;
-    uint32_t Bits = ARM64SysReg::MRSMapper().fromString(getSysReg(), Valid);
+    auto Mapper = ARM64SysReg::MRSMapper(getSysRegFeatureBits());
+    uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
 
     Inst.addOperand(MCOperand::CreateImm(Bits));
   }
@@ -1341,7 +1352,8 @@ public:
     assert(N == 1 && "Invalid number of operands!");
 
     bool Valid;
-    uint32_t Bits = ARM64SysReg::MSRMapper().fromString(getSysReg(), Valid);
+    auto Mapper = ARM64SysReg::MSRMapper(getSysRegFeatureBits());
+    uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
 
     Inst.addOperand(MCOperand::CreateImm(Bits));
   }
@@ -1666,10 +1678,12 @@ public:
     return Op;
   }
 
-  static ARM64Operand *CreateSysReg(StringRef Str, SMLoc S, MCContext &Ctx) {
+  static ARM64Operand *CreateSysReg(StringRef Str, SMLoc S,
+                                    uint64_t FeatureBits, MCContext &Ctx) {
     ARM64Operand *Op = new ARM64Operand(k_SysReg, Ctx);
     Op->SysReg.Data = Str.data();
     Op->SysReg.Length = Str.size();
+    Op->SysReg.FeatureBits = FeatureBits;
     Op->StartLoc = S;
     Op->EndLoc = S;
     return Op;
@@ -2682,7 +2696,7 @@ ARM64AsmParser::tryParseSysReg(OperandVector &Operands) {
     return MatchOperand_NoMatch;
 
   Operands.push_back(ARM64Operand::CreateSysReg(Tok.getString(), getLoc(),
-                     getContext()));
+                     STI.getFeatureBits(), getContext()));
   Parser.Lex(); // Eat identifier
 
   return MatchOperand_Success;
index 0fc559c5cf7e9ae0d0c1b9cd6e049da99c4e84c2..f53592a73aadef0fd05b8702fb8b5857d5d8aab2 100644 (file)
@@ -601,11 +601,15 @@ static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm,
 static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
                                             uint64_t Address,
                                             const void *Decoder) {
+  const ARM64Disassembler *Dis =
+      static_cast<const ARM64Disassembler *>(Decoder);
+  const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
+
   Imm |= 0x8000;
   Inst.addOperand(MCOperand::CreateImm(Imm));
 
   bool ValidNamed;
-  (void)ARM64SysReg::MRSMapper().toString(Imm, ValidNamed);
+  (void)ARM64SysReg::MRSMapper(STI.getFeatureBits()).toString(Imm, ValidNamed);
 
   return ValidNamed ? Success : Fail;
 }
@@ -613,11 +617,15 @@ static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
 static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
                                             uint64_t Address,
                                             const void *Decoder) {
+  const ARM64Disassembler *Dis =
+      static_cast<const ARM64Disassembler *>(Decoder);
+  const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
+
   Imm |= 0x8000;
   Inst.addOperand(MCOperand::CreateImm(Imm));
 
   bool ValidNamed;
-  (void)ARM64SysReg::MSRMapper().toString(Imm, ValidNamed);
+  (void)ARM64SysReg::MSRMapper(STI.getFeatureBits()).toString(Imm, ValidNamed);
 
   return ValidNamed ? Success : Fail;
 }
index 65d5eae2d21aa097f7f948feaf6b7b3572172b52..8d217a9b394db91730f3c4e40038050497b8fd6e 100644 (file)
@@ -1397,7 +1397,7 @@ void ARM64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo,
   unsigned Val = MI->getOperand(OpNo).getImm();
 
   bool Valid;
-  auto Mapper = ARM64SysReg::MRSMapper();
+  auto Mapper = ARM64SysReg::MRSMapper(getAvailableFeatures());
   std::string Name = Mapper.toString(Val, Valid);
 
   if (Valid)
@@ -1409,7 +1409,7 @@ void ARM64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo,
   unsigned Val = MI->getOperand(OpNo).getImm();
 
   bool Valid;
-  auto Mapper = ARM64SysReg::MSRMapper();
+  auto Mapper = ARM64SysReg::MSRMapper(getAvailableFeatures());
   std::string Name = Mapper.toString(Val, Valid);
 
   if (Valid)
index 8ab18e5fdbdbd91e749b5dfd8c82792863cc4ab7..5142d18c23cc19cc74da927055ed5098263e4491 100644 (file)
@@ -245,7 +245,8 @@ const ARM64NamedImmMapper::Mapping ARM64SysReg::MRSMapper::MRSPairs[] = {
   {"ich_elsr_el2", ICH_ELSR_EL2}
 };
 
-ARM64SysReg::MRSMapper::MRSMapper() {
+ARM64SysReg::MRSMapper::MRSMapper(uint64_t FeatureBits)
+  : SysRegMapper(FeatureBits) {
     InstPairs = &MRSPairs[0];
     NumInstPairs = llvm::array_lengthof(MRSPairs);
 }
@@ -268,7 +269,8 @@ const ARM64NamedImmMapper::Mapping ARM64SysReg::MSRMapper::MSRPairs[] = {
   {"icc_sgi0r_el1", ICC_SGI0R_EL1}
 };
 
-ARM64SysReg::MSRMapper::MSRMapper() {
+ARM64SysReg::MSRMapper::MSRMapper(uint64_t FeatureBits)
+  : SysRegMapper(FeatureBits) {
     InstPairs = &MSRPairs[0];
     NumInstPairs = llvm::array_lengthof(MSRPairs);
 }
@@ -750,14 +752,19 @@ const ARM64NamedImmMapper::Mapping ARM64SysReg::SysRegMapper::SysRegPairs[] = {
   {"ich_lr12_el2", ICH_LR12_EL2},
   {"ich_lr13_el2", ICH_LR13_EL2},
   {"ich_lr14_el2", ICH_LR14_EL2},
-  {"ich_lr15_el2", ICH_LR15_EL2},
+  {"ich_lr15_el2", ICH_LR15_EL2}
+};
+
+const ARM64NamedImmMapper::Mapping
+ARM64SysReg::SysRegMapper::CycloneSysRegPairs[] = {
   {"cpm_ioacc_ctl_el3", CPM_IOACC_CTL_EL3}
 };
 
 uint32_t
 ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
-  // First search the registers shared by all
   std::string NameLower = Name.lower();
+
+  // First search the registers shared by all
   for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
     if (SysRegPairs[i].Name == NameLower) {
       Valid = true;
@@ -765,6 +772,16 @@ ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
     }
   }
 
+  // Next search for target specific registers
+  if (FeatureBits & ARM64::ProcCyclone) {
+    for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
+      if (CycloneSysRegPairs[i].Name == NameLower) {
+        Valid = true;
+        return CycloneSysRegPairs[i].Value;
+      }
+    }
+  }
+
   // Now try the instruction-specific registers (either read-only or
   // write-only).
   for (unsigned i = 0; i < NumInstPairs; ++i) {
@@ -798,6 +815,7 @@ ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
 
 std::string
 ARM64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
+  // First search the registers shared by all
   for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
     if (SysRegPairs[i].Value == Bits) {
       Valid = true;
@@ -805,6 +823,18 @@ ARM64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
     }
   }
 
+  // Next search for target specific registers
+  if (FeatureBits & ARM64::ProcCyclone) {
+    for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
+      if (CycloneSysRegPairs[i].Value == Bits) {
+        Valid = true;
+        return CycloneSysRegPairs[i].Name;
+      }
+    }
+  }
+
+  // Now try the instruction-specific registers (either read-only or
+  // write-only).
   for (unsigned i = 0; i < NumInstPairs; ++i) {
     if (InstPairs[i].Value == Bits) {
       Valid = true;
index ef4caefab9438fe725437ed4047eb10107af46df..8075d6b37c9a1b267b3c2fb05b3728e260ba64ee 100644 (file)
@@ -1136,8 +1136,10 @@ namespace ARM64SysReg {
     ICH_LR13_EL2      = 0xe66d, // 11  100  1100  1101  101
     ICH_LR14_EL2      = 0xe66e, // 11  100  1100  1101  110
     ICH_LR15_EL2      = 0xe66f, // 11  100  1100  1101  111
+  };
 
-    // Cyclone specific system registers
+  // Cyclone specific system registers
+  enum CycloneSysRegValues {
     CPM_IOACC_CTL_EL3 = 0xff90
   };
 
@@ -1147,23 +1149,25 @@ namespace ARM64SysReg {
   // this one case.
   struct SysRegMapper {
     static const ARM64NamedImmMapper::Mapping SysRegPairs[];
+    static const ARM64NamedImmMapper::Mapping CycloneSysRegPairs[];
 
     const ARM64NamedImmMapper::Mapping *InstPairs;
     size_t NumInstPairs;
+    uint64_t FeatureBits;
 
-    SysRegMapper() {}
+    SysRegMapper(uint64_t FeatureBits) : FeatureBits(FeatureBits) { }
     uint32_t fromString(StringRef Name, bool &Valid) const;
     std::string toString(uint32_t Bits, bool &Valid) const;
   };
 
   struct MSRMapper : SysRegMapper {
     static const ARM64NamedImmMapper::Mapping MSRPairs[];
-    MSRMapper();
+    MSRMapper(uint64_t FeatureBits);
   };
 
   struct MRSMapper : SysRegMapper {
     static const ARM64NamedImmMapper::Mapping MRSPairs[];
-    MRSMapper();
+    MRSMapper(uint64_t FeatureBits);
   };
 
   uint32_t ParseGenericRegister(StringRef Name, bool &Valid);
index 9b3238bfb13ab9e49e9af85dd0323a016ee8abc1..fc17a1bdf24cc81782f74c30e6ff1bb34f082d0d 100644 (file)
@@ -586,14 +586,12 @@ foo:
   msr RMR_EL3, x0
   msr RMR_EL2, x0
   msr RMR_EL1, x0
-  msr CPM_IOACC_CTL_EL3, x0
   msr OSLAR_EL1, x3
   msr DBGDTRTX_EL0, x3
         
 ; CHECK: msr   RMR_EL3, x0             ; encoding: [0x40,0xc0,0x1e,0xd5]
 ; CHECK: msr   RMR_EL2, x0             ; encoding: [0x40,0xc0,0x1c,0xd5]
 ; CHECK: msr   RMR_EL1, x0             ; encoding: [0x40,0xc0,0x18,0xd5]
-; CHECK: msr   CPM_IOACC_CTL_EL3, x0   ; encoding: [0x00,0xf2,0x1f,0xd5]
 ; CHECK: msr   OSLAR_EL1, x3           ; encoding: [0x83,0x10,0x10,0xd5]
 ; CHECK: msr   DBGDTRTX_EL0, x3        ; encoding: [0x03,0x05,0x13,0xd5]
         
diff --git a/test/MC/ARM64/target-specific-sysreg.s b/test/MC/ARM64/target-specific-sysreg.s
new file mode 100644 (file)
index 0000000..05cea3a
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: not llvm-mc -triple arm64 -mcpu=generic -show-encoding < %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CHECK-GENERIC
+//
+// RUN: llvm-mc -triple arm64 -mcpu=cyclone -show-encoding < %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CHECK-CYCLONE
+
+msr CPM_IOACC_CTL_EL3, x0
+
+// CHECK-GENERIC: error: expected writable system register or pstate
+// CHECK-CYCLONE: msr CPM_IOACC_CTL_EL3, x0   // encoding: [0x00,0xf2,0x1f,0xd5]