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),
def memb_opt : Operand<i32> {
let PrintMethod = "printMemBOption";
+ let ParserMatchClass = MemBarrierOptOperand;
}
// memory barriers protect the atomic sequences
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);
CoprocNum,
CoprocReg,
Immediate,
+ MemBarrierOpt,
Memory,
Register,
RegisterList,
ARMCC::CondCodes Val;
} CC;
+ struct {
+ ARM_MB::MemBOpt Val;
+ } MBOpt;
+
struct {
unsigned Val;
} Cop;
case Immediate:
Imm = o.Imm;
break;
+ case MemBarrierOpt:
+ MBOpt = o.MBOpt;
+ break;
case Memory:
Mem = o.Mem;
break;
return Imm.Val;
}
+ ARM_MB::MemBOpt getMemBarrierOpt() const {
+ assert(Kind == MemBarrierOpt && "Invalid access!");
+ return MBOpt.Val;
+ }
+
/// @name Memory Operand Accessors
/// @{
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() ||
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!");
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.
case Immediate:
getImm()->print(OS);
break;
+ case MemBarrierOpt:
+ OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
+ break;
case Memory:
OS << "<memory "
<< "base:" << getMemBaseRegNum();
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.
///
@ 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
+
@ 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]
@ 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
+