[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