Second of a three-patch series aiming to fix MSR/MRS on Cortex-M. This adds predicate...
authorJames Molloy <james.molloy@arm.com>
Wed, 7 Sep 2011 19:42:28 +0000 (19:42 +0000)
committerJames Molloy <james.molloy@arm.com>
Wed, 7 Sep 2011 19:42:28 +0000 (19:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139250 91177308-0d34-0410-b5e6-96231b3b80d8

17 files changed:
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
test/MC/Disassembler/ARM/arm-tests.txt
test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
test/MC/Disassembler/ARM/neon-tests.txt
test/MC/Disassembler/ARM/neon.txt
test/MC/Disassembler/ARM/neont2.txt
test/MC/Disassembler/ARM/thumb-printf.txt
test/MC/Disassembler/ARM/thumb-tests.txt
utils/TableGen/DisassemblerEmitter.cpp
utils/TableGen/FixedLenDecoderEmitter.cpp
utils/TableGen/FixedLenDecoderEmitter.h

index 3b4e1c5aea77c127e875ffe54e12c73a2a2245e8..fa9eed4b47b93fc43cacb6096196bb2ea31a04d5 100644 (file)
@@ -97,6 +97,7 @@ static bool Check(DecodeStatus &Out, DecodeStatus In) {
   return false;
 }
 
+
 // Forward declare these because the autogenerated code will reference them.
 // Definitions are further down.
 static DecodeStatus DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
@@ -319,6 +320,9 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                                              raw_ostream &os) const {
   uint8_t bytes[4];
 
+  assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
+         "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");
+
   // We want to read exactly 4 bytes of data.
   if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
     Size = 0;
@@ -332,7 +336,7 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                   (bytes[0] <<  0);
 
   // Calling the auto-generated decoder function.
-  DecodeStatus result = decodeARMInstruction32(MI, insn, Address, this);
+  DecodeStatus result = decodeARMInstruction32(MI, insn, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     return result;
@@ -342,7 +346,7 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   // FIXME: This shouldn't really exist.  It's an artifact of the
   // fact that we fail to encode a few instructions properly for Thumb.
   MI.clear();
-  result = decodeCommonInstruction32(MI, insn, Address, this);
+  result = decodeCommonInstruction32(MI, insn, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     return result;
@@ -351,14 +355,14 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   // VFP and NEON instructions, similarly, are shared between ARM
   // and Thumb modes.
   MI.clear();
-  result = decodeVFPInstruction32(MI, insn, Address, this);
+  result = decodeVFPInstruction32(MI, insn, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     return result;
   }
 
   MI.clear();
-  result = decodeNEONDataInstruction32(MI, insn, Address, this);
+  result = decodeNEONDataInstruction32(MI, insn, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     // Add a fake predicate operand, because we share these instruction
@@ -369,7 +373,7 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this);
+  result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     // Add a fake predicate operand, because we share these instruction
@@ -380,7 +384,7 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeNEONDupInstruction32(MI, insn, Address, this);
+  result = decodeNEONDupInstruction32(MI, insn, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     // Add a fake predicate operand, because we share these instruction
@@ -505,6 +509,9 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                                                raw_ostream &os) const {
   uint8_t bytes[4];
 
+  assert((STI.getFeatureBits() & ARM::ModeThumb) &&
+         "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
+
   // We want to read exactly 2 bytes of data.
   if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) {
     Size = 0;
@@ -512,7 +519,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   uint16_t insn16 = (bytes[1] << 8) | bytes[0];
-  DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this);
+  DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 2;
     AddThumbPredicate(MI);
@@ -520,7 +527,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeThumbSBitInstruction16(MI, insn16, Address, this);
+  result = decodeThumbSBitInstruction16(MI, insn16, Address, this, STI);
   if (result) {
     Size = 2;
     bool InITBlock = !ITBlock.empty();
@@ -530,7 +537,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeThumb2Instruction16(MI, insn16, Address, this);
+  result = decodeThumb2Instruction16(MI, insn16, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 2;
     AddThumbPredicate(MI);
@@ -570,7 +577,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                     (bytes[1] << 24) |
                     (bytes[0] << 16);
   MI.clear();
-  result = decodeThumbInstruction32(MI, insn32, Address, this);
+  result = decodeThumbInstruction32(MI, insn32, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     bool InITBlock = ITBlock.size();
@@ -580,7 +587,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeThumb2Instruction32(MI, insn32, Address, this);
+  result = decodeThumb2Instruction32(MI, insn32, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     AddThumbPredicate(MI);
@@ -588,7 +595,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeCommonInstruction32(MI, insn32, Address, this);
+  result = decodeCommonInstruction32(MI, insn32, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     AddThumbPredicate(MI);
@@ -596,7 +603,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeVFPInstruction32(MI, insn32, Address, this);
+  result = decodeVFPInstruction32(MI, insn32, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     UpdateThumbVFPPredicate(MI);
@@ -604,7 +611,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
   }
 
   MI.clear();
-  result = decodeNEONDupInstruction32(MI, insn32, Address, this);
+  result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI);
   if (result != MCDisassembler::Fail) {
     Size = 4;
     AddThumbPredicate(MI);
@@ -616,7 +623,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
     uint32_t NEONLdStInsn = insn32;
     NEONLdStInsn &= 0xF0FFFFFF;
     NEONLdStInsn |= 0x04000000;
-    result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this);
+    result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI);
     if (result != MCDisassembler::Fail) {
       Size = 4;
       AddThumbPredicate(MI);
@@ -630,7 +637,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
     NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
     NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
     NEONDataInsn |= 0x12000000; // Set bits 28 and 25
-    result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this);
+    result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI);
     if (result != MCDisassembler::Fail) {
       Size = 4;
       AddThumbPredicate(MI);
index 66bec91c31fec2c858359c05a88752a387e9f41b..e94bc317bc870eb83e87720a6c9f75fa4a82fb35 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 -mattr +mp | FileCheck %s
 
 # CHECK:       addpl   r4, pc, #318767104
 0x4c 0x45 0x8f 0x52
index 45f6aa81f58f9ff37896613ad218a734c794b512..5ad32808e0165358c11cd5d5336789dc55c0b54a 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=1930 Name=t2LDRD_PRE Format=ARM_FORMAT_THUMBFRM(25)
index 4120779b995fe70126dfec997f4414c22faafb87..12da8690f160a41e12b87a4f4846dabc49b42734 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=737 Name=VLD1DUPq8_UPD Format=ARM_FORMAT_NLdSt(30)
index 2c2e5ac1fe5e0fe7de6ed7c2c51dc3313c14270c..a53f9405025f7e0283b1526b7b667dd3f87198c3 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=1225 Name=VQADDsv16i8 Format=ARM_FORMAT_N3Reg(37)
index 56518608456fd7a3efde27d481f2cbd882c2ff9c..a12ca9548a52120358c6f93817c6af6436ec30fa 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=1641 Name=VST2b32_UPD Format=ARM_FORMAT_NLdSt(30)
index 790f354c17876049bfd7558855b73929417a355e..7c0efab3834d45223f4301ffaa5eca873051c6d1 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=1934 Name=t2LDREXD Format=ARM_FORMAT_THUMBFRM(25)
index ce54ef3c281250e548a317ca462b049c7804b3c4..2198efc2d2577004e4d9dfee855475195be56244 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=2124 Name=t2STRD_PRE Format=ARM_FORMAT_THUMBFRM(25)
index 55a52cfef93e7097fdacf1d47ce96c524850ff25..3f406d49487bd0f63cf7f1537d48c251fe9ce6d5 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding}
 # XFAIL: *
 
 # Opcode=2127 Name=t2STREXB Format=ARM_FORMAT_THUMBFRM(25)
index 7fce4e236281293f59d6aa5fae21894b1bb5ca65..1e03debefab6bd782cd9204eddf2611458d5c199 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 | FileCheck %s
 
 # CHECK:       vbif    q15, q7, q0
 0x50 0xe1 0x7e 0xf3
index 8c43e5d71fd4425e38b5ab6c737fcbc5a690626a..5d2df93ed780aef26e1b300f42f16a908996900a 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple armv7-unknown-unknown -disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple armv7-unknown-unknown -disassemble -mattr +fp16 < %s | FileCheck %s
 
 0x20 0x03 0xf1 0xf3
 # CHECK: vabs.s8       d16, d16
index 4eb62d69c6072974de72b643479c85ebb80a609a..577703c804b70965f297a7b8f8bf3e473a606c01 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple thumbv7-unknown-unknown -disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple thumbv7-unknown-unknown -disassemble -mattr +fp16 < %s | FileCheck %s
 
 0xf1 0xff 0x20 0x03
 # CHECK: vabs.s8       d16, d16
index 6c2c500630d5991e3429d0bdb678ccbe94d22495..8158a73edcb5f98ea9764fa628b81fe6a83a5186 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 | FileCheck %s
 
 # CHECK:       push    {r0, r1, r2, r3}
 # CHECK-NEXT:  push    {r4, r5, r7, lr}
index b93d3e1427b9854fc4c1472695dcd5e0b8c65224..f76ea12bebb07533b09f984360d72b0a004aa0e9 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mattr +t2xtpk,+mp | FileCheck %s
 
 # CHECK:       add     r5, sp, #68
 0x11 0xad
 # CHECK:       pld     [r5, #30]
 0x95 0xf8 0x1e 0xf0
 
-# CHECK:       stc2    p12, cr15, [r9], {137}
-0x89 0xfc 0x89 0xfc
+# Test disabled as it was originally checking for
+# the ARM encoding of stc2, and thumb2 stc2 is
+# not implemented yet.
+# CHECK-:      stc2    p12, cr15, [r9], {137}
+#0x89 0xfc 0x89 0xfc
 
 # CHECK:       vmov    r1, r0, d11
 0x50 0xec 0x1b 0x1b
index 614ec3630fe880a8d0c3d1cae2e55f440ed946c9..24db080b2635ae2175d07d93b92c06a895ceed3d 100644 (file)
@@ -132,11 +132,12 @@ void DisassemblerEmitter::run(raw_ostream &OS) {
   if (Target.getName() == "ARM" ||
       Target.getName() == "Thumb") {
     FixedLenDecoderEmitter(Records,
+                           "ARM",
                            "if (!Check(S, ", ")) return MCDisassembler::Fail;",
                            "S", "MCDisassembler::Fail",
-                           "MCDisassembler::DecodeStatus S = MCDisassembler::Success;\n(void)S;").run(OS);
+                           "  MCDisassembler::DecodeStatus S = MCDisassembler::Success;\n(void)S;").run(OS);
     return;
   }
 
-  FixedLenDecoderEmitter(Records).run(OS);
+  FixedLenDecoderEmitter(Records, Target.getName()).run(OS);
 }
index d1f271208e53796b427426236d73c9718efc31bc..27a5587031c89c6c861d14b7f3eebfb532e49455 100644 (file)
@@ -330,6 +330,10 @@ protected:
       std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals,
       insn_t &Insn);
 
+  // Emits code to check the Predicates member of an instruction are true.
+  // Returns true if predicate matches were emitted, false otherwise.
+  bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,unsigned Opc);
+
   // Emits code to decode the singleton.  Return true if we have matched all the
   // well-known bits.
   bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc);
@@ -571,8 +575,9 @@ void FilterChooser::emitTop(raw_ostream &o, unsigned Indentation,
   o.indent(Indentation) <<
     "static MCDisassembler::DecodeStatus decode" << Namespace << "Instruction" << BitWidth
     << "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, "
-    << "const void *Decoder) {\n";
+    << "const void *Decoder, const MCSubtargetInfo &STI) {\n";
   o.indent(Indentation) << "  unsigned tmp = 0;\n  (void)tmp;\n" << Emitter->Locals << "\n";
+  o.indent(Indentation) << "  unsigned Bits = STI.getFeatureBits();\n";
 
   ++Indentation; ++Indentation;
   // Emits code to decode the instructions.
@@ -757,6 +762,43 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
 
 }
 
+static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
+                                     std::string PredicateNamespace) {
+  const char *X = str.str().c_str();
+  if (X[0] == '!')
+    o << "!(Bits & " << PredicateNamespace << "::" << &X[1] << ")";
+  else
+    o << "(Bits & " << PredicateNamespace << "::" << X << ")";
+}
+
+bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
+                                           unsigned Opc) {
+  ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates");
+  for (unsigned i = 0; i < Predicates->getSize(); ++i) {
+    Record *Pred = Predicates->getElementAsRecord(i);
+    if (!Pred->getValue("AssemblerMatcherPredicate"))
+      continue;
+
+    std::string P = Pred->getValueAsString("AssemblerCondString");
+
+    if (!P.length())
+      continue;
+
+    if (i != 0)
+      o << " && ";
+
+    StringRef SR(P);
+    std::pair<StringRef, StringRef> pairs = SR.split(',');
+    while (pairs.second.size()) {
+      emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
+      o << " && ";
+      pairs = pairs.second.split(',');
+    }
+    emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
+  }
+  return Predicates->getSize() > 0;
+}  
+
 // Emits code to decode the singleton.  Return true if we have matched all the
 // well-known bits.
 bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
@@ -775,7 +817,9 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
 
   // If we have matched all the well-known bits, just issue a return.
   if (Size == 0) {
-    o.indent(Indentation) << "{\n";
+    o.indent(Indentation) << "if (";
+    emitPredicateMatch(o, Indentation, Opc);
+    o << ") {\n";
     o.indent(Indentation) << "  MI.setOpcode(" << Opc << ");\n";
     std::vector<OperandInfo>& InsnOperands = Operands[Opc];
     for (std::vector<OperandInfo>::iterator
@@ -792,7 +836,7 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
 
     o.indent(Indentation) << "  return " << Emitter->ReturnOK << "; // " << nameWithID(Opc)
                           << '\n';
-    o.indent(Indentation) << "}\n";
+    o.indent(Indentation) << "}\n"; // Closing predicate block.
     return true;
   }
 
@@ -804,12 +848,16 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
   for (I = Size; I != 0; --I) {
     o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} ";
     if (I > 1)
-      o << "&& ";
+      o << " && ";
     else
       o << "for singleton decoding...\n";
   }
 
   o.indent(Indentation) << "if (";
+  if (emitPredicateMatch(o, Indentation, Opc) > 0) {
+    o << " &&\n";
+    o.indent(Indentation+4);
+  }
 
   for (I = Size; I != 0; --I) {
     NumBits = EndBits[I-1] - StartBits[I-1] + 1;
index 535299c32de0b4626c0472a800bf4fa5dda3a315..7460f83c69b48d6a87c4f2120c8224afa2abbdc4 100644 (file)
@@ -50,6 +50,7 @@ struct OperandInfo {
 class FixedLenDecoderEmitter : public TableGenBackend {
 public:
   FixedLenDecoderEmitter(RecordKeeper &R,
+                         std::string PredicateNamespace,
                          std::string GPrefix  = "if (",
                          std::string GPostfix = " == MCDisassembler::Fail) return MCDisassembler::Fail;",
                          std::string ROK      = "MCDisassembler::Success",
@@ -57,6 +58,7 @@ public:
                          std::string L        = "") :
     Records(R), Target(R),
     NumberedInstructions(Target.getInstructionsByEnumValue()),
+    PredicateNamespace(PredicateNamespace),
     GuardPrefix(GPrefix), GuardPostfix(GPostfix),
     ReturnOK(ROK), ReturnFail(RFail), Locals(L) {}
 
@@ -70,6 +72,7 @@ private:
   std::vector<unsigned> Opcodes;
   std::map<unsigned, std::vector<OperandInfo> > Operands;
 public:
+  std::string PredicateNamespace;
   std::string GuardPrefix, GuardPostfix;
   std::string ReturnOK, ReturnFail;
   std::string Locals;