Add support for parsing dmb/dsb instructions
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 7 Feb 2011 22:09:15 +0000 (22:09 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 7 Feb 2011 22:09:15 +0000 (22:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125055 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/arm_instructions.s
test/MC/ARM/thumb2.s

index d215678789582169e6374ca30a6e351a1f50bf34..43e53ad8d485376cd806c09f34767c435c45b7fd 100644 (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),
index 01ae5dfaf2ee2c460803b56bfe9f427010f71f05..961649b67497d88e4eab61cacd96ffc554de5db7 100644 (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
index 3280e7792af47eb61fc23c53c3d705927565fff0..87f77f25ef12eea315733da5219f448bd5ec737e 100644 (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.
 ///
index 4df8270b7d7406aeb453065cfde73b3f37dca2ef..f5bf236ab2ddf55fc81be5f7d937fb490a707f10 100644 (file)
 
 @ 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
+
index b815ad981e5593e0134037a17843b3c34330ac10..b8b068fd901c25cf7891c294d2d17faaa232722c 100644 (file)
 @ 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
+