Add support for parsing dmb/dsb instructions

llvm-svn: 125055
This commit is contained in:
Bruno Cardoso Lopes 2011-02-07 22:09:15 +00:00
parent 639dd997eb
commit 36dd43fda6
5 changed files with 148 additions and 9 deletions

View File

@ -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),

View File

@ -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

View File

@ -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,
@ -135,6 +137,10 @@ class ARMOperand : public MCParsedAsmOperand {
ARMCC::CondCodes Val;
} 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.
///

View File

@ -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

View File

@ -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