aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2011-02-07 22:09:15 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2011-02-07 22:09:15 +0000
commit706d946cfe44fa93f482c3a56ed42d52ca81b257 (patch)
treee5b1b1c229050b6025b1f101a130d3450b2e9cfc
parent480d1e3a67751c9c809e9ce047ad7e4b23bab9f1 (diff)
downloadexternal_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.td6
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td1
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp58
-rw-r--r--test/MC/ARM/arm_instructions.s49
-rw-r--r--test/MC/ARM/thumb2.s43
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
+