[llvm-commits] [llvm] r139250 - in /llvm/trunk: lib/Target/ARM/Disassembler/ test/MC/Disassembler/ARM/ utils/TableGen/

James Molloy james.molloy at arm.com
Wed Sep 7 12:42:28 PDT 2011


Author: jamesm
Date: Wed Sep  7 14:42:28 2011
New Revision: 139250

URL: http://llvm.org/viewvc/llvm-project?rev=139250&view=rev
Log:
Second of a three-patch series aiming to fix MSR/MRS on Cortex-M. This adds predicate checking to the Disassembler.

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

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Wed Sep  7 14:42:28 2011
@@ -97,6 +97,7 @@
   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 @@
                                              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 @@
                   (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 @@
   // 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 @@
   // 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 @@
   }
 
   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 @@
   }
 
   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 @@
                                                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 @@
   }
 
   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 @@
   }
 
   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 @@
   }
 
   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 @@
                     (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 @@
   }
 
   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 @@
   }
 
   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 @@
   }
 
   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 @@
   }
 
   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 @@
     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 @@
     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);

Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Wed Sep  7 14:42:28 2011
@@ -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

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt Wed Sep  7 14:42:28 2011
@@ -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)

Modified: llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt Wed Sep  7 14:42:28 2011
@@ -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

Modified: llvm/trunk/test/MC/Disassembler/ARM/neon.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/neon.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/neon.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/neon.txt Wed Sep  7 14:42:28 2011
@@ -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

Modified: llvm/trunk/test/MC/Disassembler/ARM/neont2.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/neont2.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/neont2.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/neont2.txt Wed Sep  7 14:42:28 2011
@@ -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

Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt Wed Sep  7 14:42:28 2011
@@ -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}

Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Wed Sep  7 14:42:28 2011
@@ -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
@@ -218,8 +218,11 @@
 # 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

Modified: llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp Wed Sep  7 14:42:28 2011
@@ -132,11 +132,12 @@
   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);
 }

Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Wed Sep  7 14:42:28 2011
@@ -330,6 +330,10 @@
       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 @@
   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 @@
 
 }
 
+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 @@
 
   // 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 @@
 
     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 @@
   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;

Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h?rev=139250&r1=139249&r2=139250&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h Wed Sep  7 14:42:28 2011
@@ -50,6 +50,7 @@
 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 @@
                          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 @@
   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;





More information about the llvm-commits mailing list