summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp39
-rw-r--r--test/MC/Disassembler/ARM/arm-tests.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-VQADD-arm.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt2
-rw-r--r--test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt2
-rw-r--r--test/MC/Disassembler/ARM/neon-tests.txt2
-rw-r--r--test/MC/Disassembler/ARM/neon.txt2
-rw-r--r--test/MC/Disassembler/ARM/neont2.txt2
-rw-r--r--test/MC/Disassembler/ARM/thumb-printf.txt2
-rw-r--r--test/MC/Disassembler/ARM/thumb-tests.txt9
-rw-r--r--utils/TableGen/DisassemblerEmitter.cpp5
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp56
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.h3
17 files changed, 99 insertions, 37 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 3b4e1c5aea..fa9eed4b47 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -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);
diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt
index 66bec91c31..e94bc317bc 100644
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -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
diff --git a/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt b/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
index 45f6aa81f5..5ad32808e0 100644
--- a/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
+++ b/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt b/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
index 4120779b99..12da8690f1 100644
--- a/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
+++ b/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt b/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
index 2c2e5ac1fe..a53f940502 100644
--- a/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
+++ b/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt b/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
index 5651860845..a12ca9548a 100644
--- a/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
+++ b/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
index 790f354c17..7c0efab383 100644
--- a/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
+++ b/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
index ce54ef3c28..2198efc2d2 100644
--- a/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
+++ b/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
index 55a52cfef9..3f406d4948 100644
--- a/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
+++ b/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
@@ -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)
diff --git a/test/MC/Disassembler/ARM/neon-tests.txt b/test/MC/Disassembler/ARM/neon-tests.txt
index 7fce4e2362..1e03debefa 100644
--- a/test/MC/Disassembler/ARM/neon-tests.txt
+++ b/test/MC/Disassembler/ARM/neon-tests.txt
@@ -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
diff --git a/test/MC/Disassembler/ARM/neon.txt b/test/MC/Disassembler/ARM/neon.txt
index 8c43e5d71f..5d2df93ed7 100644
--- a/test/MC/Disassembler/ARM/neon.txt
+++ b/test/MC/Disassembler/ARM/neon.txt
@@ -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
diff --git a/test/MC/Disassembler/ARM/neont2.txt b/test/MC/Disassembler/ARM/neont2.txt
index 4eb62d69c6..577703c804 100644
--- a/test/MC/Disassembler/ARM/neont2.txt
+++ b/test/MC/Disassembler/ARM/neont2.txt
@@ -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
diff --git a/test/MC/Disassembler/ARM/thumb-printf.txt b/test/MC/Disassembler/ARM/thumb-printf.txt
index 6c2c500630..8158a73edc 100644
--- a/test/MC/Disassembler/ARM/thumb-printf.txt
+++ b/test/MC/Disassembler/ARM/thumb-printf.txt
@@ -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}
diff --git a/test/MC/Disassembler/ARM/thumb-tests.txt b/test/MC/Disassembler/ARM/thumb-tests.txt
index b93d3e1427..f76ea12beb 100644
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -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
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
index 614ec3630f..24db080b26 100644
--- a/utils/TableGen/DisassemblerEmitter.cpp
+++ b/utils/TableGen/DisassemblerEmitter.cpp
@@ -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);
}
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index d1f271208e..27a5587031 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -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;
diff --git a/utils/TableGen/FixedLenDecoderEmitter.h b/utils/TableGen/FixedLenDecoderEmitter.h
index 535299c32d..7460f83c69 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.h
+++ b/utils/TableGen/FixedLenDecoderEmitter.h
@@ -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;