diff options
-rw-r--r-- | include/llvm/MC/MCDisassembler.h | 35 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 1231 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.h | 20 | ||||
-rw-r--r-- | lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp | 50 | ||||
-rw-r--r-- | lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h | 2 | ||||
-rw-r--r-- | lib/Target/X86/Disassembler/X86Disassembler.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/Disassembler/X86Disassembler.h | 10 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt | 2 | ||||
-rw-r--r-- | tools/llvm-mc/Disassembler.cpp | 21 | ||||
-rw-r--r-- | utils/TableGen/DisassemblerEmitter.cpp | 10 | ||||
-rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.cpp | 38 | ||||
-rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.h | 16 |
12 files changed, 793 insertions, 657 deletions
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index ce8759a882..adcb88254e 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -25,6 +25,34 @@ struct EDInstInfo; /// and provides an array of assembly instructions. class MCDisassembler { public: + /// Ternary decode status. Most backends will just use Fail and + /// Success, however some have a concept of an instruction with + /// understandable semantics but which is architecturally + /// incorrect. An example of this is ARM UNPREDICTABLE instructions + /// which are disassemblable but cause undefined behaviour. + /// + /// Because it makes sense to disassemble these instructions, there + /// is a "soft fail" failure mode that indicates the MCInst& is + /// valid but architecturally incorrect. + /// + /// The enum numbers are deliberately chosen such that reduction + /// from Success->SoftFail ->Fail can be done with a simple + /// bitwise-AND: + /// + /// LEFT & TOP = | Success Unpredictable Fail + /// --------------+----------------------------------- + /// Success | Success Unpredictable Fail + /// Unpredictable | Unpredictable Unpredictable Fail + /// Fail | Fail Fail Fail + /// + /// An easy way of encoding this is as 0b11, 0b01, 0b00 for + /// Success, SoftFail, Fail respectively. + enum DecodeStatus { + Fail = 0, + SoftFail = 1, + Success = 3 + }; + /// Constructor - Performs initial setup for the disassembler. MCDisassembler() : GetOpInfo(0), DisInfo(0), Ctx(0) {} @@ -41,8 +69,11 @@ public: /// @param address - The address, in the memory space of region, of the first /// byte of the instruction. /// @param vStream - The stream to print warnings and diagnostic messages on. - /// @return - True if the instruction is valid; false otherwise. - virtual bool getInstruction(MCInst& instr, + /// @return - MCDisassembler::Success if the instruction is valid, + /// MCDisassembler::SoftFail if the instruction was + /// disassemblable but invalid, + /// MCDisassembler::Fail if the instruction was invalid. + virtual DecodeStatus getInstruction(MCInst& instr, uint64_t& size, const MemoryObject ®ion, uint64_t address, diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cb7a45a257..98cdc64746 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -24,188 +24,201 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +// Pull DecodeStatus and its enum values into the global namespace. +typedef llvm::MCDisassembler::DecodeStatus DecodeStatus; +#define Success llvm::MCDisassembler::Success +#define Unpredictable llvm::MCDisassembler::SoftFail +#define Fail llvm::MCDisassembler::Fail + +// Helper macro to perform setwise reduction of the current running status +// and another status, and return if the new status is Fail. +#define CHECK(S,X) do { \ + S = (DecodeStatus) ((int)S & (X)); \ + if (S == Fail) return Fail; \ + } while(0) + // Forward declare these because the autogenerated code will reference them. // Definitions are further down. -static bool DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodeGPRnopcRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeGPRnopcRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); -static bool DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeDPRRegListOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeDPRRegListOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeBitfieldMaskOperand(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeBitfieldMaskOperand(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeAddrMode2IdxInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeAddrMode2IdxInstruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeSORegMemOperand(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeSORegMemOperand(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeAddrMode3Instruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeAddrMode3Instruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeMemMultipleWritebackInstruction(llvm::MCInst & Inst, +static DecodeStatus DecodeMemMultipleWritebackInstruction(llvm::MCInst & Inst, unsigned Insn, uint64_t Adddress, const void *Decoder); -static bool DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVCVTImmOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVCVTImmOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVLD1DupInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVLD1DupInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVLD3DupInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVLD3DupInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVLD4DupInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVLD4DupInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeNEONModImmInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeNEONModImmInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeVSHLMaxInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVSHLMaxInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeShiftRight8Imm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeShiftRight8Imm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeShiftRight16Imm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeShiftRight16Imm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeShiftRight32Imm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeShiftRight32Imm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeShiftRight64Imm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeShiftRight64Imm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeTBLInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeTBLInstruction(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVFPfpImm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeVFPfpImm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodePostIdxReg(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodePostIdxReg(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeCoprocessor(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeCoprocessor(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeMSRMask(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeMSRMask(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVLD1LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVLD1LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVLD2LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVLD2LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVLD3LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVLD3LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVLD4LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVLD4LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVST1LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVST1LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVST2LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVST2LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVST3LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVST3LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeVST4LN(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeVST4LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn, +static DecodeStatus DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn, uint64_t Address, const void *Decoder); -static bool DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddrModeRR(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbAddrModeRR(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddrModeIS(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbAddrModeIS(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddrModePC(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbAddrModePC(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddrModeSP(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbAddrModeSP(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2AddrModeSOReg(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2AddrModeSOReg(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2LoadShift(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2LoadShift(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2Imm8S4(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2Imm8S4(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2AddrModeImm8s4(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2AddrModeImm8s4(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2Imm8(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2Imm8(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2AddrModeImm8(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2AddrModeImm8(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddSPImm(llvm::MCInst &Inst, uint16_t Val, +static DecodeStatus DecodeThumbAddSPImm(llvm::MCInst &Inst, uint16_t Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbAddSPReg(llvm::MCInst &Inst, uint16_t Insn, +static DecodeStatus DecodeThumbAddSPReg(llvm::MCInst &Inst, uint16_t Insn, uint64_t Address, const void *Decoder); -static bool DecodeThumbCPS(llvm::MCInst &Inst, uint16_t Insn, +static DecodeStatus DecodeThumbCPS(llvm::MCInst &Inst, uint16_t Insn, uint64_t Address, const void *Decoder); -static bool DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static bool DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbSRImm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbSRImm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static bool DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); #include "ARMGenDisassemblerTables.inc" @@ -230,15 +243,14 @@ EDInstInfo *ThumbDisassembler::getEDInfo() const { return instInfoARM; } - -bool ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, - const MemoryObject &Region, - uint64_t Address,raw_ostream &os) const { +DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, + const MemoryObject &Region, + uint64_t Address,raw_ostream &os) const { uint8_t bytes[4]; // We want to read exactly 4 bytes of data. if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) - return false; + return Fail; // Encoded as a small-endian 32-bit word in the stream. uint32_t insn = (bytes[3] << 24) | @@ -247,10 +259,10 @@ bool ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, (bytes[0] << 0); // Calling the auto-generated decoder function. - bool result = decodeARMInstruction32(MI, insn, Address, this); - if (result) { + DecodeStatus result = decodeARMInstruction32(MI, insn, Address, this); + if (result != Fail) { Size = 4; - return true; + return result; } // Instructions that are shared between ARM and Thumb modes. @@ -258,53 +270,53 @@ bool ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, // fact that we fail to encode a few instructions properly for Thumb. MI.clear(); result = decodeCommonInstruction32(MI, insn, Address, this); - if (result) { + if (result != Fail) { Size = 4; - return true; + return result; } // VFP and NEON instructions, similarly, are shared between ARM // and Thumb modes. MI.clear(); result = decodeVFPInstruction32(MI, insn, Address, this); - if (result) { + if (result != Fail) { Size = 4; - return true; + return result; } MI.clear(); result = decodeNEONDataInstruction32(MI, insn, Address, this); - if (result) { + if (result != Fail) { Size = 4; // Add a fake predicate operand, because we share these instruction // definitions with Thumb2 where these instructions are predicable. - if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false; - return true; + if (!DecodePredicateOperand(MI, 0xE, Address, this)) return Fail; + return result; } MI.clear(); result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this); - if (result) { + if (result != Fail) { Size = 4; // Add a fake predicate operand, because we share these instruction // definitions with Thumb2 where these instructions are predicable. - if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false; - return true; + if (!DecodePredicateOperand(MI, 0xE, Address, this)) return Fail; + return result; } MI.clear(); result = decodeNEONDupInstruction32(MI, insn, Address, this); - if (result) { + if (result != Fail) { Size = 4; // Add a fake predicate operand, because we share these instruction // definitions with Thumb2 where these instructions are predicable. - if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false; - return true; + if (!DecodePredicateOperand(MI, 0xE, Address, this)) return Fail; + return result; } MI.clear(); - return false; + return Fail; } namespace llvm { @@ -403,22 +415,21 @@ void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const { } } - -bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, - const MemoryObject &Region, - uint64_t Address,raw_ostream &os) const { +DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, + const MemoryObject &Region, + uint64_t Address,raw_ostream &os) const { uint8_t bytes[4]; // We want to read exactly 2 bytes of data. if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) - return false; + return Fail; uint16_t insn16 = (bytes[1] << 8) | bytes[0]; - bool result = decodeThumbInstruction16(MI, insn16, Address, this); - if (result) { + DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this); + if (result != Fail) { Size = 2; AddThumbPredicate(MI); - return true; + return result; } MI.clear(); @@ -428,12 +439,12 @@ bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, bool InITBlock = !ITBlock.empty(); AddThumbPredicate(MI); AddThumb1SBit(MI, InITBlock); - return true; + return result; } MI.clear(); result = decodeThumb2Instruction16(MI, insn16, Address, this); - if (result) { + if (result != Fail) { Size = 2; AddThumbPredicate(MI); @@ -456,12 +467,12 @@ bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, ITBlock.push_back(firstcond); } - return true; + return result; } // We want to read exactly 4 bytes of data. if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) - return false; + return Fail; uint32_t insn32 = (bytes[3] << 8) | (bytes[2] << 0) | @@ -469,44 +480,44 @@ bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, (bytes[0] << 16); MI.clear(); result = decodeThumbInstruction32(MI, insn32, Address, this); - if (result) { + if (result != Fail) { Size = 4; bool InITBlock = ITBlock.size(); AddThumbPredicate(MI); AddThumb1SBit(MI, InITBlock); - return true; + return result; } MI.clear(); result = decodeThumb2Instruction32(MI, insn32, Address, this); - if (result) { + if (result != Fail) { Size = 4; AddThumbPredicate(MI); - return true; + return result; } MI.clear(); result = decodeCommonInstruction32(MI, insn32, Address, this); - if (result) { + if (result != Fail) { Size = 4; AddThumbPredicate(MI); - return true; + return result; } MI.clear(); result = decodeVFPInstruction32(MI, insn32, Address, this); - if (result) { + if (result != Fail) { Size = 4; UpdateThumbVFPPredicate(MI); - return true; + return result; } MI.clear(); result = decodeNEONDupInstruction32(MI, insn32, Address, this); - if (result) { + if (result != Fail) { Size = 4; AddThumbPredicate(MI); - return true; + return result; } if (fieldFromInstruction32(insn32, 24, 8) == 0xF9) { @@ -515,10 +526,10 @@ bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, NEONLdStInsn &= 0xF0FFFFFF; NEONLdStInsn |= 0x04000000; result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this); - if (result) { + if (result != Fail) { Size = 4; AddThumbPredicate(MI); - return true; + return result; } } @@ -529,14 +540,14 @@ bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 NEONDataInsn |= 0x12000000; // Set bits 28 and 25 result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this); - if (result) { + if (result != Fail) { Size = 4; AddThumbPredicate(MI); - return true; + return result; } } - return false; + return Fail; } @@ -554,30 +565,30 @@ static const unsigned GPRDecoderTable[] = { ARM::R12, ARM::SP, ARM::LR, ARM::PC }; -static bool DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 15) - return false; + return Fail; unsigned Register = GPRDecoderTable[RegNo]; Inst.addOperand(MCOperand::CreateReg(Register)); - return true; + return Success; } -static bool DecodeGPRnopcRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeGPRnopcRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (RegNo == 15) return false; + if (RegNo == 15) return Fail; return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); } -static bool DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 7) - return false; + return Fail; return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); } -static bool DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { unsigned Register = 0; switch (RegNo) { @@ -600,16 +611,16 @@ static bool DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, Register = ARM::R12; break; default: - return false; + return Fail; } Inst.addOperand(MCOperand::CreateReg(Register)); - return true; + return Success; } -static bool DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (RegNo == 13 || RegNo == 15) return false; + if (RegNo == 13 || RegNo == 15) return Fail; return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); } @@ -624,14 +635,14 @@ static const unsigned SPRDecoderTable[] = { ARM::S28, ARM::S29, ARM::S30, ARM::S31 }; -static bool DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 31) - return false; + return Fail; unsigned Register = SPRDecoderTable[RegNo]; Inst.addOperand(MCOperand::CreateReg(Register)); - return true; + return Success; } static const unsigned DPRDecoderTable[] = { @@ -645,27 +656,27 @@ static const unsigned DPRDecoderTable[] = { ARM::D28, ARM::D29, ARM::D30, ARM::D31 }; -static bool DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 31) - return false; + return Fail; unsigned Register = DPRDecoderTable[RegNo]; Inst.addOperand(MCOperand::CreateReg(Register)); - return true; + return Success; } -static bool DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 7) - return false; + return Fail; return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); } -static bool DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 15) - return false; + return Fail; return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); } @@ -677,65 +688,66 @@ static const unsigned QPRDecoderTable[] = { }; -static bool DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 31) - return false; + return Fail; RegNo >>= 1; unsigned Register = QPRDecoderTable[RegNo]; Inst.addOperand(MCOperand::CreateReg(Register)); - return true; + return Success; } -static bool DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { - if (Val == 0xF) return false; + if (Val == 0xF) return Fail; // AL predicate is not allowed on Thumb1 branches. if (Inst.getOpcode() == ARM::tBcc && Val == 0xE) - return false; + return Fail; Inst.addOperand(MCOperand::CreateImm(Val)); if (Val == ARMCC::AL) { Inst.addOperand(MCOperand::CreateReg(0)); } else Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); - return true; + return Success; } -static bool DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { if (Val) Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); else Inst.addOperand(MCOperand::CreateReg(0)); - return true; + return Success; } -static bool DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { uint32_t imm = Val & 0xFF; uint32_t rot = (Val & 0xF00) >> 7; uint32_t rot_imm = (imm >> rot) | (imm << (32-rot)); Inst.addOperand(MCOperand::CreateImm(rot_imm)); - return true; + return Success; } -static bool DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { Val <<= 2; Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(Val))); - return true; + return Success; } -static bool DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Val, +static DecodeStatus DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { + DecodeStatus S = Success; unsigned Rm = fieldFromInstruction32(Val, 0, 4); unsigned type = fieldFromInstruction32(Val, 5, 2); unsigned imm = fieldFromInstruction32(Val, 7, 5); // Register-immediate - if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) |