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 | |
parent | 480d1e3a67751c9c809e9ce047ad7e4b23bab9f1 (diff) | |
download | external_llvm-706d946cfe44fa93f482c3a56ed42d52ca81b257.zip external_llvm-706d946cfe44fa93f482c3a56ed42d52ca81b257.tar.gz external_llvm-706d946cfe44fa93f482c3a56ed42d52ca81b257.tar.bz2 |
Add support for parsing dmb/dsb instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125055 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 6 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 1 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 58 | ||||
-rw-r--r-- | test/MC/ARM/arm_instructions.s | 49 | ||||
-rw-r--r-- | test/MC/ARM/thumb2.s | 43 |
5 files changed, 148 insertions, 9 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index d215678..43e53ad 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -149,6 +149,12 @@ def CCOutOperand : AsmOperandClass { let SuperClasses = []; } +def MemBarrierOptOperand : AsmOperandClass { + let Name = "MemBarrierOpt"; + let SuperClasses = []; + let ParserMethod = "ParseMemBarrierOptOperand"; +} + // ARM Predicate operand. Default to 14 = always (AL). Second part is CC // register whose default is 0 (no register). def pred : PredicateOperand<OtherVT, (ops i32imm, CCR), diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 01ae5df..961649b 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -3191,6 +3191,7 @@ def MVNCCi : AI1<0b1111, (outs GPR:$Rd), def memb_opt : Operand<i32> { let PrintMethod = "printMemBOption"; + let ParserMatchClass = MemBarrierOptOperand; } // memory barriers protect the atomic sequences diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3280e77..87f77f2 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. /// diff --git a/test/MC/ARM/arm_instructions.s b/test/MC/ARM/arm_instructions.s index 4df8270..f5bf236 100644 --- a/test/MC/ARM/arm_instructions.s +++ b/test/MC/ARM/arm_instructions.s @@ -188,3 +188,52 @@ @ CHECK: nop @ encoding: [0x00,0xf0,0x20,0xe3] nop + +@ CHECK: dmb sy @ encoding: [0x5f,0xf0,0x7f,0xf5] + dmb sy + +@ CHECK: dmb st @ encoding: [0x5e,0xf0,0x7f,0xf5] + dmb st + +@ CHECK: dmb ish @ encoding: [0x5b,0xf0,0x7f,0xf5] + dmb ish + +@ CHECK: dmb ishst @ encoding: [0x5a,0xf0,0x7f,0xf5] + dmb ishst + +@ CHECK: dmb nsh @ encoding: [0x57,0xf0,0x7f,0xf5] + dmb nsh + +@ CHECK: dmb nshst @ encoding: [0x56,0xf0,0x7f,0xf5] + dmb nshst + +@ CHECK: dmb osh @ encoding: [0x53,0xf0,0x7f,0xf5] + dmb osh + +@ CHECK: dmb oshst @ encoding: [0x52,0xf0,0x7f,0xf5] + dmb oshst + +@ CHECK: dsb sy @ encoding: [0x4f,0xf0,0x7f,0xf5] + dsb sy + +@ CHECK: dsb st @ encoding: [0x4e,0xf0,0x7f,0xf5] + dsb st + +@ CHECK: dsb ish @ encoding: [0x4b,0xf0,0x7f,0xf5] + dsb ish + +@ CHECK: dsb ishst @ encoding: [0x4a,0xf0,0x7f,0xf5] + dsb ishst + +@ CHECK: dsb nsh @ encoding: [0x47,0xf0,0x7f,0xf5] + dsb nsh + +@ CHECK: dsb nshst @ encoding: [0x46,0xf0,0x7f,0xf5] + dsb nshst + +@ CHECK: dsb osh @ encoding: [0x43,0xf0,0x7f,0xf5] + dsb osh + +@ CHECK: dsb oshst @ encoding: [0x42,0xf0,0x7f,0xf5] + dsb oshst + diff --git a/test/MC/ARM/thumb2.s b/test/MC/ARM/thumb2.s index b815ad9..b8b068f 100644 --- a/test/MC/ARM/thumb2.s +++ b/test/MC/ARM/thumb2.s @@ -92,15 +92,6 @@ @ CHECK: pkhtb r0, r0, r1, asr #22 @ encoding: [0xa1,0x50,0xc0,0xea] pkhtb r0, r0, r1, asr #22 -@ CHECK: dmb st @ encoding: [0x5e,0x8f,0xbf,0xf3] - dmb st -@ CHECK: dmb sy @ encoding: [0x5f,0x8f,0xbf,0xf3] - dmb sy -@ CHECK: dmb ishst @ encoding: [0x5a,0x8f,0xbf,0xf3] - dmb ishst -@ CHECK: dmb ish @ encoding: [0x5b,0x8f,0xbf,0xf3] - dmb ish - @ CHECK: str.w r0, [r1, #4092] @ encoding: [0xfc,0x0f,0xc1,0xf8] str.w r0, [r1, #4092] @ CHECK: str r0, [r1, #-128] @ encoding: [0x80,0x0c,0x41,0xf8] @@ -227,3 +218,37 @@ @ CHECK: wfi.w @ encoding: [0xaf,0xf3,0x03,0x80] wfi.w +@ CHECK: dmb sy @ encoding: [0xbf,0xf3,0x5f,0x8f] + dmb sy +@ CHECK: dmb st @ encoding: [0xbf,0xf3,0x5e,0x8f] + dmb st +@ CHECK: dmb ish @ encoding: [0xbf,0xf3,0x5b,0x8f] + dmb ish +@ CHECK: dmb ishst @ encoding: [0xbf,0xf3,0x5a,0x8f] + dmb ishst +@ CHECK: dmb nsh @ encoding: [0xbf,0xf3,0x57,0x8f] + dmb nsh +@ CHECK: dmb nshst @ encoding: [0xbf,0xf3,0x56,0x8f] + dmb nshst +@ CHECK: dmb osh @ encoding: [0xbf,0xf3,0x53,0x8f] + dmb osh +@ CHECK: dmb oshst @ encoding: [0xbf,0xf3,0x52,0x8f] + dmb oshst + +@ CHECK: dsb sy @ encoding: [0xbf,0xf3,0x4f,0x8f] + dsb sy +@ CHECK: dsb st @ encoding: [0xbf,0xf3,0x4e,0x8f] + dsb st +@ CHECK: dsb ish @ encoding: [0xbf,0xf3,0x4b,0x8f] + dsb ish +@ CHECK: dsb ishst @ encoding: [0xbf,0xf3,0x4a,0x8f] + dsb ishst +@ CHECK: dsb nsh @ encoding: [0xbf,0xf3,0x47,0x8f] + dsb nsh +@ CHECK: dsb nshst @ encoding: [0xbf,0xf3,0x46,0x8f] + dsb nshst +@ CHECK: dsb osh @ encoding: [0xbf,0xf3,0x43,0x8f] + dsb osh +@ CHECK: dsb oshst @ encoding: [0xbf,0xf3,0x42,0x8f] + dsb oshst + |