diff options
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 39 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/arm-tests.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-VQADD-arm.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/neon-tests.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/neon.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/neont2.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/thumb-printf.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/thumb-tests.txt | 9 | ||||
-rw-r--r-- | utils/TableGen/DisassemblerEmitter.cpp | 5 | ||||
-rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.cpp | 56 | ||||
-rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.h | 3 |
17 files changed, 99 insertions, 37 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 3b4e1c5..fa9eed4 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 66bec91..e94bc31 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 45f6aa8..5ad3280 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 4120779..12da869 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 2c2e5ac..a53f940 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 5651860..a12ca95 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 790f354..7c0efab 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 ce54ef3..2198efc 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 55a52cf..3f406d4 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 7fce4e2..1e03deb 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 8c43e5d..5d2df93 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 4eb62d6..577703c 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 6c2c500..8158a73 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 b93d3e1..f76ea12 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 614ec36..24db080 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 d1f2712..27a5587 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 535299c..7460f83 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; |