diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-02-07 22:09:15 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-02-07 22:09:15 +0000 |
commit | 706d946cfe44fa93f482c3a56ed42d52ca81b257 (patch) | |
tree | e5b1b1c229050b6025b1f101a130d3450b2e9cfc /lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | 480d1e3a67751c9c809e9ce047ad7e4b23bab9f1 (diff) |
Add support for parsing dmb/dsb instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125055 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3280e7792a..87f77f25ef 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -58,6 +58,7 @@ class ARMAsmParser : public TargetAsmParser { bool ParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*>&); bool ParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*>&); bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); + bool ParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &); bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); @@ -119,6 +120,7 @@ class ARMOperand : public MCParsedAsmOperand { CoprocNum, CoprocReg, Immediate, + MemBarrierOpt, Memory, Register, RegisterList, @@ -136,6 +138,10 @@ class ARMOperand : public MCParsedAsmOperand { } CC; struct { + ARM_MB::MemBOpt Val; + } MBOpt; + + struct { unsigned Val; } Cop; @@ -199,6 +205,9 @@ public: case Immediate: Imm = o.Imm; break; + case MemBarrierOpt: + MBOpt = o.MBOpt; + break; case Memory: Mem = o.Mem; break; @@ -241,6 +250,11 @@ public: return Imm.Val; } + ARM_MB::MemBOpt getMemBarrierOpt() const { + assert(Kind == MemBarrierOpt && "Invalid access!"); + return MBOpt.Val; + } + /// @name Memory Operand Accessors /// @{ @@ -285,6 +299,7 @@ public: bool isDPRRegList() const { return Kind == DPRRegisterList; } bool isSPRRegList() const { return Kind == SPRRegisterList; } bool isToken() const { return Kind == Token; } + bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } bool isMemory() const { return Kind == Memory; } bool isMemMode5() const { if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || @@ -373,6 +388,11 @@ public: addExpr(Inst, getImm()); } + void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); + } + void addMemMode5Operands(MCInst &Inst, unsigned N) const { assert(N == 2 && isMemMode5() && "Invalid number of operands!"); @@ -524,6 +544,14 @@ public: Op->EndLoc = E; return Op; } + + static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { + ARMOperand *Op = new ARMOperand(MemBarrierOpt); + Op->MBOpt.Val = Opt; + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } }; } // end anonymous namespace. @@ -545,6 +573,9 @@ void ARMOperand::dump(raw_ostream &OS) const { case Immediate: getImm()->print(OS); break; + case MemBarrierOpt: + OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; + break; case Memory: OS << "<memory " << "base:" << getMemBaseRegNum(); @@ -823,6 +854,33 @@ ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { return false; } +/// ParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. +bool ARMAsmParser:: +ParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + SMLoc S = Parser.getTok().getLoc(); + const AsmToken &Tok = Parser.getTok(); + assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + StringRef OptStr = Tok.getString(); + + unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) + .Case("sy", ARM_MB::SY) + .Case("st", ARM_MB::ST) + .Case("ish", ARM_MB::ISH) + .Case("ishst", ARM_MB::ISHST) + .Case("nsh", ARM_MB::NSH) + .Case("nshst", ARM_MB::NSHST) + .Case("osh", ARM_MB::OSH) + .Case("oshst", ARM_MB::OSHST) + .Default(~0U); + + if (Opt == ~0U) + return true; + + Parser.Lex(); // Eat identifier token. + Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); + return false; +} + /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. /// |