[JSC][GTK][JSCONLY] Use capstone disassembler
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2018 11:42:09 +0000 (11:42 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2018 11:42:09 +0000 (11:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185283

Reviewed by Michael Catanzaro.

.:

* Source/CMakeLists.txt:
* Source/cmake/FindLLVM.cmake: Removed.
* Source/cmake/OptionsCommon.cmake:
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsJSCOnly.cmake:
* Source/cmake/OptionsWPE.cmake:

Source/JavaScriptCore:

Instead of adding MIPS disassembler baked by ourselves, we import capstone disassembler.
And use capstone disassembler for MIPS, ARM, and ARMv7 in GTK, WPE, WinCairo and JSCOnly ports.

And we remove ARM LLVM disassembler.

Capstone is licensed under 3-clause BSD, which is acceptable in WebKit tree.

* CMakeLists.txt:
* Sources.txt:
* disassembler/ARMLLVMDisassembler.cpp: Removed.
* disassembler/CapstoneDisassembler.cpp: Added.
(JSC::tryToDisassemble):

Source/ThirdParty:

Add capstone to ThirdParty. We build capstone as a static library,
and link it against JSC. We only build disassembler for target architecture.
So for MIPS target, we only enable MIPS part of capstone.

We also remove unnecessary architectures in capstone, XCore, PowerPC, SystemZ, etc.
This is simply done by deleting these architecture directories.

We pick "next" branch instead of "master" branch since "next" branch is actively
developed.

* capstone/CMakeLists.txt: Added.
* capstone/Source/.appveyor.yml: Added.
* capstone/Source/.gitattributes: Added.
* capstone/Source/.gitignore: Added.
* capstone/Source/.travis.yml: Added.
* capstone/Source/CMakeLists.txt: Added.
* capstone/Source/COMPILE.TXT: Added.
* capstone/Source/COMPILE_CMAKE.TXT: Added.
* capstone/Source/COMPILE_MSVC.TXT: Added.
* capstone/Source/CREDITS.TXT: Added.
* capstone/Source/ChangeLog-capstone: Added.
* capstone/Source/HACK.TXT: Added.
* capstone/Source/LEB128.h: Added.
(decodeULEB128):
* capstone/Source/LICENSE.TXT: Added.
* capstone/Source/LICENSE_LLVM.TXT: Added.
* capstone/Source/MCDisassembler.h: Added.
* capstone/Source/MCFixedLenDisassembler.h: Added.
* capstone/Source/MCInst.c: Added.
(MCInst_Init):
(MCInst_clear):
(MCInst_insert0):
(MCInst_setOpcode):
(MCInst_setOpcodePub):
(MCInst_getOpcode):
(MCInst_getOpcodePub):
(MCInst_getOperand):
(MCInst_getNumOperands):
(MCInst_addOperand2):
(MCOperand_Init):
(MCOperand_isValid):
(MCOperand_isReg):
(MCOperand_isImm):
(MCOperand_isFPImm):
(MCOperand_getReg):
(MCOperand_setReg):
(MCOperand_getImm):
(MCOperand_setImm):
(MCOperand_getFPImm):
(MCOperand_setFPImm):
(MCOperand_CreateReg1):
(MCOperand_CreateReg0):
(MCOperand_CreateImm1):
(MCOperand_CreateImm0):
* capstone/Source/MCInst.h: Added.
* capstone/Source/MCInstrDesc.c: Added.
(MCOperandInfo_isPredicate):
(MCOperandInfo_isOptionalDef):
* capstone/Source/MCInstrDesc.h: Added.
* capstone/Source/MCRegisterInfo.c: Added.
(MCRegisterInfo_InitMCRegisterInfo):
(DiffListIterator_init):
(DiffListIterator_getVal):
(DiffListIterator_next):
(DiffListIterator_isValid):
(MCRegisterInfo_getMatchingSuperReg):
(MCRegisterInfo_getSubReg):
(MCRegisterInfo_getRegClass):
(MCRegisterClass_contains):
* capstone/Source/MCRegisterInfo.h: Added.
* capstone/Source/Makefile: Added.
* capstone/Source/MathExtras.h: Added.
(Hi_32):
(Lo_32):
(isUIntN):
(isMask_32):
(isMask_64):
(isShiftedMask_32):
(isShiftedMask_64):
(isPowerOf2_32):
(CountLeadingZeros_32):
(CountLeadingOnes_32):
(CountLeadingZeros_64):
(CountLeadingOnes_64):
(CountTrailingZeros_32):
(CountTrailingOnes_32):
(CountTrailingZeros_64):
(CountTrailingOnes_64):
(CountPopulation_32):
(CountPopulation_64):
(Log2_32):
(Log2_64):
(Log2_32_Ceil):
(Log2_64_Ceil):
(GreatestCommonDivisor64):
(BitsToDouble):
(BitsToFloat):
(DoubleToBits):
(FloatToBits):
(MinAlign):
(NextPowerOf2):
(RoundUpToAlignment):
(OffsetToAlignment):
(abs64):
(SignExtend32):
(SignExtend64):
(countLeadingZeros):
* capstone/Source/README.md: Added.
* capstone/Source/RELEASE_NOTES: Added.
* capstone/Source/SStream.c: Added.
(SStream_Init):
(SStream_concat0):
(SStream_concat):
(printInt64Bang):
(printUInt64Bang):
(printInt64):
(printInt32BangDec):
(printInt32Bang):
(printInt32):
(printUInt32Bang):
(printUInt32):
* capstone/Source/SStream.h: Added.
* capstone/Source/TODO: Added.
* capstone/Source/arch/ARM/ARMAddressingModes.h: Added.
(ARM_AM_getAddrOpcStr):
(ARM_AM_getShiftOpcStr):
(ARM_AM_getShiftOpcEncoding):
(ARM_AM_getAMSubModeStr):
(rotr32):
(rotl32):
(getSORegOpc):
(getSORegOffset):
(ARM_AM_getSORegShOp):
(getSOImmValImm):
(getSOImmValRot):
(getSOImmValRotate):
(getSOImmVal):
(isSOImmTwoPartVal):
(getSOImmTwoPartFirst):
(getSOImmTwoPartSecond):
(getThumbImmValShift):
(isThumbImmShiftedVal):
(getThumbImm16ValShift):
(isThumbImm16ShiftedVal):
(getThumbImmNonShiftedVal):
(getT2SOImmValSplatVal):
(getT2SOImmValRotateVal):
(getT2SOImmVal):
(getT2SOImmValRotate):
(isT2SOImmTwoPartVal):
(getT2SOImmTwoPartFirst):
(getT2SOImmTwoPartSecond):
(ARM_AM_getAM2Opc):
(getAM2Offset):
(getAM2Op):
(getAM2ShiftOpc):
(getAM2IdxMode):
(getAM3Opc):
(getAM3Offset):
(getAM3Op):
(getAM3IdxMode):
(getAM4SubMode):
(getAM4ModeImm):
(ARM_AM_getAM5Opc):
(ARM_AM_getAM5Offset):
(ARM_AM_getAM5Op):
(createNEONModImm):
(getNEONModImmOpCmode):
(getNEONModImmVal):
(ARM_AM_decodeNEONModImm):
(getFPImmFloat):
* capstone/Source/arch/ARM/ARMBaseInfo.h: Added.
(ARMCC_getOppositeCondition):
(ARMCC_ARMCondCodeToString):
(ARM_PROC_IFlagsToString):
(ARM_PROC_IModToString):
(ARM_MB_MemBOptToString):
(ARM_ISB_InstSyncBOptToString):
(isARMLowRegister):
(ARMII_AddrModeToString):
* capstone/Source/arch/ARM/ARMDisassembler.c: Added.
(ITStatus_push_back):
(ITStatus_instrInITBlock):
(ITStatus_instrLastInITBlock):
(ITStatus_getITCC):
(ITStatus_advanceITState):
(ITStatus_setITState):
(Check):
(ARM_getFeatureBits):
(DecodePredicateOperand):
(ARM_init):
(checkDecodedInstruction):
(_ARM_getInstruction):
(AddThumb1SBit):
(AddThumbPredicate):
(UpdateThumbVFPPredicate):
(_Thumb_getInstruction):
(Thumb_getInstruction):
(ARM_getInstruction):
(DecodeGPRnopcRegisterClass):
(DecodeGPRwithAPSRRegisterClass):
(DecodetGPRRegisterClass):
(DecodetcGPRRegisterClass):
(DecoderGPRRegisterClass):
(DecodeDPRRegisterClass):
(DecodeDPR_8RegisterClass):
(DecodeDPR_VFP2RegisterClass):
(DecodeDPairRegisterClass):
(DecodeCCOutOperand):
(DecodeSORegImmOperand):
(DecodeSORegRegOperand):
(DecodeRegListOperand):
(DecodeSPRRegListOperand):
(DecodeDPRRegListOperand):
(DecodeBitfieldMaskOperand):
(DecodeCopMemInstruction):
(DecodeAddrMode2IdxInstruction):
(DecodeSORegMemOperand):
(DecodeAddrMode3Instruction):
(DecodeRFEInstruction):
(DecodeQADDInstruction):
(DecodeMemMultipleWritebackInstruction):
(DecodeCPSInstruction):
(DecodeT2CPSInstruction):
(DecodeT2MOVTWInstruction):
(DecodeArmMOVTWInstruction):
(DecodeSMLAInstruction):
(DecodeAddrModeImm12Operand):
(DecodeAddrMode5Operand):
(DecodeAddrMode7Operand):
(DecodeT2BInstruction):
(DecodeBranchImmInstruction):
(DecodeAddrMode6Operand):
(DecodeVLDInstruction):
(DecodeVLDST1Instruction):
(DecodeVLDST2Instruction):
(DecodeVLDST3Instruction):
(DecodeVLDST4Instruction):
(DecodeVSTInstruction):
(DecodeVLD1DupInstruction):
(DecodeVLD2DupInstruction):
(DecodeVLD3DupInstruction):
(DecodeVLD4DupInstruction):
(DecodeNEONModImmInstruction):
(DecodeVSHLMaxInstruction):
(DecodeShiftRight8Imm):
(DecodeShiftRight16Imm):
(DecodeShiftRight32Imm):
(DecodeShiftRight64Imm):
(DecodeTBLInstruction):
(DecodeThumbAddSpecialReg):
(DecodeThumbBROperand):
(DecodeT2BROperand):
(DecodeThumbCmpBROperand):
(DecodeThumbAddrModeRR):
(DecodeThumbAddrModeIS):
(DecodeThumbAddrModePC):
(DecodeThumbAddrModeSP):
(DecodeT2AddrModeSOReg):
(DecodeT2LoadShift):
(DecodeT2LoadImm8):
(DecodeT2LoadImm12):
(DecodeT2LoadT):
(DecodeT2LoadLabel):
(DecodeT2Imm8S4):
(DecodeT2AddrModeImm8s4):
(DecodeT2AddrModeImm0_1020s4):
(DecodeT2Imm8):
(DecodeT2AddrModeImm8):
(DecodeT2LdStPre):
(DecodeT2AddrModeImm12):
(DecodeThumbAddSPImm):
(DecodeThumbAddSPReg):
(DecodeThumbCPS):
(DecodePostIdxReg):
(DecodeThumbBLXOffset):
(DecodeCoprocessor):
(DecodeThumbTableBranch):
(DecodeThumb2BCCInstruction):
(DecodeT2SOImm):
(DecodeThumbBCCTargetOperand):
(DecodeThumbBLTargetOperand):
(DecodeMemBarrierOption):
(DecodeInstSyncBarrierOption):
(DecodeMSRMask):
(DecodeBankedReg):
(DecodeDoubleRegLoad):
(DecodeDoubleRegStore):
(DecodeLDRPreImm):
(DecodeLDRPreReg):
(DecodeSTRPreImm):
(DecodeSTRPreReg):
(DecodeVLD1LN):
(DecodeVST1LN):
(DecodeVLD2LN):
(DecodeVST2LN):
(DecodeVLD3LN):
(DecodeVST3LN):
(DecodeVLD4LN):
(DecodeVST4LN):
(DecodeVMOVSRR):
(DecodeVMOVRRS):
(DecodeIT):
(DecodeT2LDRDPreInstruction):
(DecodeT2STRDPreInstruction):
(DecodeT2Adr):
(DecodeT2ShifterImmOperand):
(DecodeSwap):
(DecodeVCVTD):
(DecodeVCVTQ):
(DecodeLDR):
(DecodeMRRC2):
* capstone/Source/arch/ARM/ARMDisassembler.h: Added.
* capstone/Source/arch/ARM/ARMGenAsmWriter.inc: Added.
* capstone/Source/arch/ARM/ARMGenDisassemblerTables.inc: Added.
* capstone/Source/arch/ARM/ARMGenInstrInfo.inc: Added.
* capstone/Source/arch/ARM/ARMGenRegisterInfo.inc: Added.
* capstone/Source/arch/ARM/ARMGenSubtargetInfo.inc: Added.
* capstone/Source/arch/ARM/ARMInstPrinter.c: Added.
(get_op_access):
(set_mem_access):
(op_addImm):
(ARM_getRegName):
(translateShiftImm):
(printRegImmShift):
(printRegName):
(ARM_printInst):
(printOperand):
(printThumbLdrLabelOperand):
(printSORegRegOperand):
(printSORegImmOperand):
(printAM2PreOrOffsetIndexOp):
(printAddrModeTBB):
(printAddrModeTBH):
(printAddrMode2Operand):
(printAddrMode2OffsetOperand):
(printAM3PreOrOffsetIndexOp):
(printAddrMode3Operand):
(printAddrMode3OffsetOperand):
(printPostIdxImm8Operand):
(printPostIdxRegOperand):
(printPostIdxImm8s4Operand):
(printAddrMode5Operand):
(printAddrMode6Operand):
(printAddrMode7Operand):
(printAddrMode6OffsetOperand):
(printBitfieldInvMaskImmOperand):
(printMemBOption):
(printInstSyncBOption):
(printShiftImmOperand):
(printPKHLSLShiftImm):
(printPKHASRShiftImm):
(printRegisterList):
(printGPRPairOperand):
(printSetendOperand):
(printCPSIMod):
(printCPSIFlag):
(printMSRMaskOperand):
(printBankedRegOperand):
(printPredicateOperand):
(printMandatoryPredicateOperand):
(printSBitModifierOperand):
(printNoHashImmediate):
(printPImmediate):
(printCImmediate):
(printCoprocOptionImm):
(printAdrLabelOperand):
(printThumbS4ImmOperand):
(printThumbSRImm):
(printThumbITMask):
(printThumbAddrModeRROperand):
(printThumbAddrModeImm5SOperand):
(printThumbAddrModeImm5S1Operand):
(printThumbAddrModeImm5S2Operand):
(printThumbAddrModeImm5S4Operand):
(printThumbAddrModeSPOperand):
(printT2SOOperand):
(printAddrModeImm12Operand):
(printT2AddrModeImm8Operand):
(printT2AddrModeImm8s4Operand):
(printT2AddrModeImm0_1020s4Operand):
(printT2AddrModeImm8OffsetOperand):
(printT2AddrModeImm8s4OffsetOperand):
(printT2AddrModeSoRegOperand):
(printFPImmOperand):
(printNEONModImmOperand):
(printImmPlusOneOperand):
(printRotImmOperand):
(printModImmOperand):
(printFBits16):
(printFBits32):
(printVectorIndex):
(printVectorListOne):
(printVectorListTwo):
(printVectorListTwoSpaced):
(printVectorListThree):
(printVectorListFour):
(printVectorListOneAllLanes):
(printVectorListTwoAllLanes):
(printVectorListThreeAllLanes):
(printVectorListFourAllLanes):
(printVectorListTwoSpacedAllLanes):
(printVectorListThreeSpacedAllLanes):
(printVectorListFourSpacedAllLanes):
(printVectorListThreeSpaced):
(printVectorListFourSpaced):
(ARM_addVectorDataType):
(ARM_addVectorDataSize):
(ARM_addReg):
(ARM_addUserMode):
(ARM_addSysReg):
* capstone/Source/arch/ARM/ARMInstPrinter.h: Added.
* capstone/Source/arch/ARM/ARMMapping.c: Added.
(ARM_reg_name2):
(ARM_insn_name):
(ARM_rel_branch):
(ARM_blx_to_arm_mode):
(ARM_reg_access):
* capstone/Source/arch/ARM/ARMMapping.h: Added.
* capstone/Source/arch/ARM/ARMMappingInsn.inc: Added.
* capstone/Source/arch/ARM/ARMMappingInsnOp.inc: Added.
* capstone/Source/arch/ARM/ARMModule.c: Added.
(init):
(option):
(ARM_enable):
* capstone/Source/arch/Mips/MipsDisassembler.c: Added.
(getFeatureBits):
(Mips_init):
(readInstruction16):
(readInstruction32):
(MipsDisassembler_getInstruction):
(Mips_getInstruction):
(getReg):
(DecodeINSVE_DF_4):
(DecodeAddiGroupBranch_4):
(DecodeDaddiGroupBranch_4):
(DecodeBlezlGroupBranch_4):
(DecodeBgtzlGroupBranch_4):
(DecodeBgtzGroupBranch_4):
(DecodeBlezGroupBranch_4):
(DecodeCPU16RegsRegisterClass):
(DecodeGPR64RegisterClass):
(DecodeGPRMM16RegisterClass):
(DecodeGPRMM16ZeroRegisterClass):
(DecodeGPRMM16MovePRegisterClass):
(DecodeGPR32RegisterClass):
(DecodePtrRegisterClass):
(DecodeDSPRRegisterClass):
(DecodeFGR64RegisterClass):
(DecodeFGR32RegisterClass):
(DecodeCCRRegisterClass):
(DecodeFCCRegisterClass):
(DecodeCCRegisterClass):
(DecodeFGRCCRegisterClass):
(DecodeMem):
(DecodeCacheOp):
(DecodeCacheOpMM):
(DecodeCacheOpR6):
(DecodeSyncI):
(DecodeMSA128Mem):
(DecodeMemMMImm4):
(DecodeMemMMSPImm5Lsl2):
(DecodeMemMMGPImm7Lsl2):
(DecodeMemMMReglistImm4Lsl2):
(DecodeMemMMImm12):
(DecodeMemMMImm16):
(DecodeFMem):
(DecodeFMem2):
(DecodeFMem3):
(DecodeFMemCop2R6):
(DecodeSpecial3LlSc):
(DecodeHWRegsRegisterClass):
(DecodeAFGR64RegisterClass):
(DecodeACC64DSPRegisterClass):
(DecodeHI32DSPRegisterClass):
(DecodeLO32DSPRegisterClass):
(DecodeMSA128BRegisterClass):
(DecodeMSA128HRegisterClass):
(DecodeMSA128WRegisterClass):
(DecodeMSA128DRegisterClass):
(DecodeMSACtrlRegisterClass):
(DecodeCOP2RegisterClass):
(DecodeBranchTarget):
(DecodeJumpTarget):
(DecodeBranchTarget21):
(DecodeBranchTarget26):
(DecodeBranchTarget7MM):
(DecodeBranchTarget10MM):
(DecodeBranchTargetMM):
(DecodeJumpTargetMM):
(DecodeAddiur2Simm7):
(DecodeUImm6Lsl2):
(DecodeLiSimm7):
(DecodeSimm4):
(DecodeSimm16):
(DecodeLSAImm):
(DecodeInsSize):
(DecodeExtSize):
(DecodeSimm19Lsl2):
(DecodeSimm18Lsl3):
(DecodeSimm9SP):
(DecodeANDI16Imm):
(DecodeUImm5lsl2):
(DecodeRegListOperand):
(DecodeRegListOperand16):
(DecodeMovePRegPair):
(DecodeSimm23Lsl2):
* capstone/Source/arch/Mips/MipsDisassembler.h: Added.
* capstone/Source/arch/Mips/MipsGenAsmWriter.inc: Added.
* capstone/Source/arch/Mips/MipsGenDisassemblerTables.inc: Added.
* capstone/Source/arch/Mips/MipsGenInstrInfo.inc: Added.
* capstone/Source/arch/Mips/MipsGenRegisterInfo.inc: Added.
* capstone/Source/arch/Mips/MipsGenSubtargetInfo.inc: Added.
* capstone/Source/arch/Mips/MipsInstPrinter.c: Added.
(set_mem_access):
(isReg):
(MipsFCCToString):
(printRegName):
(Mips_printInst):
(printOperand):
(printUnsignedImm):
(printUnsignedImm8):
(printMemOperand):
(printMemOperandEA):
(printFCCOperand):
(printRegisterPair):
(printAlias1):
(printAlias2):
(printAlias):
(printRegisterList):
* capstone/Source/arch/Mips/MipsInstPrinter.h: Added.
* capstone/Source/arch/Mips/MipsMapping.c: Added.
(Mips_get_insn_id):
(Mips_group_name):
(Mips_map_insn):
(Mips_map_register):
* capstone/Source/arch/Mips/MipsMapping.h: Added.
* capstone/Source/arch/Mips/MipsMappingInsn.inc: Added.
* capstone/Source/arch/Mips/MipsModule.c: Added.
(init):
(option):
(Mips_enable):
* capstone/Source/capstone.pc.in: Added.
* capstone/Source/config.mk: Added.
* capstone/Source/cs.c: Added.
(cs_kern_os_calloc):
(cs_version):
(cs_support):
(cs_errno):
(cs_strerror):
(cs_open):
(cs_close):
(fill_insn):
(skipdata_size):
(cs_option):
(skipdata_opstr):
(cs_disasm):
(cs_disasm_ex):
(cs_free):
(cs_malloc):
(cs_disasm_iter):
(cs_reg_name):
(cs_insn_name):
(cs_group_name):
(cs_insn_group):
(cs_reg_read):
(cs_reg_write):
(cs_op_count):
(cs_op_index):
(cs_regs_access):
* capstone/Source/cs_priv.h: Added.
* capstone/Source/functions.mk: Added.
* capstone/Source/include/capstone/arm.h: Added.
* capstone/Source/include/capstone/arm64.h: Added.
* capstone/Source/include/capstone/capstone.h: Added.
* capstone/Source/include/capstone/evm.h: Added.
* capstone/Source/include/capstone/m680x.h: Added.
* capstone/Source/include/capstone/m68k.h: Added.
* capstone/Source/include/capstone/mips.h: Added.
* capstone/Source/include/capstone/platform.h: Added.
* capstone/Source/include/capstone/ppc.h: Added.
* capstone/Source/include/capstone/sparc.h: Added.
* capstone/Source/include/capstone/systemz.h: Added.
* capstone/Source/include/capstone/tms320c64x.h: Added.
* capstone/Source/include/capstone/x86.h: Added.
* capstone/Source/include/capstone/xcore.h: Added.
* capstone/Source/include/windowsce/intrin.h: Added.
* capstone/Source/include/windowsce/stdint.h: Added.
* capstone/Source/make.sh: Added.
* capstone/Source/nmake-x86.bat: Added.
* capstone/Source/nmake.bat: Added.
* capstone/Source/pkgconfig.mk: Added.
* capstone/Source/utils.c: Added.
(make_id2insn):
(insn_find):
(name2id):
(id2name):
(count_positive):
(count_positive8):
(cs_strdup):
(cs_snprintf):
(arr_exist8):
(arr_exist):
* capstone/Source/utils.h: Added.
* capstone/capstone-Revision.txt: Added.

Source/WTF:

Add USE_CAPSTONE used for MIPS and ARM.

* wtf/Platform.h:

Tools:

* gtk/manifest.txt.in:
* wpe/manifest.txt.in:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231553 268f45cc-cd09-0410-ab3c-d52691b4dbfc

105 files changed:
ChangeLog
Source/CMakeLists.txt
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/disassembler/ARMLLVMDisassembler.cpp [deleted file]
Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp [new file with mode: 0644]
Source/ThirdParty/ChangeLog
Source/ThirdParty/capstone/CMakeLists.txt [new file with mode: 0644]
Source/ThirdParty/capstone/Source/.appveyor.yml [new file with mode: 0644]
Source/ThirdParty/capstone/Source/.gitattributes [new file with mode: 0644]
Source/ThirdParty/capstone/Source/.gitignore [new file with mode: 0644]
Source/ThirdParty/capstone/Source/.travis.yml [new file with mode: 0644]
Source/ThirdParty/capstone/Source/CMakeLists.txt [new file with mode: 0644]
Source/ThirdParty/capstone/Source/COMPILE.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/COMPILE_CMAKE.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/COMPILE_MSVC.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/CREDITS.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/ChangeLog-capstone [new file with mode: 0644]
Source/ThirdParty/capstone/Source/HACK.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/LEB128.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/LICENSE.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/LICENSE_LLVM.TXT [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCDisassembler.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCFixedLenDisassembler.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCInst.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCInst.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCInstrDesc.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCInstrDesc.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCRegisterInfo.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MCRegisterInfo.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/Makefile [new file with mode: 0644]
Source/ThirdParty/capstone/Source/MathExtras.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/README.md [new file with mode: 0644]
Source/ThirdParty/capstone/Source/RELEASE_NOTES [new file with mode: 0644]
Source/ThirdParty/capstone/Source/SStream.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/SStream.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/TODO [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMAddressingModes.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMBaseInfo.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMDisassembler.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMDisassembler.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMGenAsmWriter.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMGenDisassemblerTables.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMGenInstrInfo.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMGenRegisterInfo.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMGenSubtargetInfo.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMInstPrinter.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMInstPrinter.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMMapping.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMMapping.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMMappingInsn.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMMappingInsnOp.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/ARM/ARMModule.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsDisassembler.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsDisassembler.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsGenAsmWriter.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsGenDisassemblerTables.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsGenInstrInfo.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsGenRegisterInfo.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsGenSubtargetInfo.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsInstPrinter.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsInstPrinter.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsMapping.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsMapping.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsMappingInsn.inc [new file with mode: 0644]
Source/ThirdParty/capstone/Source/arch/Mips/MipsModule.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/capstone.pc.in [new file with mode: 0644]
Source/ThirdParty/capstone/Source/config.mk [new file with mode: 0644]
Source/ThirdParty/capstone/Source/cs.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/cs_priv.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/functions.mk [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/arm.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/arm64.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/capstone.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/evm.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/m680x.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/m68k.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/mips.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/platform.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/ppc.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/sparc.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/systemz.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/tms320c64x.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/x86.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/capstone/xcore.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/windowsce/intrin.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/include/windowsce/stdint.h [new file with mode: 0644]
Source/ThirdParty/capstone/Source/make.sh [new file with mode: 0755]
Source/ThirdParty/capstone/Source/nmake-x86.bat [new file with mode: 0644]
Source/ThirdParty/capstone/Source/nmake.bat [new file with mode: 0644]
Source/ThirdParty/capstone/Source/pkgconfig.mk [new file with mode: 0644]
Source/ThirdParty/capstone/Source/utils.c [new file with mode: 0644]
Source/ThirdParty/capstone/Source/utils.h [new file with mode: 0644]
Source/ThirdParty/capstone/capstone-Revision.txt [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h
Source/cmake/FindLLVM.cmake [deleted file]
Source/cmake/OptionsCommon.cmake
Source/cmake/OptionsGTK.cmake
Source/cmake/OptionsJSCOnly.cmake
Source/cmake/OptionsWPE.cmake
Tools/ChangeLog
Tools/gtk/manifest.txt.in
Tools/wpe/manifest.txt.in

index 3418532..81ff262 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2018-05-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC][GTK][JSCONLY] Use capstone disassembler
+        https://bugs.webkit.org/show_bug.cgi?id=185283
+
+        Reviewed by Michael Catanzaro.
+
+        * Source/CMakeLists.txt:
+        * Source/cmake/FindLLVM.cmake: Removed.
+        * Source/cmake/OptionsCommon.cmake:
+        * Source/cmake/OptionsGTK.cmake:
+        * Source/cmake/OptionsJSCOnly.cmake:
+        * Source/cmake/OptionsWPE.cmake:
+
 2018-05-08  Valerie R Young  <valerie@bocoup.com>
 
         test262/Runner.pm: create results dir for results of test262 run
index 05d8207..54fe4a2 100644 (file)
@@ -7,6 +7,10 @@ endif ()
 
 add_subdirectory(WTF)
 
+if (USE_CAPSTONE)
+    add_subdirectory(ThirdParty/capstone)
+endif ()
+
 add_subdirectory(JavaScriptCore)
 
 if (WIN32 AND ENABLE_GRAPHICS_CONTEXT_3D)
index 7080962..3a4e26e 100644 (file)
@@ -50,6 +50,10 @@ set(JavaScriptCore_PRIVATE_INCLUDE_DIRECTORIES
     "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/yarr"
 )
 
+if (USE_CAPSTONE)
+    list(APPEND JavaScriptCore_PRIVATE_INCLUDE_DIRECTORIES "${THIRDPARTY_DIR}/capstone/Source/include")
+endif ()
+
 set(JavaScriptCore_SYSTEM_INCLUDE_DIRECTORIES
     "${ICU_INCLUDE_DIRS}"
 )
@@ -115,9 +119,12 @@ set(JavaScriptCore_OBJECT_LUT_SOURCES
 set(JavaScriptCore_LIBRARIES
     WTF${DEBUG_SUFFIX}
     ${ICU_I18N_LIBRARIES}
-    ${LLVM_LIBRARIES}
 )
 
+if (USE_CAPSTONE)
+    list(APPEND JavaScriptCore_LIBRARIES capstone)
+endif ()
+
 # Since r228149, on MIPS we need to link with -latomic, because
 # __atomic_fetch_add_8 is not available as a compiler intrinsic. It is
 # available on other platforms (including 32-bit Arm), so the link with
index a842134..b129aaa 100644 (file)
@@ -1,3 +1,23 @@
+2018-05-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC][GTK][JSCONLY] Use capstone disassembler
+        https://bugs.webkit.org/show_bug.cgi?id=185283
+
+        Reviewed by Michael Catanzaro.
+
+        Instead of adding MIPS disassembler baked by ourselves, we import capstone disassembler.
+        And use capstone disassembler for MIPS, ARM, and ARMv7 in GTK, WPE, WinCairo and JSCOnly ports.
+
+        And we remove ARM LLVM disassembler.
+
+        Capstone is licensed under 3-clause BSD, which is acceptable in WebKit tree.
+
+        * CMakeLists.txt:
+        * Sources.txt:
+        * disassembler/ARMLLVMDisassembler.cpp: Removed.
+        * disassembler/CapstoneDisassembler.cpp: Added.
+        (JSC::tryToDisassemble):
+
 2018-05-09  Dominik Infuehr  <dinfuehr@igalia.com>
 
         [MIPS] Use mfhc1 and mthc1 to fix assembler error
index 662475f..e4f01ad 100644 (file)
@@ -411,8 +411,8 @@ dfg/DFGWatchpointCollectionPhase.cpp
 dfg/DFGWorklist.cpp
 
 disassembler/ARM64Disassembler.cpp
-disassembler/ARMLLVMDisassembler.cpp
 disassembler/ARMv7Disassembler.cpp
+disassembler/CapstoneDisassembler.cpp
 disassembler/Disassembler.cpp
 disassembler/UDis86Disassembler.cpp
 disassembler/X86Disassembler.cpp
diff --git a/Source/JavaScriptCore/disassembler/ARMLLVMDisassembler.cpp b/Source/JavaScriptCore/disassembler/ARMLLVMDisassembler.cpp
deleted file mode 100644 (file)
index a349abb..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Disassembler.h"
-
-#if USE(ARM_LLVM_DISASSEMBLER)
-
-#include "MacroAssemblerCodeRef.h"
-#include <llvm-c/Disassembler.h>
-#include <llvm-c/Target.h>
-
-namespace JSC {
-
-bool tryToDisassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char* prefix, PrintStream& out)
-{
-    LLVMInitializeAllTargetInfos();
-    LLVMInitializeAllTargetMCs();
-    LLVMInitializeAllDisassemblers();
-
-    const char* triple = "armv7-unknown-linux-gnueabihf";
-    LLVMDisasmContextRef disassemblyContext = LLVMCreateDisasm(triple, 0, 0, 0, 0);
-
-    RELEASE_ASSERT(disassemblyContext);
-
-    char pcString[20];
-    char instructionString[100];
-
-    uint8_t* pc = static_cast<uint8_t*>(codePtr.executableAddress());
-    uint8_t* end = pc + size;
-
-    while (pc < end) {
-        snprintf(
-            pcString, sizeof(pcString), "0x%lx",
-            static_cast<unsigned long>(bitwise_cast<uintptr_t>(pc)));
-
-        size_t instructionSize = LLVMDisasmInstruction(
-            disassemblyContext, pc, end - pc, bitwise_cast<uintptr_t>(pc),
-            instructionString, sizeof(instructionString));
-
-        if (!instructionSize)
-            snprintf(instructionString, sizeof(instructionString), "unknown instruction");
-
-        out.printf("%s%16s: [0x%08lx] %s\n", prefix, pcString, *(reinterpret_cast<unsigned long*>(pc)), instructionString);
-        pc += 4;
-    }
-
-    LLVMDisasmDispose(disassemblyContext);
-    return true;
-}
-
-} // namespace JSC
-
-#endif // USE(ARM_LLVM_DISASSEMBLER)
diff --git a/Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp b/Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp
new file mode 100644 (file)
index 0000000..47b5612
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(DISASSEMBLER) && USE(CAPSTONE)
+
+#include "MacroAssemblerCodeRef.h"
+#include "Options.h"
+#include <capstone/capstone.h>
+
+namespace JSC {
+
+bool tryToDisassemble(const MacroAssemblerCodePtr<DisassemblyPtrTag>& codePtr, size_t size, const char* prefix, PrintStream& out)
+{
+    csh handle;
+    cs_insn* instructions;
+
+#if CPU(X86)
+    if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
+        return false;
+#elif CPU(X86_64)
+    if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
+        return false;
+#elif CPU(ARM_TRADITIONAL)
+    if (cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle) != CS_ERR_OK)
+        return false;
+#elif CPU(ARM_THUMB2)
+    if (cs_open(CS_ARCH_ARM, CS_MODE_THUMB, &handle) != CS_ERR_OK)
+        return false;
+#elif CPU(ARM64)
+    if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &handle) != CS_ERR_OK)
+        return false;
+#elif CPU(MIPS)
+    if (cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32, &handle) != CS_ERR_OK)
+        return false;
+#else
+    return false;
+#endif
+
+#if CPU(X86) || CPU(X86_64)
+    if (cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT) != CS_ERR_OK) {
+        cs_close(&handle);
+        return false;
+    }
+#endif
+
+    size_t count = cs_disasm(handle, codePtr.untaggedExecutableAddress<unsigned char*>(), size, codePtr.untaggedExecutableAddress<uintptr_t>(), 0, &instructions);
+    if (count > 0) {
+        for (size_t i = 0; i < count; ++i) {
+            auto& instruction = instructions[i];
+            char pcString[20];
+            snprintf(pcString, sizeof(pcString), "0x%llx", static_cast<unsigned long long>(instruction.address));
+            out.printf("%s%16s: %s %s\n", prefix, pcString, instruction.mnemonic, instruction.op_str);
+        }
+        cs_free(instructions, count);
+    }
+    cs_close(&handle);
+    return true;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(DISASSEMBLER) && USE(CAPSTONE)
index 153819d..a486798 100644 (file)
@@ -1,3 +1,616 @@
+2018-05-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC][GTK][JSCONLY] Use capstone disassembler
+        https://bugs.webkit.org/show_bug.cgi?id=185283
+
+        Reviewed by Michael Catanzaro.
+
+        Add capstone to ThirdParty. We build capstone as a static library,
+        and link it against JSC. We only build disassembler for target architecture.
+        So for MIPS target, we only enable MIPS part of capstone.
+
+        We also remove unnecessary architectures in capstone, XCore, PowerPC, SystemZ, etc.
+        This is simply done by deleting these architecture directories.
+
+        We pick "next" branch instead of "master" branch since "next" branch is actively
+        developed.
+
+        * capstone/CMakeLists.txt: Added.
+        * capstone/Source/.appveyor.yml: Added.
+        * capstone/Source/.gitattributes: Added.
+        * capstone/Source/.gitignore: Added.
+        * capstone/Source/.travis.yml: Added.
+        * capstone/Source/CMakeLists.txt: Added.
+        * capstone/Source/COMPILE.TXT: Added.
+        * capstone/Source/COMPILE_CMAKE.TXT: Added.
+        * capstone/Source/COMPILE_MSVC.TXT: Added.
+        * capstone/Source/CREDITS.TXT: Added.
+        * capstone/Source/ChangeLog-capstone: Added.
+        * capstone/Source/HACK.TXT: Added.
+        * capstone/Source/LEB128.h: Added.
+        (decodeULEB128):
+        * capstone/Source/LICENSE.TXT: Added.
+        * capstone/Source/LICENSE_LLVM.TXT: Added.
+        * capstone/Source/MCDisassembler.h: Added.
+        * capstone/Source/MCFixedLenDisassembler.h: Added.
+        * capstone/Source/MCInst.c: Added.
+        (MCInst_Init):
+        (MCInst_clear):
+        (MCInst_insert0):
+        (MCInst_setOpcode):
+        (MCInst_setOpcodePub):
+        (MCInst_getOpcode):
+        (MCInst_getOpcodePub):
+        (MCInst_getOperand):
+        (MCInst_getNumOperands):
+        (MCInst_addOperand2):
+        (MCOperand_Init):
+        (MCOperand_isValid):
+        (MCOperand_isReg):
+        (MCOperand_isImm):
+        (MCOperand_isFPImm):
+        (MCOperand_getReg):
+        (MCOperand_setReg):
+        (MCOperand_getImm):
+        (MCOperand_setImm):
+        (MCOperand_getFPImm):
+        (MCOperand_setFPImm):
+        (MCOperand_CreateReg1):
+        (MCOperand_CreateReg0):
+        (MCOperand_CreateImm1):
+        (MCOperand_CreateImm0):
+        * capstone/Source/MCInst.h: Added.
+        * capstone/Source/MCInstrDesc.c: Added.
+        (MCOperandInfo_isPredicate):
+        (MCOperandInfo_isOptionalDef):
+        * capstone/Source/MCInstrDesc.h: Added.
+        * capstone/Source/MCRegisterInfo.c: Added.
+        (MCRegisterInfo_InitMCRegisterInfo):
+        (DiffListIterator_init):
+        (DiffListIterator_getVal):
+        (DiffListIterator_next):
+        (DiffListIterator_isValid):
+        (MCRegisterInfo_getMatchingSuperReg):
+        (MCRegisterInfo_getSubReg):
+        (MCRegisterInfo_getRegClass):
+        (MCRegisterClass_contains):
+        * capstone/Source/MCRegisterInfo.h: Added.
+        * capstone/Source/Makefile: Added.
+        * capstone/Source/MathExtras.h: Added.
+        (Hi_32):
+        (Lo_32):
+        (isUIntN):
+        (isMask_32):
+        (isMask_64):
+        (isShiftedMask_32):
+        (isShiftedMask_64):
+        (isPowerOf2_32):
+        (CountLeadingZeros_32):
+        (CountLeadingOnes_32):
+        (CountLeadingZeros_64):
+        (CountLeadingOnes_64):
+        (CountTrailingZeros_32):
+        (CountTrailingOnes_32):
+        (CountTrailingZeros_64):
+        (CountTrailingOnes_64):
+        (CountPopulation_32):
+        (CountPopulation_64):
+        (Log2_32):
+        (Log2_64):
+        (Log2_32_Ceil):
+        (Log2_64_Ceil):
+        (GreatestCommonDivisor64):
+        (BitsToDouble):
+        (BitsToFloat):
+        (DoubleToBits):
+        (FloatToBits):
+        (MinAlign):
+        (NextPowerOf2):
+        (RoundUpToAlignment):
+        (OffsetToAlignment):
+        (abs64):
+        (SignExtend32):
+        (SignExtend64):
+        (countLeadingZeros):
+        * capstone/Source/README.md: Added.
+        * capstone/Source/RELEASE_NOTES: Added.
+        * capstone/Source/SStream.c: Added.
+        (SStream_Init):
+        (SStream_concat0):
+        (SStream_concat):
+        (printInt64Bang):
+        (printUInt64Bang):
+        (printInt64):
+        (printInt32BangDec):
+        (printInt32Bang):
+        (printInt32):
+        (printUInt32Bang):
+        (printUInt32):
+        * capstone/Source/SStream.h: Added.
+        * capstone/Source/TODO: Added.
+        * capstone/Source/arch/ARM/ARMAddressingModes.h: Added.
+        (ARM_AM_getAddrOpcStr):
+        (ARM_AM_getShiftOpcStr):
+        (ARM_AM_getShiftOpcEncoding):
+        (ARM_AM_getAMSubModeStr):
+        (rotr32):
+        (rotl32):
+        (getSORegOpc):
+        (getSORegOffset):
+        (ARM_AM_getSORegShOp):
+        (getSOImmValImm):
+        (getSOImmValRot):
+        (getSOImmValRotate):
+        (getSOImmVal):
+        (isSOImmTwoPartVal):
+        (getSOImmTwoPartFirst):
+        (getSOImmTwoPartSecond):
+        (getThumbImmValShift):
+        (isThumbImmShiftedVal):
+        (getThumbImm16ValShift):
+        (isThumbImm16ShiftedVal):
+        (getThumbImmNonShiftedVal):
+        (getT2SOImmValSplatVal):
+        (getT2SOImmValRotateVal):
+        (getT2SOImmVal):
+        (getT2SOImmValRotate):
+        (isT2SOImmTwoPartVal):
+        (getT2SOImmTwoPartFirst):
+        (getT2SOImmTwoPartSecond):
+        (ARM_AM_getAM2Opc):
+        (getAM2Offset):
+        (getAM2Op):
+        (getAM2ShiftOpc):
+        (getAM2IdxMode):
+        (getAM3Opc):
+        (getAM3Offset):
+        (getAM3Op):
+        (getAM3IdxMode):
+        (getAM4SubMode):
+        (getAM4ModeImm):
+        (ARM_AM_getAM5Opc):
+        (ARM_AM_getAM5Offset):
+        (ARM_AM_getAM5Op):
+        (createNEONModImm):
+        (getNEONModImmOpCmode):
+        (getNEONModImmVal):
+        (ARM_AM_decodeNEONModImm):
+        (getFPImmFloat):
+        * capstone/Source/arch/ARM/ARMBaseInfo.h: Added.
+        (ARMCC_getOppositeCondition):
+        (ARMCC_ARMCondCodeToString):
+        (ARM_PROC_IFlagsToString):
+        (ARM_PROC_IModToString):
+        (ARM_MB_MemBOptToString):
+        (ARM_ISB_InstSyncBOptToString):
+        (isARMLowRegister):
+        (ARMII_AddrModeToString):
+        * capstone/Source/arch/ARM/ARMDisassembler.c: Added.
+        (ITStatus_push_back):
+        (ITStatus_instrInITBlock):
+        (ITStatus_instrLastInITBlock):
+        (ITStatus_getITCC):
+        (ITStatus_advanceITState):
+        (ITStatus_setITState):
+        (Check):
+        (ARM_getFeatureBits):
+        (DecodePredicateOperand):
+        (ARM_init):
+        (checkDecodedInstruction):
+        (_ARM_getInstruction):
+        (AddThumb1SBit):
+        (AddThumbPredicate):
+        (UpdateThumbVFPPredicate):
+        (_Thumb_getInstruction):
+        (Thumb_getInstruction):
+        (ARM_getInstruction):
+        (DecodeGPRnopcRegisterClass):
+        (DecodeGPRwithAPSRRegisterClass):
+        (DecodetGPRRegisterClass):
+        (DecodetcGPRRegisterClass):
+        (DecoderGPRRegisterClass):
+        (DecodeDPRRegisterClass):
+        (DecodeDPR_8RegisterClass):
+        (DecodeDPR_VFP2RegisterClass):
+        (DecodeDPairRegisterClass):
+        (DecodeCCOutOperand):
+        (DecodeSORegImmOperand):
+        (DecodeSORegRegOperand):
+        (DecodeRegListOperand):
+        (DecodeSPRRegListOperand):
+        (DecodeDPRRegListOperand):
+        (DecodeBitfieldMaskOperand):
+        (DecodeCopMemInstruction):
+        (DecodeAddrMode2IdxInstruction):
+        (DecodeSORegMemOperand):
+        (DecodeAddrMode3Instruction):
+        (DecodeRFEInstruction):
+        (DecodeQADDInstruction):
+        (DecodeMemMultipleWritebackInstruction):
+        (DecodeCPSInstruction):
+        (DecodeT2CPSInstruction):
+        (DecodeT2MOVTWInstruction):
+        (DecodeArmMOVTWInstruction):
+        (DecodeSMLAInstruction):
+        (DecodeAddrModeImm12Operand):
+        (DecodeAddrMode5Operand):
+        (DecodeAddrMode7Operand):
+        (DecodeT2BInstruction):
+        (DecodeBranchImmInstruction):
+        (DecodeAddrMode6Operand):
+        (DecodeVLDInstruction):
+        (DecodeVLDST1Instruction):
+        (DecodeVLDST2Instruction):
+        (DecodeVLDST3Instruction):
+        (DecodeVLDST4Instruction):
+        (DecodeVSTInstruction):
+        (DecodeVLD1DupInstruction):
+        (DecodeVLD2DupInstruction):
+        (DecodeVLD3DupInstruction):
+        (DecodeVLD4DupInstruction):
+        (DecodeNEONModImmInstruction):
+        (DecodeVSHLMaxInstruction):
+        (DecodeShiftRight8Imm):
+        (DecodeShiftRight16Imm):
+        (DecodeShiftRight32Imm):
+        (DecodeShiftRight64Imm):
+        (DecodeTBLInstruction):
+        (DecodeThumbAddSpecialReg):
+        (DecodeThumbBROperand):
+        (DecodeT2BROperand):
+        (DecodeThumbCmpBROperand):
+        (DecodeThumbAddrModeRR):
+        (DecodeThumbAddrModeIS):
+        (DecodeThumbAddrModePC):
+        (DecodeThumbAddrModeSP):
+        (DecodeT2AddrModeSOReg):
+        (DecodeT2LoadShift):
+        (DecodeT2LoadImm8):
+        (DecodeT2LoadImm12):
+        (DecodeT2LoadT):
+        (DecodeT2LoadLabel):
+        (DecodeT2Imm8S4):
+        (DecodeT2AddrModeImm8s4):
+        (DecodeT2AddrModeImm0_1020s4):
+        (DecodeT2Imm8):
+        (DecodeT2AddrModeImm8):
+        (DecodeT2LdStPre):
+        (DecodeT2AddrModeImm12):
+        (DecodeThumbAddSPImm):
+        (DecodeThumbAddSPReg):
+        (DecodeThumbCPS):
+        (DecodePostIdxReg):
+        (DecodeThumbBLXOffset):
+        (DecodeCoprocessor):
+        (DecodeThumbTableBranch):
+        (DecodeThumb2BCCInstruction):
+        (DecodeT2SOImm):
+        (DecodeThumbBCCTargetOperand):
+        (DecodeThumbBLTargetOperand):
+        (DecodeMemBarrierOption):
+        (DecodeInstSyncBarrierOption):
+        (DecodeMSRMask):
+        (DecodeBankedReg):
+        (DecodeDoubleRegLoad):
+        (DecodeDoubleRegStore):
+        (DecodeLDRPreImm):
+        (DecodeLDRPreReg):
+        (DecodeSTRPreImm):
+        (DecodeSTRPreReg):
+        (DecodeVLD1LN):
+        (DecodeVST1LN):
+        (DecodeVLD2LN):
+        (DecodeVST2LN):
+        (DecodeVLD3LN):
+        (DecodeVST3LN):
+        (DecodeVLD4LN):
+        (DecodeVST4LN):
+        (DecodeVMOVSRR):
+        (DecodeVMOVRRS):
+        (DecodeIT):
+        (DecodeT2LDRDPreInstruction):
+        (DecodeT2STRDPreInstruction):
+        (DecodeT2Adr):
+        (DecodeT2ShifterImmOperand):
+        (DecodeSwap):
+        (DecodeVCVTD):
+        (DecodeVCVTQ):
+        (DecodeLDR):
+        (DecodeMRRC2):
+        * capstone/Source/arch/ARM/ARMDisassembler.h: Added.
+        * capstone/Source/arch/ARM/ARMGenAsmWriter.inc: Added.
+        * capstone/Source/arch/ARM/ARMGenDisassemblerTables.inc: Added.
+        * capstone/Source/arch/ARM/ARMGenInstrInfo.inc: Added.
+        * capstone/Source/arch/ARM/ARMGenRegisterInfo.inc: Added.
+        * capstone/Source/arch/ARM/ARMGenSubtargetInfo.inc: Added.
+        * capstone/Source/arch/ARM/ARMInstPrinter.c: Added.
+        (get_op_access):
+        (set_mem_access):
+        (op_addImm):
+        (ARM_getRegName):
+        (translateShiftImm):
+        (printRegImmShift):
+        (printRegName):
+        (ARM_printInst):
+        (printOperand):
+        (printThumbLdrLabelOperand):
+        (printSORegRegOperand):
+        (printSORegImmOperand):
+        (printAM2PreOrOffsetIndexOp):
+        (printAddrModeTBB):
+        (printAddrModeTBH):
+        (printAddrMode2Operand):
+        (printAddrMode2OffsetOperand):
+        (printAM3PreOrOffsetIndexOp):
+        (printAddrMode3Operand):
+        (printAddrMode3OffsetOperand):
+        (printPostIdxImm8Operand):
+        (printPostIdxRegOperand):
+        (printPostIdxImm8s4Operand):
+        (printAddrMode5Operand):
+        (printAddrMode6Operand):
+        (printAddrMode7Operand):
+        (printAddrMode6OffsetOperand):
+        (printBitfieldInvMaskImmOperand):
+        (printMemBOption):
+        (printInstSyncBOption):
+        (printShiftImmOperand):
+        (printPKHLSLShiftImm):
+        (printPKHASRShiftImm):
+        (printRegisterList):
+        (printGPRPairOperand):
+        (printSetendOperand):
+        (printCPSIMod):
+        (printCPSIFlag):
+        (printMSRMaskOperand):
+        (printBankedRegOperand):
+        (printPredicateOperand):
+        (printMandatoryPredicateOperand):
+        (printSBitModifierOperand):
+        (printNoHashImmediate):
+        (printPImmediate):
+        (printCImmediate):
+        (printCoprocOptionImm):
+        (printAdrLabelOperand):
+        (printThumbS4ImmOperand):
+        (printThumbSRImm):
+        (printThumbITMask):
+        (printThumbAddrModeRROperand):
+        (printThumbAddrModeImm5SOperand):
+        (printThumbAddrModeImm5S1Operand):
+        (printThumbAddrModeImm5S2Operand):
+        (printThumbAddrModeImm5S4Operand):
+        (printThumbAddrModeSPOperand):
+        (printT2SOOperand):
+        (printAddrModeImm12Operand):
+        (printT2AddrModeImm8Operand):
+        (printT2AddrModeImm8s4Operand):
+        (printT2AddrModeImm0_1020s4Operand):
+        (printT2AddrModeImm8OffsetOperand):
+        (printT2AddrModeImm8s4OffsetOperand):
+        (printT2AddrModeSoRegOperand):
+        (printFPImmOperand):
+        (printNEONModImmOperand):
+        (printImmPlusOneOperand):
+        (printRotImmOperand):
+        (printModImmOperand):
+        (printFBits16):
+        (printFBits32):
+        (printVectorIndex):
+        (printVectorListOne):
+        (printVectorListTwo):
+        (printVectorListTwoSpaced):
+        (printVectorListThree):
+        (printVectorListFour):
+        (printVectorListOneAllLanes):
+        (printVectorListTwoAllLanes):
+        (printVectorListThreeAllLanes):
+        (printVectorListFourAllLanes):
+        (printVectorListTwoSpacedAllLanes):
+        (printVectorListThreeSpacedAllLanes):
+        (printVectorListFourSpacedAllLanes):
+        (printVectorListThreeSpaced):
+        (printVectorListFourSpaced):
+        (ARM_addVectorDataType):
+        (ARM_addVectorDataSize):
+        (ARM_addReg):
+        (ARM_addUserMode):
+        (ARM_addSysReg):
+        * capstone/Source/arch/ARM/ARMInstPrinter.h: Added.
+        * capstone/Source/arch/ARM/ARMMapping.c: Added.
+        (ARM_reg_name2):
+        (ARM_insn_name):
+        (ARM_rel_branch):
+        (ARM_blx_to_arm_mode):
+        (ARM_reg_access):
+        * capstone/Source/arch/ARM/ARMMapping.h: Added.
+        * capstone/Source/arch/ARM/ARMMappingInsn.inc: Added.
+        * capstone/Source/arch/ARM/ARMMappingInsnOp.inc: Added.
+        * capstone/Source/arch/ARM/ARMModule.c: Added.
+        (init):
+        (option):
+        (ARM_enable):
+        * capstone/Source/arch/Mips/MipsDisassembler.c: Added.
+        (getFeatureBits):
+        (Mips_init):
+        (readInstruction16):
+        (readInstruction32):
+        (MipsDisassembler_getInstruction):
+        (Mips_getInstruction):
+        (getReg):
+        (DecodeINSVE_DF_4):
+        (DecodeAddiGroupBranch_4):
+        (DecodeDaddiGroupBranch_4):
+        (DecodeBlezlGroupBranch_4):
+        (DecodeBgtzlGroupBranch_4):
+        (DecodeBgtzGroupBranch_4):
+        (DecodeBlezGroupBranch_4):
+        (DecodeCPU16RegsRegisterClass):
+        (DecodeGPR64RegisterClass):
+        (DecodeGPRMM16RegisterClass):
+        (DecodeGPRMM16ZeroRegisterClass):
+        (DecodeGPRMM16MovePRegisterClass):
+        (DecodeGPR32RegisterClass):
+        (DecodePtrRegisterClass):
+        (DecodeDSPRRegisterClass):
+        (DecodeFGR64RegisterClass):
+        (DecodeFGR32RegisterClass):
+        (DecodeCCRRegisterClass):
+        (DecodeFCCRegisterClass):
+        (DecodeCCRegisterClass):
+        (DecodeFGRCCRegisterClass):
+        (DecodeMem):
+        (DecodeCacheOp):
+        (DecodeCacheOpMM):
+        (DecodeCacheOpR6):
+        (DecodeSyncI):
+        (DecodeMSA128Mem):
+        (DecodeMemMMImm4):
+        (DecodeMemMMSPImm5Lsl2):
+        (DecodeMemMMGPImm7Lsl2):
+        (DecodeMemMMReglistImm4Lsl2):
+        (DecodeMemMMImm12):
+        (DecodeMemMMImm16):
+        (DecodeFMem):
+        (DecodeFMem2):
+        (DecodeFMem3):
+        (DecodeFMemCop2R6):
+        (DecodeSpecial3LlSc):
+        (DecodeHWRegsRegisterClass):
+        (DecodeAFGR64RegisterClass):
+        (DecodeACC64DSPRegisterClass):
+        (DecodeHI32DSPRegisterClass):
+        (DecodeLO32DSPRegisterClass):
+        (DecodeMSA128BRegisterClass):
+        (DecodeMSA128HRegisterClass):
+        (DecodeMSA128WRegisterClass):
+        (DecodeMSA128DRegisterClass):
+        (DecodeMSACtrlRegisterClass):
+        (DecodeCOP2RegisterClass):
+        (DecodeBranchTarget):
+        (DecodeJumpTarget):
+        (DecodeBranchTarget21):
+        (DecodeBranchTarget26):
+        (DecodeBranchTarget7MM):
+        (DecodeBranchTarget10MM):
+        (DecodeBranchTargetMM):
+        (DecodeJumpTargetMM):
+        (DecodeAddiur2Simm7):
+        (DecodeUImm6Lsl2):
+        (DecodeLiSimm7):
+        (DecodeSimm4):
+        (DecodeSimm16):
+        (DecodeLSAImm):
+        (DecodeInsSize):
+        (DecodeExtSize):
+        (DecodeSimm19Lsl2):
+        (DecodeSimm18Lsl3):
+        (DecodeSimm9SP):
+        (DecodeANDI16Imm):
+        (DecodeUImm5lsl2):
+        (DecodeRegListOperand):
+        (DecodeRegListOperand16):
+        (DecodeMovePRegPair):
+        (DecodeSimm23Lsl2):
+        * capstone/Source/arch/Mips/MipsDisassembler.h: Added.
+        * capstone/Source/arch/Mips/MipsGenAsmWriter.inc: Added.
+        * capstone/Source/arch/Mips/MipsGenDisassemblerTables.inc: Added.
+        * capstone/Source/arch/Mips/MipsGenInstrInfo.inc: Added.
+        * capstone/Source/arch/Mips/MipsGenRegisterInfo.inc: Added.
+        * capstone/Source/arch/Mips/MipsGenSubtargetInfo.inc: Added.
+        * capstone/Source/arch/Mips/MipsInstPrinter.c: Added.
+        (set_mem_access):
+        (isReg):
+        (MipsFCCToString):
+        (printRegName):
+        (Mips_printInst):
+        (printOperand):
+        (printUnsignedImm):
+        (printUnsignedImm8):
+        (printMemOperand):
+        (printMemOperandEA):
+        (printFCCOperand):
+        (printRegisterPair):
+        (printAlias1):
+        (printAlias2):
+        (printAlias):
+        (printRegisterList):
+        * capstone/Source/arch/Mips/MipsInstPrinter.h: Added.
+        * capstone/Source/arch/Mips/MipsMapping.c: Added.
+        (Mips_get_insn_id):
+        (Mips_group_name):
+        (Mips_map_insn):
+        (Mips_map_register):
+        * capstone/Source/arch/Mips/MipsMapping.h: Added.
+        * capstone/Source/arch/Mips/MipsMappingInsn.inc: Added.
+        * capstone/Source/arch/Mips/MipsModule.c: Added.
+        (init):
+        (option):
+        (Mips_enable):
+        * capstone/Source/capstone.pc.in: Added.
+        * capstone/Source/config.mk: Added.
+        * capstone/Source/cs.c: Added.
+        (cs_kern_os_calloc):
+        (cs_version):
+        (cs_support):
+        (cs_errno):
+        (cs_strerror):
+        (cs_open):
+        (cs_close):
+        (fill_insn):
+        (skipdata_size):
+        (cs_option):
+        (skipdata_opstr):
+        (cs_disasm):
+        (cs_disasm_ex):
+        (cs_free):
+        (cs_malloc):
+        (cs_disasm_iter):
+        (cs_reg_name):
+        (cs_insn_name):
+        (cs_group_name):
+        (cs_insn_group):
+        (cs_reg_read):
+        (cs_reg_write):
+        (cs_op_count):
+        (cs_op_index):
+        (cs_regs_access):
+        * capstone/Source/cs_priv.h: Added.
+        * capstone/Source/functions.mk: Added.
+        * capstone/Source/include/capstone/arm.h: Added.
+        * capstone/Source/include/capstone/arm64.h: Added.
+        * capstone/Source/include/capstone/capstone.h: Added.
+        * capstone/Source/include/capstone/evm.h: Added.
+        * capstone/Source/include/capstone/m680x.h: Added.
+        * capstone/Source/include/capstone/m68k.h: Added.
+        * capstone/Source/include/capstone/mips.h: Added.
+        * capstone/Source/include/capstone/platform.h: Added.
+        * capstone/Source/include/capstone/ppc.h: Added.
+        * capstone/Source/include/capstone/sparc.h: Added.
+        * capstone/Source/include/capstone/systemz.h: Added.
+        * capstone/Source/include/capstone/tms320c64x.h: Added.
+        * capstone/Source/include/capstone/x86.h: Added.
+        * capstone/Source/include/capstone/xcore.h: Added.
+        * capstone/Source/include/windowsce/intrin.h: Added.
+        * capstone/Source/include/windowsce/stdint.h: Added.
+        * capstone/Source/make.sh: Added.
+        * capstone/Source/nmake-x86.bat: Added.
+        * capstone/Source/nmake.bat: Added.
+        * capstone/Source/pkgconfig.mk: Added.
+        * capstone/Source/utils.c: Added.
+        (make_id2insn):
+        (insn_find):
+        (name2id):
+        (id2name):
+        (count_positive):
+        (count_positive8):
+        (cs_strdup):
+        (cs_snprintf):
+        (arr_exist8):
+        (arr_exist):
+        * capstone/Source/utils.h: Added.
+        * capstone/capstone-Revision.txt: Added.
+
 2018-03-05  Don Olmstead  <don.olmstead@sony.com>
 
         [CMake] Split JSC header copying into public and private targets
diff --git a/Source/ThirdParty/capstone/CMakeLists.txt b/Source/ThirdParty/capstone/CMakeLists.txt
new file mode 100644 (file)
index 0000000..06fc06a
--- /dev/null
@@ -0,0 +1,121 @@
+add_definitions(-DCAPSTONE_USE_SYS_DYN_MEM)
+
+## sources
+set(SOURCES_ENGINE
+    Source/cs.c
+    Source/MCInst.c
+    Source/MCInstrDesc.c
+    Source/MCRegisterInfo.c
+    Source/SStream.c
+    Source/utils.c
+)
+set(HEADERS_ENGINE
+    Source/cs_priv.h
+    Source/LEB128.h
+    Source/MathExtras.h
+    Source/MCDisassembler.h
+    Source/MCFixedLenDisassembler.h
+    Source/MCInst.h
+    Source/MCInstrDesc.h
+    Source/MCRegisterInfo.h
+    Source/SStream.h
+    Source/utils.h
+    )
+
+set(HEADERS_COMMON
+    Source/include/capstone/arm64.h
+    Source/include/capstone/arm.h
+    Source/include/capstone/capstone.h
+    Source/include/capstone/mips.h
+    Source/include/capstone/ppc.h
+    Source/include/capstone/x86.h
+    Source/include/capstone/sparc.h
+    Source/include/capstone/systemz.h
+    Source/include/capstone/xcore.h
+    Source/include/capstone/m68k.h
+    Source/include/capstone/tms320c64x.h
+    Source/include/capstone/m680x.h
+    Source/include/capstone/platform.h
+    )
+
+
+## architecture support
+if (WTF_CPU_ARM)
+    add_definitions(-DCAPSTONE_HAS_ARM)
+    set(SOURCES_ARM
+        Source/arch/ARM/ARMDisassembler.c
+        Source/arch/ARM/ARMInstPrinter.c
+        Source/arch/ARM/ARMMapping.c
+        Source/arch/ARM/ARMModule.c
+    )
+    set(HEADERS_ARM
+        Source/arch/ARM/ARMAddressingModes.h
+        Source/arch/ARM/ARMBaseInfo.h
+        Source/arch/ARM/ARMDisassembler.h
+        Source/arch/ARM/ARMGenAsmWriter.inc
+        Source/arch/ARM/ARMGenDisassemblerTables.inc
+        Source/arch/ARM/ARMGenInstrInfo.inc
+        Source/arch/ARM/ARMGenRegisterInfo.inc
+        Source/arch/ARM/ARMGenSubtargetInfo.inc
+        Source/arch/ARM/ARMInstPrinter.h
+        Source/arch/ARM/ARMMapping.h
+        Source/arch/ARM/ARMMappingInsn.inc
+        Source/arch/ARM/ARMMappingInsnOp.inc
+        )
+endif ()
+
+if (WTF_CPU_MIPS)
+    add_definitions(-DCAPSTONE_HAS_MIPS)
+    set(SOURCES_MIPS
+        Source/arch/Mips/MipsDisassembler.c
+        Source/arch/Mips/MipsInstPrinter.c
+        Source/arch/Mips/MipsMapping.c
+        Source/arch/Mips/MipsModule.c
+    )
+    set(HEADERS_MIPS
+        Source/arch/Mips/MipsDisassembler.h
+        Source/arch/Mips/MipsGenAsmWriter.inc
+        Source/arch/Mips/MipsGenDisassemblerTables.inc
+        Source/arch/Mips/MipsGenInstrInfo.inc
+        Source/arch/Mips/MipsGenRegisterInfo.inc
+        Source/arch/Mips/MipsGenSubtargetInfo.inc
+        Source/arch/Mips/MipsInstPrinter.h
+        Source/arch/Mips/MipsMapping.h
+        Source/arch/Mips/MipsMappingInsn.inc
+        )
+endif ()
+
+set(capstone_SOURCES
+    ${SOURCES_ENGINE}
+    ${SOURCES_ARM}
+    ${SOURCES_ARM64}
+    ${SOURCES_MIPS}
+    ${SOURCES_X86}
+    )
+
+set(capstone_HEADERS
+    ${HEADERS_COMMON}
+    ${HEADERS_ENGINE}
+    ${HEADERS_ARM}
+    ${HEADERS_ARM64}
+    ${HEADERS_MIPS}
+    ${HEADERS_X86}
+    )
+
+set(capstone_INCLUDE_DIRECTORIES "${THIRDPARTY_DIR}/capstone/Source/include")
+
+## targets
+add_library(capstone STATIC ${capstone_SOURCES} ${capstone_HEADERS})
+set_property(TARGET capstone PROPERTY OUTPUT_NAME capstone)
+target_include_directories(capstone PRIVATE ${capstone_INCLUDE_DIRECTORIES})
+
+if (COMPILER_IS_GCC_OR_CLANG)
+    WEBKIT_ADD_TARGET_C_FLAGS(capstone
+        -Wno-sign-compare
+        -Wno-unused-parameter
+        -Wno-implicit-fallthrough
+        -Wno-missing-field-initializers
+        -Wno-missing-format-attribute
+        -Wno-discarded-qualifiers
+    )
+endif ()
diff --git a/Source/ThirdParty/capstone/Source/.appveyor.yml b/Source/ThirdParty/capstone/Source/.appveyor.yml
new file mode 100644 (file)
index 0000000..87b8bf4
--- /dev/null
@@ -0,0 +1,14 @@
+version: 4.0-{build}
+
+os:
+  - Visual Studio 2015
+
+before_build:
+  - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
+
+build_script:
+  - mkdir build
+  - cd build
+  - cmake -DCMAKE_BUILD_TYPE=RELEASE -G "NMake Makefiles" ..
+  - nmake
+
diff --git a/Source/ThirdParty/capstone/Source/.gitattributes b/Source/ThirdParty/capstone/Source/.gitattributes
new file mode 100644 (file)
index 0000000..03e638d
--- /dev/null
@@ -0,0 +1 @@
+/arch/**/*.inc linguist-language=C
diff --git a/Source/ThirdParty/capstone/Source/.gitignore b/Source/ThirdParty/capstone/Source/.gitignore
new file mode 100644 (file)
index 0000000..ec5bc8d
--- /dev/null
@@ -0,0 +1,111 @@
+.DS_Store
+
+# Object files
+*.o
+*.ko
+
+# Gcc dependency-tracking files
+*.d
+
+# Libraries
+*.lib
+*.a
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# python
+bindings/python/build/
+bindings/python/capstone.egg-info/
+*.pyc
+
+# java
+bindings/java/capstone.jar
+
+# ocaml
+bindings/ocaml/*.cmi
+bindings/ocaml/*.cmx
+bindings/ocaml/*.cmxa
+bindings/ocaml/*.mli
+bindings/ocaml/test
+bindings/ocaml/test_arm
+bindings/ocaml/test_arm64
+bindings/ocaml/test_basic
+bindings/ocaml/test_mips
+bindings/ocaml/test_x86
+bindings/ocaml/test_detail
+bindings/ocaml/test_ppc
+bindings/ocaml/test_sparc
+bindings/ocaml/test_systemz
+bindings/ocaml/test_xcore
+bindings/ocaml/test_m680x
+
+
+# test binaries
+tests/test_basic
+tests/test_detail
+tests/test_iter
+tests/test_arm
+tests/test_arm64
+tests/test_mips
+tests/test_x86
+tests/test_ppc
+tests/test_skipdata
+tests/test_sparc
+tests/test_systemz
+tests/test_xcore
+tests/*.static
+tests/test_customized_mnem
+tests/test_m68k
+tests/test_tms320c64x
+tests/test_m680x
+tests/test_evm
+
+# vim tmp file
+*.swp
+*~
+
+capstone.pc
+
+# local files
+_*
+
+# freebsd ports: generated file with "make makesum" command
+packages/freebsd/ports/devel/capstone/distinfo
+
+# VisualStudio
+ProjectUpgradeLog.log
+Debug/
+Release/
+ipch/
+build*/
+*.sdf
+*.opensdf
+*.suo
+*.user
+*.backup
+*.VC.db
+*.VC.opendb
+
+# Xcode
+xcode/Capstone.xcodeproj/xcuserdata
+xcode/Capstone.xcodeproj/project.xcworkspace/xcuserdata
+
+# suite/
+test_arm_regression
+test_arm_regression.o
+fuzz_harness
+test_iter_benchmark
+
+
+*.s
+
+cstool/cstool
diff --git a/Source/ThirdParty/capstone/Source/.travis.yml b/Source/ThirdParty/capstone/Source/.travis.yml
new file mode 100644 (file)
index 0000000..aa8f5a1
--- /dev/null
@@ -0,0 +1,16 @@
+language: cpp
+sudo: false
+before_install:
+        - export LD_LIBRARY_PATH=`pwd`/tests/:$LD_LIBRARY_PATH
+script:
+        - ./make.sh
+        - make check
+        - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cp libcapstone.so.* bindings/python/libcapstone.so; fi
+        - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cp libcapstone.*.dylib bindings/python/libcapstone.dylib; fi
+        - cd bindings/python && make check
+compiler:
+        - clang
+        - gcc
+os:
+        - linux
+        - osx
diff --git a/Source/ThirdParty/capstone/Source/CMakeLists.txt b/Source/ThirdParty/capstone/Source/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8488466
--- /dev/null
@@ -0,0 +1,550 @@
+cmake_minimum_required(VERSION 2.6)
+project(capstone)
+
+set(VERSION_MAJOR 4)
+set(VERSION_MINOR 0)
+set(VERSION_PATCH 0)
+
+if(POLICY CMP0042)
+  # http://www.cmake.org/cmake/help/v3.0/policy/CMP0042.html
+  cmake_policy(SET CMP0042 NEW)
+endif(POLICY CMP0042)
+
+if (POLICY CMP0048)
+  # use old policy to honor version set using VERSION_* variables to preserve backwards
+  # compatibility. change OLD to NEW when minimum cmake version is updated to 3.* and
+  # set VERSION using project(capstone VERSION 4.0.0).
+  # http://www.cmake.org/cmake/help/v3.0/policy/CMP0048.html
+  cmake_policy (SET CMP0048 OLD)
+endif()
+
+# to configure the options specify them in in the command line or change them in the cmake UI.
+# Don't edit the makefile!
+option(CAPSTONE_BUILD_STATIC_RUNTIME "Embed static runtime" ON)
+option(CAPSTONE_BUILD_STATIC "Build static library" ON)
+option(CAPSTONE_BUILD_SHARED "Build shared library" ON)
+option(CAPSTONE_BUILD_DIET "Build diet library" OFF)
+option(CAPSTONE_BUILD_TESTS "Build tests" ON)
+option(CAPSTONE_BUILD_CSTOOL "Build cstool" ON)
+option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON)
+
+set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM)
+set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM)
+
+list(LENGTH SUPPORTED_ARCHITECTURES count)
+math(EXPR count "${count}-1")
+# create options controlling whether support for a particular architecture is needed
+foreach(i RANGE ${count})
+  list(GET SUPPORTED_ARCHITECTURES ${i} supported_architecture)
+  list(GET SUPPORTED_ARCHITECTURE_LABELS ${i} supported_architecture_label)
+  option("CAPSTONE_${supported_architecture}_SUPPORT" "${supported_architecture_label} support" ON)
+endforeach(i)
+
+# propagate achitecture support variables to preprocessor
+foreach(supported_architecture ${SUPPORTED_ARCHITECTURES})
+  set(option_name "CAPSTONE_${supported_architecture}_SUPPORT")
+  if(${option_name})
+    message("Enabling ${option_name}")
+    add_definitions("-D${option_name}")
+  endif()
+endforeach(supported_architecture)
+
+option(CAPSTONE_X86_REDUCE "x86 with reduce instruction sets to minimize library" OFF)
+option(CAPSTONE_X86_ATT_DISABLE "Disable x86 AT&T syntax" OFF)
+option(CAPSTONE_OSXKERNEL_SUPPORT "Support to embed Capstone into OS X Kernel extensions" OFF)
+
+if (MSVC)
+    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
+    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
+endif ()
+
+enable_testing()
+
+if (CAPSTONE_BUILD_DIET)
+    add_definitions(-DCAPSTONE_DIET)
+endif ()
+
+if (CAPSTONE_USE_DEFAULT_ALLOC)
+    add_definitions(-DCAPSTONE_USE_SYS_DYN_MEM)
+endif ()
+
+if (CAPSTONE_X86_REDUCE)
+    add_definitions(-DCAPSTONE_X86_REDUCE)
+endif ()
+
+if (CAPSTONE_X86_ATT_DISABLE)
+    add_definitions(-DCAPSTONE_X86_ATT_DISABLE)
+endif ()
+
+## sources
+set(SOURCES_ENGINE
+    cs.c
+    MCInst.c
+    MCInstrDesc.c
+    MCRegisterInfo.c
+    SStream.c
+    utils.c
+)
+set(HEADERS_ENGINE
+    cs_priv.h
+    LEB128.h
+    MathExtras.h
+    MCDisassembler.h
+    MCFixedLenDisassembler.h
+    MCInst.h
+    MCInstrDesc.h
+    MCRegisterInfo.h
+    SStream.h
+    utils.h
+    )
+
+set(HEADERS_COMMON
+    include/capstone/arm64.h
+    include/capstone/arm.h
+    include/capstone/capstone.h
+    include/capstone/mips.h
+    include/capstone/ppc.h
+    include/capstone/x86.h
+    include/capstone/sparc.h
+    include/capstone/systemz.h
+    include/capstone/xcore.h
+    include/capstone/m68k.h
+    include/capstone/tms320c64x.h
+    include/capstone/m680x.h
+    include/capstone/platform.h
+    )
+
+
+set(TEST_SOURCES test_basic.c test_detail.c test_skipdata.c test_iter.c)
+
+## architecture support
+if (CAPSTONE_ARM_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_ARM)
+    set(SOURCES_ARM
+        arch/ARM/ARMDisassembler.c
+        arch/ARM/ARMInstPrinter.c
+        arch/ARM/ARMMapping.c
+        arch/ARM/ARMModule.c
+    )
+    set(HEADERS_ARM
+        arch/ARM/ARMAddressingModes.h
+        arch/ARM/ARMBaseInfo.h
+        arch/ARM/ARMDisassembler.h
+        arch/ARM/ARMGenAsmWriter.inc
+        arch/ARM/ARMGenDisassemblerTables.inc
+        arch/ARM/ARMGenInstrInfo.inc
+        arch/ARM/ARMGenRegisterInfo.inc
+        arch/ARM/ARMGenSubtargetInfo.inc
+        arch/ARM/ARMInstPrinter.h
+        arch/ARM/ARMMapping.h
+        arch/ARM/ARMMappingInsn.inc
+        arch/ARM/ARMMappingInsnOp.inc
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_arm.c)
+endif ()
+
+if (CAPSTONE_ARM64_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_ARM64)
+    set(SOURCES_ARM64
+        arch/AArch64/AArch64BaseInfo.c
+        arch/AArch64/AArch64Disassembler.c
+        arch/AArch64/AArch64InstPrinter.c
+        arch/AArch64/AArch64Mapping.c
+        arch/AArch64/AArch64Module.c
+    )
+    set(HEADERS_ARM64
+        arch/AArch64/AArch64AddressingModes.h
+        arch/AArch64/AArch64BaseInfo.h
+        arch/AArch64/AArch64Disassembler.h
+        arch/AArch64/AArch64GenAsmWriter.inc
+        arch/AArch64/AArch64GenDisassemblerTables.inc
+        arch/AArch64/AArch64GenInstrInfo.inc
+        arch/AArch64/AArch64GenRegisterInfo.inc
+        arch/AArch64/AArch64GenSubtargetInfo.inc
+        arch/AArch64/AArch64InstPrinter.h
+        arch/AArch64/AArch64Mapping.h
+        arch/AArch64/AArch64MappingInsn.inc
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_arm64.c)
+endif ()
+
+if (CAPSTONE_MIPS_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_MIPS)
+    set(SOURCES_MIPS
+        arch/Mips/MipsDisassembler.c
+        arch/Mips/MipsInstPrinter.c
+        arch/Mips/MipsMapping.c
+        arch/Mips/MipsModule.c
+    )
+    set(HEADERS_MIPS
+        arch/Mips/MipsDisassembler.h
+        arch/Mips/MipsGenAsmWriter.inc
+        arch/Mips/MipsGenDisassemblerTables.inc
+        arch/Mips/MipsGenInstrInfo.inc
+        arch/Mips/MipsGenRegisterInfo.inc
+        arch/Mips/MipsGenSubtargetInfo.inc
+        arch/Mips/MipsInstPrinter.h
+        arch/Mips/MipsMapping.h
+        arch/Mips/MipsMappingInsn.inc
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_mips.c)
+endif ()
+
+if (CAPSTONE_PPC_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_POWERPC)
+    set(SOURCES_PPC
+        arch/PowerPC/PPCDisassembler.c
+        arch/PowerPC/PPCInstPrinter.c
+        arch/PowerPC/PPCMapping.c
+        arch/PowerPC/PPCModule.c
+    )
+    set(HEADERS_PPC
+        arch/PowerPC/PPCDisassembler.h
+        arch/PowerPC/PPCGenAsmWriter.inc
+        arch/PowerPC/PPCGenDisassemblerTables.inc
+        arch/PowerPC/PPCGenInstrInfo.inc
+        arch/PowerPC/PPCGenRegisterInfo.inc
+        arch/PowerPC/PPCGenSubtargetInfo.inc
+        arch/PowerPC/PPCInstPrinter.h
+        arch/PowerPC/PPCMapping.h
+        arch/PowerPC/PPCMappingInsn.inc
+        arch/PowerPC/PPCPredicates.h
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_ppc.c)
+endif ()
+
+if (CAPSTONE_X86_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_X86)
+    set(SOURCES_X86
+        arch/X86/X86Disassembler.c
+        arch/X86/X86DisassemblerDecoder.c
+        arch/X86/X86IntelInstPrinter.c
+        arch/X86/X86Mapping.c
+        arch/X86/X86Module.c
+    )
+    set(HEADERS_X86
+        arch/X86/X86BaseInfo.h
+        arch/X86/X86Disassembler.h
+        arch/X86/X86DisassemblerDecoder.h
+        arch/X86/X86DisassemblerDecoderCommon.h
+        arch/X86/X86GenAsmWriter.inc
+        arch/X86/X86GenAsmWriter1.inc
+        arch/X86/X86GenAsmWriter1_reduce.inc
+        arch/X86/X86GenAsmWriter_reduce.inc
+        arch/X86/X86GenDisassemblerTables.inc
+        arch/X86/X86GenDisassemblerTables_reduce.inc
+        arch/X86/X86GenInstrInfo.inc
+        arch/X86/X86GenInstrInfo_reduce.inc
+        arch/X86/X86GenRegisterInfo.inc
+        arch/X86/X86InstPrinter.h
+        arch/X86/X86Mapping.h
+        arch/X86/X86MappingInsn.inc
+        arch/X86/X86MappingInsnOp.inc
+        arch/X86/X86MappingInsnOp_reduce.inc
+        arch/X86/X86MappingInsn_reduce.inc
+        )
+    if (NOT CAPSTONE_BUILD_DIET)
+        set(SOURCES_X86 ${SOURCES_X86} arch/X86/X86ATTInstPrinter.c)
+    endif ()
+    set(TEST_SOURCES ${TEST_SOURCES} test_x86.c test_customized_mnem.c)
+endif ()
+
+if (CAPSTONE_SPARC_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_SPARC)
+    set(SOURCES_SPARC
+        arch/Sparc/SparcDisassembler.c
+        arch/Sparc/SparcInstPrinter.c
+        arch/Sparc/SparcMapping.c
+        arch/Sparc/SparcModule.c
+    )
+    set(HEADERS_SPARC
+        arch/Sparc/Sparc.h
+        arch/Sparc/SparcDisassembler.h
+        arch/Sparc/SparcGenAsmWriter.inc
+        arch/Sparc/SparcGenDisassemblerTables.inc
+        arch/Sparc/SparcGenInstrInfo.inc
+        arch/Sparc/SparcGenRegisterInfo.inc
+        arch/Sparc/SparcGenSubtargetInfo.inc
+        arch/Sparc/SparcInstPrinter.h
+        arch/Sparc/SparcMapping.h
+        arch/Sparc/SparcMappingInsn.inc
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_sparc.c)
+endif ()
+
+if (CAPSTONE_SYSZ_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_SYSZ)
+    set(SOURCES_SYSZ
+        arch/SystemZ/SystemZDisassembler.c
+        arch/SystemZ/SystemZInstPrinter.c
+        arch/SystemZ/SystemZMapping.c
+        arch/SystemZ/SystemZMCTargetDesc.c
+        arch/SystemZ/SystemZModule.c
+    )
+    set(HEADERS_SYSZ
+        arch/SystemZ/SystemZDisassembler.h
+        arch/SystemZ/SystemZGenAsmWriter.inc
+        arch/SystemZ/SystemZGenDisassemblerTables.inc
+        arch/SystemZ/SystemZGenInstrInfo.inc
+        arch/SystemZ/SystemZGenRegisterInfo.inc
+        arch/SystemZ/SystemZGenSubtargetInfo.inc
+        arch/SystemZ/SystemZInstPrinter.h
+        arch/SystemZ/SystemZMapping.h
+        arch/SystemZ/SystemZMappingInsn.inc
+        arch/SystemZ/SystemZMCTargetDesc.h
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_systemz.c)
+endif ()
+
+if (CAPSTONE_XCORE_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_XCORE)
+    set(SOURCES_XCORE
+        arch/XCore/XCoreDisassembler.c
+        arch/XCore/XCoreInstPrinter.c
+        arch/XCore/XCoreMapping.c
+        arch/XCore/XCoreModule.c
+    )
+    set(HEADERS_XCORE
+        arch/XCore/XCoreDisassembler.h
+        arch/XCore/XCoreGenAsmWriter.inc
+        arch/XCore/XCoreGenDisassemblerTables.inc
+        arch/XCore/XCoreGenInstrInfo.inc
+        arch/XCore/XCoreGenRegisterInfo.inc
+        arch/XCore/XCoreInstPrinter.h
+        arch/XCore/XCoreMapping.h
+        arch/XCore/XCoreMappingInsn.inc
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_xcore.c)
+endif ()
+
+if (CAPSTONE_M68K_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_M68K)
+    set(SOURCES_M68K
+               arch/M68K/M68KDisassembler.c
+               arch/M68K/M68KInstPrinter.c
+               arch/M68K/M68KModule.c
+    )
+    set(HEADERS_M68K
+               arch/M68K/M68KDisassembler.h
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_m68k.c)
+endif ()
+
+if (CAPSTONE_TMS320C64X_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_TMS320C64X)
+    set(SOURCES_TMS320C64X
+        arch/TMS320C64x/TMS320C64xDisassembler.c
+        arch/TMS320C64x/TMS320C64xInstPrinter.c
+        arch/TMS320C64x/TMS320C64xMapping.c
+        arch/TMS320C64x/TMS320C64xModule.c
+        )
+    set(HEADERS_TMS320C64X
+        arch/TMS320C64x/TMS320C64xDisassembler.h
+        arch/TMS320C64x/TMS320C64xGenAsmWriter.inc
+        arch/TMS320C64x/TMS320C64xGenDisassemblerTables.inc
+        arch/TMS320C64x/TMS320C64xGenInstrInfo.inc
+        arch/TMS320C64x/TMS320C64xGenRegisterInfo.inc
+        arch/TMS320C64x/TMS320C64xInstPrinter.h
+        arch/TMS320C64x/TMS320C64xMapping.h
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_tms320c64x.c)
+endif ()
+
+if (CAPSTONE_M680X_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_M680X)
+    set(SOURCES_M680X
+               arch/M680X/M680XDisassembler.c
+               arch/M680X/M680XInstPrinter.c
+               arch/M680X/M680XModule.c
+    )
+    set(HEADERS_M680X
+               arch/M680X/M680XInstPrinter.h
+               arch/M680X/M680XDisassembler.h
+               arch/M680X/M680XDisassemblerInternals.h
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_m680x.c)
+endif ()
+
+if (CAPSTONE_EVM_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_EVM)
+    set(SOURCES_EVM
+        arch/EVM/EVMDisassembler.c
+        arch/EVM/EVMInstPrinter.c
+        arch/EVM/EVMMapping.c
+        arch/EVM/EVMModule.c
+    )
+    set(HEADERS_EVM
+        arch/EVM/EVMDisassembler.h
+        arch/EVM/EVMInstPrinter.h
+        arch/EVM/EVMMapping.h
+        arch/EVM/EVMMappingInsn.inc
+        )
+    set(TEST_SOURCES ${TEST_SOURCES} test_evm.c)
+endif ()
+
+if (CAPSTONE_OSXKERNEL_SUPPORT)
+    add_definitions(-DCAPSTONE_HAS_OSXKERNEL)
+endif ()
+
+set(ALL_SOURCES
+    ${SOURCES_ENGINE}
+    ${SOURCES_ARM}
+    ${SOURCES_ARM64}
+    ${SOURCES_MIPS}
+    ${SOURCES_PPC}
+    ${SOURCES_X86}
+    ${SOURCES_SPARC}
+    ${SOURCES_SYSZ}
+    ${SOURCES_XCORE}
+    ${SOURCES_M68K}
+    ${SOURCES_TMS320C64X}
+    ${SOURCES_M680X}
+    ${SOURCES_EVM}
+    )
+
+set(ALL_HEADERS
+    ${HEADERS_COMMON}
+    ${HEADERS_ENGINE}
+    ${HEADERS_ARM}
+    ${HEADERS_ARM64}
+    ${HEADERS_MIPS}
+    ${HEADERS_PPC}
+    ${HEADERS_X86}
+    ${HEADERS_SPARC}
+    ${HEADERS_SYSZ}
+    ${HEADERS_XCORE}
+    ${HEADERS_M68K}
+    ${HEADERS_TMS320C64X}
+    ${HEADERS_M680X}
+    ${HEADERS_EVM}
+    )
+
+include_directories("${PROJECT_SOURCE_DIR}/include")
+
+## properties
+# version info
+set_property(GLOBAL PROPERTY VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+
+## targets
+if (CAPSTONE_BUILD_STATIC)
+    add_library(capstone-static STATIC ${ALL_SOURCES} ${ALL_HEADERS})
+    set_property(TARGET capstone-static PROPERTY OUTPUT_NAME capstone)
+    set(default-target capstone-static)
+endif ()
+
+# Force static runtime libraries
+if (CAPSTONE_BUILD_STATIC_RUNTIME)
+    FOREACH(flag
+       CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
+       CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT
+       CMAKE_CXX_FLAGS_RELEASE  CMAKE_CXX_FLAGS_RELWITHDEBINFO
+       CMAKE_CXX_FLAGS_DEBUG  CMAKE_CXX_FLAGS_DEBUG_INIT)
+       if (MSVC)
+           STRING(REPLACE "/MD"  "/MT" "${flag}" "${${flag}}")
+           SET("${flag}" "${${flag}} /EHsc")
+       endif (MSVC)
+    ENDFOREACH()
+endif ()
+
+if (CAPSTONE_BUILD_SHARED)
+    add_library(capstone-shared SHARED ${ALL_SOURCES} ${ALL_HEADERS})
+    set_property(TARGET capstone-shared PROPERTY OUTPUT_NAME capstone)
+    set_property(TARGET capstone-shared PROPERTY COMPILE_FLAGS -DCAPSTONE_SHARED)
+
+    if (MSVC)
+        set_target_properties(capstone-shared PROPERTIES IMPORT_SUFFIX _dll.lib)
+    else()
+        set_target_properties(capstone-shared PROPERTIES
+           VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+           SOVERSION ${VERSION_MAJOR})
+    endif ()
+
+    if(NOT DEFINED default-target)      # honor `capstone-static` for tests first.
+       set(default-target capstone-shared)
+       add_definitions(-DCAPSTONE_SHARED)
+    endif ()
+endif ()
+
+if (CAPSTONE_BUILD_TESTS)
+    foreach (TSRC ${TEST_SOURCES})
+        STRING(REGEX REPLACE ".c$" "" TBIN ${TSRC})
+        add_executable(${TBIN} "tests/${TSRC}")
+        target_link_libraries(${TBIN} ${default-target})
+        add_test(NAME "capstone_${TBIN}" COMMAND ${TBIN})
+    endforeach ()
+    if (CAPSTONE_ARM_SUPPORT)
+        set(ARM_REGRESS_TEST test_arm_regression.c)
+        STRING(REGEX REPLACE ".c$" "" ARM_REGRESS_BIN ${ARM_REGRESS_TEST})
+        add_executable(${ARM_REGRESS_BIN} "suite/arm/${ARM_REGRESS_TEST}")
+        target_link_libraries(${ARM_REGRESS_BIN} ${default-target})
+        add_test(NAME "capstone_${ARM_REGRESS_BIN}" COMMAND ${ARM_REGRESS_BIN})
+    endif()
+endif ()
+
+source_group("Source\\Engine" FILES ${SOURCES_ENGINE})
+source_group("Source\\ARM" FILES ${SOURCES_ARM})
+source_group("Source\\ARM64" FILES ${SOURCES_ARM64})
+source_group("Source\\Mips" FILES ${SOURCES_MIPS})
+source_group("Source\\PowerPC" FILES ${SOURCES_PPC})
+source_group("Source\\Sparc" FILES ${SOURCES_SPARC})
+source_group("Source\\SystemZ" FILES ${SOURCES_SYSZ})
+source_group("Source\\X86" FILES ${SOURCES_X86})
+source_group("Source\\XCore" FILES ${SOURCES_XCORE})
+source_group("Source\\M68K" FILES ${SOURCES_M68K})
+source_group("Source\\TMS320C64x" FILES ${SOURCES_TMS320C64X})
+source_group("Source\\M680X" FILES ${SOURCES_M680X})
+source_group("Source\\EVM" FILES ${SOURCES_EVM})
+
+source_group("Include\\Common" FILES ${HEADERS_COMMON})
+source_group("Include\\Engine" FILES ${HEADERS_ENGINE})
+source_group("Include\\ARM" FILES ${HEADERS_ARM})
+source_group("Include\\ARM64" FILES ${HEADERS_ARM64})
+source_group("Include\\Mips" FILES ${HEADERS_MIPS})
+source_group("Include\\PowerPC" FILES ${HEADERS_PPC})
+source_group("Include\\Sparc" FILES ${HEADERS_SPARC})
+source_group("Include\\SystemZ" FILES ${HEADERS_SYSZ})
+source_group("Include\\X86" FILES ${HEADERS_X86})
+source_group("Include\\XCore" FILES ${HEADERS_XCORE})
+source_group("Include\\M68K" FILES ${HEADERS_M68K})
+source_group("Include\\TMS320C64x" FILES ${HEADERS_TMS320C64X})
+source_group("Include\\M680X" FILES ${HEADERS_MC680X})
+source_group("Include\\EVM" FILES ${HEADERS_EVM})
+
+### test library 64bit routine:
+get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+
+if (NOT APPLE AND "${LIB64}" STREQUAL "TRUE")
+    set(LIBSUFFIX 64)
+else()
+    set(LIBSUFFIX "")
+endif()
+
+set(INSTALL_LIB_DIR     lib${LIBSUFFIX} CACHE PATH "Installation directory for libraries")
+mark_as_advanced(INSTALL_LIB_DIR)
+
+## installation
+install(FILES ${HEADERS_COMMON} DESTINATION include/capstone)
+configure_file(capstone.pc.in capstone.pc @ONLY)
+
+if (CAPSTONE_BUILD_STATIC)
+    install(TARGETS capstone-static
+            RUNTIME DESTINATION bin
+            LIBRARY DESTINATION ${INSTALL_LIB_DIR}
+            ARCHIVE DESTINATION ${INSTALL_LIB_DIR})
+endif ()
+
+if (CAPSTONE_BUILD_SHARED)
+    install(TARGETS capstone-shared
+            RUNTIME DESTINATION bin
+            LIBRARY DESTINATION ${INSTALL_LIB_DIR}
+            ARCHIVE DESTINATION ${INSTALL_LIB_DIR})
+endif ()
+
+if (CAPSTONE_BUILD_SHARED AND CAPSTONE_BUILD_CSTOOL)
+FILE(GLOB CSTOOL_SRC cstool/*.c)
+add_executable(cstool ${CSTOOL_SRC})
+target_link_libraries(cstool ${default-target})
+
+install(TARGETS cstool DESTINATION bin)
+install(FILES ${CMAKE_BINARY_DIR}/capstone.pc DESTINATION lib/pkgconfig)
+endif ()
diff --git a/Source/ThirdParty/capstone/Source/COMPILE.TXT b/Source/ThirdParty/capstone/Source/COMPILE.TXT
new file mode 100644 (file)
index 0000000..56aecad
--- /dev/null
@@ -0,0 +1,200 @@
+This documentation explains how to compile, install & run Capstone on MacOSX,
+Linux, *BSD & Solaris. We also show steps to cross-compile for Microsoft Windows.
+
+To natively compile for Windows using Microsoft Visual Studio, see COMPILE_MSVC.TXT.
+
+To compile using CMake, see COMPILE_CMAKE.TXT.
+
+To compile using XCode on MacOSX, see xcode/README.md.
+
+To compile for Windows CE (a.k.a, Windows Embedded Compact), see windowsce/COMPILE.md.
+
+                        *-*-*-*-*-*
+
+Capstone requires no prerequisite packages, so it is easy to compile & install.
+
+
+
+(0) Tailor Capstone to your need.
+
+  Out of 12 archtitectures supported by Capstone (Arm, Arm64, M68K, Mips, PPC,
+  Sparc, SystemZ, XCore, X86, M680X, TMS320C64x & EVM), if you just need several
+  selected archs, choose the ones you want to compile in by editing "config.mk"
+  before going to next steps.
+
+  By default, all 12 architectures are compiled.
+
+  The other way of customize Capstone without having to edit config.mk is to
+  pass the desired options on the commandline to ./make.sh. Currently,
+  Capstone supports 5 options, as followings.
+
+  - CAPSTONE_ARCHS: specify list of architectures to compiled in.
+  - CAPSTONE_USE_SYS_DYN_MEM: change this if you have your own dynamic memory management.
+  - CAPSTONE_DIET: use this to make the output binaries more compact.
+  - CAPSTONE_X86_REDUCE: another option to make X86 binary smaller.
+  - CAPSTONE_X86_ATT_DISABLE: disables AT&T syntax on x86.
+  - CAPSTONE_STATIC: build static library.
+  - CAPSTONE_SHARED: build dynamic (shared) library.
+
+  By default, Capstone uses system dynamic memory management, both DIET and X86_REDUCE
+  modes are disable, and builds all the static & shared libraries.
+
+  To avoid editing config.mk for these customization, we can pass their values to
+  make.sh, as followings.
+
+  $ CAPSTONE_ARCHS="arm aarch64 x86" CAPSTONE_USE_SYS_DYN_MEM=no CAPSTONE_DIET=yes CAPSTONE_X86_REDUCE=yes ./make.sh
+
+  NOTE: on commandline, put these values in front of ./make.sh, not after it.
+
+  For each option, refer to docs/README for more details.
+
+
+
+(1) Compile from source
+
+  On *nix (such as MacOSX, Linux, *BSD, Solaris):
+
+  - To compile for current platform, run:
+
+               $ ./make.sh
+
+  - On 64-bit OS, run the command below to cross-compile Capstone for 32-bit binary:
+
+               $ ./make.sh nix32
+
+
+
+(2) Install Capstone on *nix
+
+  To install Capstone, run:
+
+       $ sudo ./make.sh install
+
+       For FreeBSD/OpenBSD, where sudo is unavailable, run:
+
+               $ su; ./make.sh install
+
+  Users are then required to enter root password to copy Capstone into machine
+  system directories.
+
+  Afterwards, run ./tests/test* to see the tests disassembling sample code.
+
+
+  NOTE: The core framework installed by "./make.sh install" consist of
+  following files:
+
+       /usr/include/capstone/capstone.h
+       /usr/include/capstone/x86.h
+       /usr/include/capstone/arm.h
+       /usr/include/capstone/arm64.h
+       /usr/include/capstone/evm.h
+       /usr/include/capstone/m68k.h
+       /usr/include/capstone/m680x.h
+       /usr/include/capstone/mips.h
+       /usr/include/capstone/ppc.h
+       /usr/include/capstone/sparc.h
+       /usr/include/capstone/systemz.h
+       /usr/include/capstone/tms320c64x.h
+       /usr/include/capstone/xcore.h
+       /usr/include/capstone/platform.h
+       /usr/lib/libcapstone.so (for Linux/*nix), or /usr/lib/libcapstone.dylib (OSX)
+       /usr/lib/libcapstone.a
+
+
+
+(3) Cross-compile for Windows from *nix
+
+  To cross-compile for Windows, Linux & gcc-mingw-w64-i686 (and also gcc-mingw-w64-x86-64
+  for 64-bit binaries) are required.
+
+       - To cross-compile Windows 32-bit binary, simply run:
+
+               $ ./make.sh cross-win32
+
+       - To cross-compile Windows 64-bit binary, run:
+
+               $ ./make.sh cross-win64
+
+  Resulted files libcapstone.dll, libcapstone.dll.a & tests/test*.exe can then
+  be used on Windows machine.
+
+
+
+(4) Cross-compile for iOS from Mac OSX.
+
+  To cross-compile for iOS (iPhone/iPad/iPod), Mac OSX with XCode installed is required. 
+
+       - To cross-compile for ArmV7 (iPod 4, iPad 1/2/3, iPhone4, iPhone4S), run:
+               $ ./make.sh ios_armv7
+
+       - To cross-compile for ArmV7s (iPad 4, iPhone 5C, iPad mini), run:
+               $ ./make.sh ios_armv7s
+
+       - To cross-compile for Arm64 (iPhone 5S, iPad mini Retina, iPad Air), run:
+               $ ./make.sh ios_arm64
+
+       - To cross-compile for all iDevices (armv7 + armv7s + arm64), run:
+               $ ./make.sh ios
+
+  Resulted files libcapstone.dylib, libcapstone.a & tests/test* can then
+  be used on iOS devices.
+
+
+
+(5) Cross-compile for Android
+
+  To cross-compile for Android (smartphone/tablet), Android NDK is required.
+  NOTE: Only ARM and ARM64 are currently supported.
+
+       $ NDK=/android/android-ndk-r10e ./make.sh cross-android arm
+  or
+       $ NDK=/android/android-ndk-r10e ./make.sh cross-android arm64
+
+  Resulted files libcapstone.so, libcapstone.a & tests/test* can then
+  be used on Android devices.
+
+
+
+(6) Compile on Windows with Cygwin
+
+  To compile under Cygwin gcc-mingw-w64-i686 or x86_64-w64-mingw32 run:
+
+        - To compile Windows 32-bit binary under Cygwin, run:
+
+                $ ./make.sh cygwin-mingw32
+
+        - To compile Windows 64-bit binary under Cygwin, run:
+
+                $ ./make.sh cygwin-mingw64
+
+  Resulted files libcapstone.dll, libcapstone.dll.a & tests/test*.exe can then
+  be used on Windows machine.
+
+
+
+(7) By default, "cc" (default C compiler on the system) is used as compiler.
+
+       - To use "clang" compiler instead, run the command below:
+
+               $ ./make.sh clang
+
+       - To use "gcc" compiler instead, run:
+
+               $ ./make.sh gcc
+
+
+
+(8) To uninstall Capstone, run the command below:
+
+               $ sudo ./make.sh uninstall
+
+
+
+(9) Language bindings
+
+  So far, Python, Ocaml & Java are supported by bindings in the main code.
+  Look for the bindings under directory bindings/, and refer to README file
+  of corresponding languages.
+
+  Community also provide bindings for C#, Go, Ruby, NodeJS, C++ & Vala. Links to
+  these can be found at address http://capstone-engine.org/download.html
diff --git a/Source/ThirdParty/capstone/Source/COMPILE_CMAKE.TXT b/Source/ThirdParty/capstone/Source/COMPILE_CMAKE.TXT
new file mode 100644 (file)
index 0000000..6b35d8d
--- /dev/null
@@ -0,0 +1,85 @@
+This documentation explains how to compile Capstone with CMake, focus on
+using Microsoft Visual C as the compiler.
+
+To compile Capstone on *nix, see COMPILE.TXT.
+
+To compile Capstone on Windows using Visual Studio, see COMPILE_MSVC.TXT.
+
+                        *-*-*-*-*-*
+
+This documentation requires CMake & Windows SDK or MS Visual Studio installed on
+your machine.
+
+Get CMake for free from http://www.cmake.org.
+
+
+
+(0) Tailor Capstone to your need.
+
+  Out of 12 archtitectures supported by Capstone (Arm, Arm64, M68K, Mips, PPC,
+  Sparc, SystemZ, X86, XCore, M680X, TMS320C64x & EVM), if you just need several selected archs,
+  run "cmake" with the unwanted archs disabled (set to 0) as followings.
+
+  - CAPSTONE_ARM_SUPPORT: support ARM. Run cmake with -DCAPSTONE_ARM_SUPPORT=0 to remove ARM.
+  - CAPSTONE_ARM64_SUPPORT: support ARM64. Run cmake with -DCAPSTONE_ARM64_SUPPORT=0 to remove ARM64.
+  - CAPSTONE_M680X_SUPPORT: support M680X. Run cmake with -DCAPSTONE_M680X_SUPPORT=0 to remove M680X.
+  - CAPSTONE_M68K_SUPPORT: support M68K. Run cmake with -DCAPSTONE_M68K_SUPPORT=0 to remove M68K.
+  - CAPSTONE_MIPS_SUPPORT: support Mips. Run cmake with -DCAPSTONE_MIPS_SUPPORT=0 to remove Mips.
+  - CAPSTONE_PPC_SUPPORT: support PPC. Run cmake with -DCAPSTONE_PPC_SUPPORT=0 to remove PPC.
+  - CAPSTONE_SPARC_SUPPORT: support Sparc. Run cmake with -DCAPSTONE_SPARC_SUPPORT=0 to remove Sparc.
+  - CAPSTONE_SYSZ_SUPPORT: support SystemZ. Run cmake with -DCAPSTONE_SYSZ_SUPPORT=0 to remove SystemZ.
+  - CAPSTONE_XCORE_SUPPORT: support XCore. Run cmake with -DCAPSTONE_XCORE_SUPPORT=0 to remove XCore.
+  - CAPSTONE_X86_SUPPORT: support X86. Run cmake with -DCAPSTONE_X86_SUPPORT=0 to remove X86.
+  - CAPSTONE_X86_TMS320C64X: support TMS320C64X. Run cmake with -DCAPSTONE_TMS320C64X_SUPPORT=0 to remove TMS320C64X.
+  - CAPSTONE_X86_M680X: support M680X. Run cmake with -DCAPSTONE_M680X_SUPPORT=0 to remove M680X.
+  - CAPSTONE_X86_EVM: support EVM. Run cmake with -DCAPSTONE_EVM_SUPPORT=0 to remove EVM.
+
+  By default, all 10 architectures are compiled in.
+
+
+  Besides, Capstone also allows some more customization via following macros.
+
+  - CAPSTONE_USE_SYS_DYN_MEM: change this to OFF to use your own dynamic memory management.
+  - CAPSTONE_BUILD_DIET: change this to ON to make the binaries more compact.
+  - CAPSTONE_X86_REDUCE: change this to ON to make X86 binary smaller.
+  - CAPSTONE_X86_ATT_DISABLE: change this to ON to disable AT&T syntax on x86.
+
+  By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE
+  modes are disabled. To use your own memory allocations, turn ON both DIET &
+  X86_REDUCE, run "cmake" with: -DCAPSTONE_USE_SYS_DYN_MEM=0 -DCAPSTONE_BUILD_DIET=1 -DCAPSTONE_X86_REDUCE=1
+
+
+  For each option, refer to docs/README for more details.
+
+
+
+(1) CMake allows you to generate different generators to build Capstone. Below is
+    some examples on how to build Capstone on Windows with CMake.
+
+
+  (*) To build Capstone using Nmake of Windows SDK, do:
+
+      mkdir build
+      cd build
+      ..\nmake.bat
+
+  After this, find the samples test*.exe, capstone.lib & capstone.dll
+  in the same directory.
+
+
+
+  (*) To build Capstone using Visual Studio, choose the generator accordingly to the
+  version of Visual Studio on your machine. For example, with Visual Studio 2013, do:
+
+      mkdir build
+      cd build
+      cmake -G "Visual Studio 12" ..
+
+  After this, find capstone.sln in the same directory. Open it with Visual Studio
+  and build the solution including libraries & all test as usual.
+
+
+
+(2) You can make sure the prior steps successfully worked by launching one of the
+  testing binary (test*.exe).
+
diff --git a/Source/ThirdParty/capstone/Source/COMPILE_MSVC.TXT b/Source/ThirdParty/capstone/Source/COMPILE_MSVC.TXT
new file mode 100644 (file)
index 0000000..24705ed
--- /dev/null
@@ -0,0 +1,108 @@
+This documentation explains how to compile Capstone on Windows using
+Microsoft Visual Studio version 2010 or newer.
+
+To compile Capstone on *nix, see COMPILE.TXT
+
+To compile Capstone with CMake, see COMPILE_CMAKE.TXT
+
+                        *-*-*-*-*-*
+
+Capstone requires no prerequisite packages with default configurations, so it is
+easy to compile & install. Open the Visual Studio solution "msvc/capstone.sln"
+and follow the instructions below.
+
+NOTE: This requires Visual Studio 2010 or newer versions.
+
+If you wish to embed Capstone in a kernel driver, Visual Studio 2013 or newer
+versions, and Windows Driver Kit 8.1 Update 1 or newer versions are required.
+
+
+(0) Tailor Capstone to your need.
+
+  Out of 9 archtitectures supported by Capstone (Arm, Arm64, M68K, Mips, PPC,
+  Sparc, SystemZ, X86 & XCore), if you just need several selected archs, choose
+  the ones you want to compile in by opening Visual Studio solution "msvc\capstone.sln",
+  then directly editing the projects "capstone_static" & "capstone_dll" for static
+  and dynamic libraries, respectively. This must be done before going to the
+  next steps.
+
+  In VisualStudio interface, modify the preprocessor definitions via
+  "Project Properties" -> "Configuration Properties" -> "C/C++" -> "Preprocessor"
+  to customize Capstone library, as followings.
+
+  - CAPSTONE_HAS_ARM: support ARM. Delete this to remove ARM support.
+  - CAPSTONE_HAS_ARM64: support ARM64. Delete this to remove ARM64 support.
+  - CAPSTONE_HAS_M68K: support M68K. Delete this to remove M68K support.
+  - CAPSTONE_HAS_MIPS: support Mips. Delete this to remove Mips support.
+  - CAPSTONE_HAS_PPC: support PPC. Delete this to remove PPC support.
+  - CAPSTONE_HAS_SPARC: support Sparc. Delete this to remove Sparc support.
+  - CAPSTONE_HAS_SYSZ: support SystemZ. Delete this to remove SystemZ support.
+  - CAPSTONE_HAS_X86: support X86. Delete this to remove X86 support.
+  - CAPSTONE_HAS_XCORE: support XCore. Delete this to remove XCore support.
+
+  By default, all 9 architectures are compiled in.
+
+
+  Besides, Capstone also allows some more customization via following macros.
+
+  - CAPSTONE_USE_SYS_DYN_MEM: delete this to use your own dynamic memory management.
+  - CAPSTONE_DIET_NO: rename this to "CAPSTONE_DIET" to make the binaries more compact.
+  - CAPSTONE_X86_REDUCE_NO: rename this to "CAPSTONE_X86_REDUCE" to make X86 binary smaller.
+  - CAPSTONE_X86_ATT_DISABLE_NO: rename this to "CAPSTONE_X86_ATT_DISABLE" to disable
+    AT&T syntax on x86.
+
+  By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE
+  modes are disable.
+
+
+  For each option, refer to docs/README for more details.
+
+
+
+(1) Compile from source on Windows with Visual Studio
+
+  - Choose the configuration and the platform you want: Release/Debug & Win32/Win64.
+  - Build only the libraries, or the libraries along with all the tests.
+  - "capstone_static_winkernel" is for compiling Capstone for a driver and
+    "test_winkernel" is a test for a driver, and those are excluded from build by
+    default. To compile them, open the Configuration Manager through the [Build]
+    menu and check "Build" check boxes for those project.
+
+
+
+(2) You can make sure the prior steps successfully worked by launching one of the
+  testing binary (test*.exe).
+
+  The testing binary for a driver "test_winkernel.sys" is made up of all tests for
+  supported architectures configured with the step (0) along side its own tests.
+  Below explains a procedure to run the test driver and check test results.
+
+  On the x64 platform, the test signing mode has to be enabled to install the test
+  driver. To do it, open the command prompt with the administrator privileges and
+  type the following command, and then restart the system to activate the change:
+
+      >bcdedit /set testsigning on
+
+  Test results from the test driver is sent to kernel debug buffer. In order to
+  see those results, download DebugView and run it with the administrator
+  privileges, then check [Capture Kernel] through the [Capture] menu.
+
+  DebugView: https://technet.microsoft.com/en-us/sysinternals/debugview.aspx
+
+  To install and uninstall the driver, use the 'sc' command. For installing and
+  executing test_winkernel.sys, execute the following commands with the
+  administrator privileges:
+
+      >sc create test_winkernel type= kernel binPath= <full path to test_winkernel.sys>
+      [SC] CreateService SUCCESS
+
+      >sc start test_winkernel
+      [SC] StartService FAILED 995:
+
+      The I/O operation has been aborted because of either a thread exit or an application request.
+
+  To uninstall the driver, execute the following commands with the administrator
+  privileges:
+
+      >sc delete test_winkernel
+      >bcdedit /deletevalue testsigning
diff --git a/Source/ThirdParty/capstone/Source/CREDITS.TXT b/Source/ThirdParty/capstone/Source/CREDITS.TXT
new file mode 100644 (file)
index 0000000..5418cc6
--- /dev/null
@@ -0,0 +1,69 @@
+This file credits all the contributors of the Capstone engine project.
+
+Key developers
+==============
+1. Nguyen Anh Quynh <aquynh -at- gmail.com>
+       - Core engine
+       - Bindings: Python, Ruby, OCaml, Java, C#
+
+2. Tan Sheng Di <shengdi -at- coseinc.com>
+       - Bindings: Ruby
+
+3. Ben Nagy <ben -at- coseinc.com>
+       - Bindings: Ruby, Go
+
+4. Dang Hoang Vu <dang.hvu -at- gmail.com>
+       - Bindings: Java
+
+
+Beta testers (in random order)
+==============================
+Pancake
+Van Hauser
+FX of Phenoelit
+The Grugq, The Grugq   <-- our hero for submitting the first ever patch!
+Isaac Dawson, Veracode Inc
+Patroklos Argyroudis, Census Inc. (http://census-labs.com)
+Attila Suszter
+Le Dinh Long
+Nicolas Ruff
+Gunther
+Alex Ionescu, Winsider Seminars & Solutions Inc.
+Snare
+Daniel Godas-Lopez
+Joshua J. Drake
+Edgar Barbosa
+Ralf-Philipp Weinmann
+Hugo Fortier
+Joxean Koret
+Bruce Dang
+Andrew Dunham
+
+
+Contributors (in no particular order)
+=====================================
+(Please let us know if you want to have your name here)
+
+Ole André Vadla Ravnås (author of the 100th Pull-Request in our Github repo, thanks!)
+Axel "0vercl0k" Souchet (@0vercl0k) & Alex Ionescu: port to MSVC.
+Daniel Pistelli: Cmake support.
+Peter Hlavaty: integrate Capstone for Windows kernel drivers.
+Guillaume Jeanne: Ocaml binding.
+Martin Tofall, Obsidium Software: Optimize X86 performance & size.
+David Martínez Moreno & Hilko Bengen: Debian package.
+Félix Cloutier: Xcode project.
+Benoit Lecocq: OpenBSD package.
+Christophe Avoinne (Hlide): Improve memory management for better performance.
+Michael Cohen & Nguyen Tan Cong: Python module installer.
+Bui Dinh Cuong: Explicit registers accessed for Arm64.
+Vincent Bénony: Explicit registers accessed for X86.
+Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package.
+Felix Gröbert (Google): fuzz testing harness.
+Daniel Collin & Nicolas Planel: M68K architecture.
+Pranith Kumar: Explicit registers accessed for Arm64.
+Xipiter LLC: Capstone logo redesigned.
+Satoshi Tanda: Support Windows kernel driver.
+Koutheir Attouchi: Support for Windows CE.
+Fotis Loukos: TMS320C64x architecture.
+Wolfgang Schwotzer: M680X architecture.
+
diff --git a/Source/ThirdParty/capstone/Source/ChangeLog-capstone b/Source/ThirdParty/capstone/Source/ChangeLog-capstone
new file mode 100644 (file)
index 0000000..1094cff
--- /dev/null
@@ -0,0 +1,357 @@
+This file details the changelog of Capstone.
+
+[ Arm ]
+
+- Fix a bug where Arm.Operand is wrongly calculated for the second and
+  following operands
+- Fix a bug where Arm.OpInfo.memBarrier and Arm.OpInfo.op is wrongly
+  calculated
+
+[ Bindings ]
+
+- Java; add Capstone.strerror() and CsInsn.regsAccess().
+
+---------------------------------
+Version 3.0.2: March 11th, 2015
+
+
+[ Library ]
+
+- On *nix, only export symbols that are part of the API (instead of all
+  the internal symbols).
+
+
+[ X86 ]
+
+- Do not consider 0xF2 as REPNE prefix if it is a part of instruction encoding.
+- Fix implicit registers read/written & instruction groups of some instructions.
+- More flexible on the order of prefixes, so better handle some tricky
+  instructions.
+- REPNE prefix can go with STOS & MOVS instructions.
+- Fix a compilation bug for X86_REDUCE mode.
+- Fix operand size of instructions with operand PTR []
+
+
+[ Arm ]
+
+- Fix a bug where arm_op_mem.disp is wrongly calculated (in DETAIL mode).
+- Fix a bug on handling the If-Then block.
+
+
+[ Mips ]
+
+- Sanity check for the input size for MIPS64 mode.
+
+
+[ MSVC ]
+
+- Compile capstone.dll with static runtime MSVCR built in.
+
+
+[ Python binding ]
+
+- Fix a compiling issue of Cython binding with gcc 4.9.
+
+---------------------------------
+Version 3.0.1: February 03rd, 2015
+
+[ X86 ]
+
+- Properly handle LOCK, REP, REPE & REPNE prefixes.
+- Handle undocumented immediates for SSE's (V)CMPPS/PD/SS/SD instructions.
+- Print LJUMP/LCALL without * as prefix for Intel syntax.
+- Handle REX prefix properly for segment/MMX related instructions (x86_64).
+- Instruction with length > 15 is consider invalid.
+- Handle some tricky encodings for instructions MOVSXD, FXCH, FCOM, FCOMP,
+  FSTP, FSTPNCE, NOP.
+- Handle some tricky code for some X86_64 instructions with REX prefix.
+- Add missing operands in detail mode for PUSH , POP , IN/OUT reg, reg
+- MOV32ms & MOV32sm should reference word rather than dword.
+
+
+[ Arm64 ]
+
+- BL & BLR instructions do not read SP register.
+- Print absolute (rather than relative) address for instructions B, BL,
+  CBNZ, ADR.
+
+
+[ Arm ]
+
+- Instructions ADC & SBC do not update flags.
+- BL & BLX do not read SP, but PC register.
+- Alias LDR instruction with operands [sp], 4 to POP.
+- Print immediate operand of MVN instruction in positive hexadecimal form.
+
+
+[ PowerPC ]
+
+- Fix some compilation bugs when DIET mode is enable.
+- Populate SLWI/SRWI instruction details with SH operand.
+
+
+[ Python binding ]
+
+- Fix a Cython bug when CsInsn.bytes returns a shorten array of bytes.
+- Fixed a memory leak for Cython disasm functions when we immaturely quit
+  the enumeration of disassembled instructions.
+- Fix a NULL memory access issue when SKIPDATA & Detail modes are enable
+  at the same time.
+- Fix a memory leaking bug when when we stop enumeration over the disassembled
+  instructions prematurely.
+- Export generic operand types & groups (CS_OP_xxx & CS_GRP_xxx).
+
+---------------------------------
+Version 3.0: November 19th, 2014
+
+[ API ]
+
+- New API: cs_disasm_iter & cs_malloc. See docs/README for tutorials.
+- Renamed cs_disasm_ex to cs_disasm (cs_disasm_ex is still supported, but
+  marked obsolete to be removed in future)
+- Support SKIPDATA mode, so Capstone can jump over unknown data and keep going
+  from the next legitimate instruction. See docs/README for tutorials.
+- More details provided in cs_detail struct for all architectures.
+- API version was bumped to 3.0.
+
+
+[ Bindings ]
+
+- Python binding supports Python3 (besides Python2).
+- Support Ocaml binding.
+- Java: add close() method to be used to deinitialize a Capstone object when
+  no longer use it.
+
+
+[ Architectures ]
+
+- New architectures: Sparc, SystemZ & XCore.
+- Important bugfixes for Arm, Arm64, Mips, PowerPC & X86.
+- Support more instructions for Arm, Arm64, Mips, PowerPC & X86.
+- Always expose absolute addresses rather than relative addresses (Arm, Arm64,
+  Mips, PPC, Sparc, X86).
+- Use common instruction operand types REG, IMM, MEM & FP across all
+  architectures (to enable cross-architecture analysis).
+- Use common instruction group types across all architectures (to enable
+  cross-architecture analysis).
+
+
+[ X86 ]
+
+- X86 engine is mature & handles all the malware tricks (that we are aware of).
+- Added a lot of new instructions (such as AVX512, 3DNow, etc).
+- Add prefix symbols X86_PREFIX_REP/REPNE/LOCK/CS/DS/SS/FS/GS/ES/OPSIZE/ADDRSIZE.
+- Print immediate in positive form & hexadecimal for AND/OR/XOR instructions.
+- More friendly disassembly for JMP16i (in the form segment:offset)
+
+
+[ Mips ]
+
+- Engine added supports for new hardware modes: Mips32R6 (CS_MODE_MIPS32R6) &
+  MipsGP64 (CS_MODE_MIPSGP64).
+- Removed the ABI-only mode CS_MODE_N64.
+- New modes CS_MODE_MIPS32 & CS_MODE_MIPS64 (to use instead of CS_MODE_32 &
+  CS_MODE_64).
+
+
+[ ARM ]
+
+- Support new mode CS_MODE_V8 for Armv8 A32 encodings.
+- Print immediate in positive form & hexadecimal for AND/ORR/EOR/BIC instructions
+
+
+[ ARM64 ]
+
+- Print immediate in hexadecimal for AND/ORR/EOR/TST instructions.
+
+
+[ PowerPC ]
+
+- Do not print a dot in front of absolute address.
+
+
+[ Other features ]
+
+- Support for Microsoft Visual Studio (so enable Windows native compilation).
+- Support CMake compilation.
+- Cross-compile for Android.
+- Build libraries/tests using XCode project
+- Much faster, while consuming less memory for all architectures.
+
+---------------------------------
+Version 2.1.2: April 3rd, 2014
+
+This is a stable release to fix some bugs deep in the core. There is no update
+to any architectures or bindings, so bindings version 2.1 can be used with this
+version 2.1.2 just fine.
+
+[ Core changes]
+
+- Support cross-compilation for all iDevices (iPhone/iPad/iPod).
+- X86: do not print memory offset in negative form.
+- Fix a bug in X86 when Capstone cannot handle short instruction.
+- Print negative number above -9 without prefix 0x (arm64, mips, arm).
+- Correct the SONAME setup for library versioning (Linux, *BSD, Solaris).
+- Set library versioning for dylib of OSX.
+
+---------------------------------
+Version 2.1.1: March 13th, 2014
+
+This is a stable release to fix some bugs deep in the core. There is no update
+to any architectures or bindings, so bindings version 2.1 can be used with this
+version 2.1.1 just fine.
+
+[ Core changes]
+
+- Fix a buffer overflow bug in Thumb mode (ARM). Some special input can
+  trigger this flaw.
+- Fix a crash issue when embedding Capstone into OSX kernel. This should
+  also enable Capstone to be embedded into other systems with limited stack
+  memory size such as Linux kernel or some firmwares.
+- Use a proper SONAME for library versioning (Linux).
+
+---------------------------------
+Version 2.1: March 5th, 2014
+
+[ API changes ]
+
+- API version has been bumped to 2.1.
+- Change prototype of cs_close() to be able to invalidate closed handle.
+  See http://capstone-engine.org/version_2.1_API.html for more information.
+- Extend cs_support() to handle more query types, not only about supported
+  architectures. This change is backward compatible, however, so existent code
+  do not need to be modified to support this.
+- New query type CS_SUPPORT_DIET for cs_support() to ask about diet status of
+  the engine.
+- New error code CS_ERR_DIET to report errors about newly added diet mode.
+- New error code CS_ERR_VERSION to report issue of incompatible versions between
+  bindings & core engine.
+
+
+[ Core changes ]
+
+- On memory usage, Capstone uses about 40% less memory, while still faster
+  than version 2.0.
+- All architectures are much smaller: binaries size reduce at least 30%.
+  Especially, X86-only binary reduces from 1.9MB to just 720KB.
+- Support "diet" mode, in which engine size is further reduced (by around 40%)
+  for embedding purpose. The price to pay is that we have to sacrifice some
+  non-critical data fields. See http://capstone-engine.org/diet.html for more
+  details.
+
+
+[ Architectures ]
+
+- Update all 5 architectures to fix bugs.
+- PowerPC:
+       - New instructions: FMR & MSYNC.
+- Mips:
+       - New instruction: DLSA
+- X86:
+       - Properly handle AVX-512 instructions.
+       - New instructions: PSETPM, SALC, INT1, GETSEC.
+       - Fix some memory leaking issues in case of prefixed instructions such
+         as LOCK, REP, REPNE.
+
+
+[ Python binding ]
+
+- Verify the core version at initialization time. Refuse to run if its version
+  is different from the core's version.
+- New API disasm_lite() added to Cs class. This light API only returns tuples of
+  (address, size, mnemonic, op_str), rather than list of CsInsn objects. This
+  improves performance by around 30% in some benchmarks.
+- New API version_bind() returns binding's version, which might differ from
+  the core's API version if the binding is out-of-date.
+- New API debug() returns information on Cython support, diet status & archs
+  compiled in.
+- Fixed some memory leaking bugs for Cython binding.
+- Fix a bug crashing Cython code when accessing @regs_read/regs_write/groups.
+- Support diet mode.
+
+
+[ Java binding ]
+
+- Fix some memory leaking bugs.
+- New API version() returns combined version.
+- Support diet mode.
+- Better support for detail option.
+
+
+[ Miscellaneous ]
+
+- make.sh now can uninstall the core engine. This is done with:
+
+       $ sudo ./make.sh uninstall
+
+----------------------------------
+Version 2.0: January 22nd, 2014
+
+Release 2.0 deprecates verison 1.0 and brings a lot of crucial changes.
+
+[ API changes ]
+
+- API version has been bumped to 2.0 (see cs_version() API)
+- New API cs_strerror(errno) returns a string describing error code given
+  in its only argument.
+- cs_version() now returns combined version encoding both major & minor versions.
+- New option CS_OPT_MODE allows to change engine’s mode at run-time with
+  cs_option().
+- New option CS_OPT_MEM allows to specify user-defined functions for dynamically
+  memory management used internally by Capstone. This is useful to embed Capstone
+  into special environments such as kernel or firware.
+- New API cs_support() can be used to check if this lib supports a particular
+  architecture (this is necessary since we now allow to choose which architectures
+  to compile in).
+- The detail option is OFF by default now. To get detail information, it should be
+  explicitly turned ON. The details then can be accessed using cs_insn.detail
+  pointer (to newly added structure cs_detail)
+
+
+[ Core changes ]
+
+- On memory usage, Capstone uses much less memory, but a lot faster now.
+- User now can choose which architectures to be supported by modifying config.mk
+  before compiling/installing.
+
+
+[ Architectures ]
+
+- Arm
+     - Support Big-Endian mode (besides Little-Endian mode).
+     - Support friendly register, so instead of output sub "r12,r11,0x14",
+        we have "sub ip,fp,0x14".
+- Arm64: support Big-Endian mode (besides Little-Endian mode).
+- PowerPC: newly added.
+- Mips: support friendly register, so instead of output "srl $2,$1,0x1f",
+     we have "srl $v0,$at,0x1f".
+- X86: bug fixes.
+
+
+[ Python binding ]
+
+- Python binding is vastly improved in performance: around 3 ~ 4 times faster
+  than in 1.0.
+- Cython support has been added, which can further speed up over the default
+  pure Python binding (up to 30% in some cases)
+- Function cs_disasm_quick() & Cs.disasm() now use generator (rather than a list)
+  to return succesfully disassembled instructions. This improves the performance
+  and reduces memory usage.
+
+
+[ Java binding ]
+
+- Better performance & bug fixes.
+
+
+[ Miscellaneous ]
+
+- Fixed some installation issues with Gentoo Linux.
+- Capstone now can easily compile/install on all *nix, including Linux, OSX,
+  {Net, Free, Open}BSD & Solaris.
+
+----------------------------------
+[Version 1.0]: December 18th, 2013
+
+- Initial public release.
+
diff --git a/Source/ThirdParty/capstone/Source/HACK.TXT b/Source/ThirdParty/capstone/Source/HACK.TXT
new file mode 100644 (file)
index 0000000..e641c68
--- /dev/null
@@ -0,0 +1,48 @@
+Capstone source is organized as followings.
+
+
+.                   <- core engine + README + COMPILE.TXT etc
+├── arch            <- code handling disasm engine for each arch
+│   ├── AArch64     <- ARM64 (aka ARMv8) engine
+│   ├── ARM         <- ARM engine
+│   ├── M680X       <- M680X engine
+│   ├── M68K        <- M68K engine
+│   ├── Mips        <- Mips engine
+│   ├── PowerPC     <- PowerPC engine
+│   ├── Sparc       <- Sparc engine
+│   ├── SystemZ     <- SystemZ engine
+│   ├── X86         <- X86 engine
+│   └── XCore       <- XCore engine
+├── bindings        <- all bindings are under this dir
+│   ├── java        <- Java bindings + test code
+│   ├── ocaml       <- Ocaml bindings + test code
+│   └── python      <- Python bindings + test code
+├── contrib         <- Code contributed by community to help Capstone integration
+├── cstool          <- Cstool
+├── docs            <- Documentation
+├── include         <- API headers in C language (*.h)
+├── msvc            <- Microsoft Visual Studio support (for Windows compile)
+├── packages        <- Packages for Linux/OSX/BSD.
+├── windows         <- Windows support (for Windows kernel driver compile)
+├── suite           <- Development test tools - for Capstone developers only
+├── tests           <- Test code (in C language)
+└── xcode           <- Xcode support (for MacOSX compile)
+
+
+Follow instructions in COMPILE.TXT for how to compile and run test code.
+
+Note: if you find some strange bugs, it is recommended to firstly clean
+the code and try to recompile/reinstall again. This can be done with:
+
+       $ ./make.sh
+       $ sudo ./make.sh install
+
+Then test Capstone with cstool, for example:
+
+       $ cstool x32 "90 91"
+
+At the same time, for Java/Ocaml/Python bindings, be sure to always use
+the bindings coming with the core to avoid potential incompatibility issue
+with older versions.
+See bindings/<language>/README for detail instructions on how to compile &
+install the bindings.
diff --git a/Source/ThirdParty/capstone/Source/LEB128.h b/Source/ThirdParty/capstone/Source/LEB128.h
new file mode 100644 (file)
index 0000000..da4140c
--- /dev/null
@@ -0,0 +1,38 @@
+//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares some utility functions for encoding SLEB128 and
+// ULEB128 values.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_LLVM_SUPPORT_LEB128_H
+#define CS_LLVM_SUPPORT_LEB128_H
+
+#include "include/capstone/capstone.h"
+
+/// Utility function to decode a ULEB128 value.
+static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n)
+{
+       const uint8_t *orig_p = p;
+       uint64_t Value = 0;
+       unsigned Shift = 0;
+       do {
+               Value += (*p & 0x7f) << Shift;
+               Shift += 7;
+       } while (*p++ >= 128);
+       if (n)
+               *n = (unsigned)(p - orig_p);
+       return Value;
+}
+
+#endif  // LLVM_SYSTEM_LEB128_H
diff --git a/Source/ThirdParty/capstone/Source/LICENSE.TXT b/Source/ThirdParty/capstone/Source/LICENSE.TXT
new file mode 100644 (file)
index 0000000..0dabdc7
--- /dev/null
@@ -0,0 +1,31 @@
+This is the software license for Capstone disassembly framework.
+Capstone has been designed & implemented by Nguyen Anh Quynh <aquynh@gmail.com>
+
+See http://www.capstone-engine.org for further information.
+
+Copyright (c) 2013, COSEINC.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+* Neither the name of the developer(s) nor the names of its
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Source/ThirdParty/capstone/Source/LICENSE_LLVM.TXT b/Source/ThirdParty/capstone/Source/LICENSE_LLVM.TXT
new file mode 100644 (file)
index 0000000..66d6647
--- /dev/null
@@ -0,0 +1,71 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+Autoconf            llvm/autoconf
+                    llvm/projects/ModuleMaker/autoconf
+                    llvm/projects/sample/autoconf
+Google Test         llvm/utils/unittest/googletest
+OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
+pyyaml tests        llvm/test/YAMLParser/{*.data, LICENSE.TXT}
+ARM contributions   llvm/lib/Target/ARM/LICENSE.TXT
+md5 contributions   llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
diff --git a/Source/ThirdParty/capstone/Source/MCDisassembler.h b/Source/ThirdParty/capstone/Source/MCDisassembler.h
new file mode 100644 (file)
index 0000000..35d8e63
--- /dev/null
@@ -0,0 +1,14 @@
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_MCDISASSEMBLER_H
+#define CS_MCDISASSEMBLER_H
+
+typedef enum DecodeStatus {
+       MCDisassembler_Fail = 0,
+       MCDisassembler_SoftFail = 1,
+       MCDisassembler_Success = 3,
+} DecodeStatus;
+
+#endif
+
diff --git a/Source/ThirdParty/capstone/Source/MCFixedLenDisassembler.h b/Source/ThirdParty/capstone/Source/MCFixedLenDisassembler.h
new file mode 100644 (file)
index 0000000..27ac115
--- /dev/null
@@ -0,0 +1,30 @@
+//===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Fixed length disassembler decoder state machine driver.
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+#define CS_LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+
+// Disassembler state machine opcodes.
+enum DecoderOps {
+       MCD_OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len)
+       MCD_OPC_FilterValue,      // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
+       MCD_OPC_CheckField,       // OPC_CheckField(uint8_t Start, uint8_t Len,
+                                                         //                uleb128 Val, uint16_t NumToSkip)
+       MCD_OPC_CheckPredicate,   // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
+       MCD_OPC_Decode,           // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+       MCD_OPC_SoftFail,         // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+       MCD_OPC_Fail              // OPC_Fail()
+};
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/MCInst.c b/Source/ThirdParty/capstone/Source/MCInst.c
new file mode 100644 (file)
index 0000000..cc062d0
--- /dev/null
@@ -0,0 +1,180 @@
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#if defined(CAPSTONE_HAS_OSXKERNEL)
+#include <libkern/libkern.h>
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+#include "MCInst.h"
+#include "utils.h"
+
+#define MCINST_CACHE (ARR_SIZE(mcInst->Operands) - 1)
+
+void MCInst_Init(MCInst *inst)
+{
+       inst->Opcode = 0;
+       inst->OpcodePub = 0;
+       inst->size = 0;
+       inst->has_imm = false;
+       inst->op1_size = 0;
+       inst->writeback = false;
+       inst->ac_idx = 0;
+       inst->popcode_adjust = 0;
+       inst->assembly[0] = '\0';
+}
+
+void MCInst_clear(MCInst *inst)
+{
+       inst->size = 0;
+}
+
+// do not free @Op
+void MCInst_insert0(MCInst *inst, int index, MCOperand *Op)
+{
+       int i;
+
+       for(i = inst->size; i > index; i--)
+               //memcpy(&(inst->Operands[i]), &(inst->Operands[i-1]), sizeof(MCOperand));
+               inst->Operands[i] = inst->Operands[i-1];
+
+       inst->Operands[index] = *Op;
+       inst->size++;
+}
+
+void MCInst_setOpcode(MCInst *inst, unsigned Op)
+{
+       inst->Opcode = Op;
+}
+
+void MCInst_setOpcodePub(MCInst *inst, unsigned Op)
+{
+       inst->OpcodePub = Op;
+}
+
+unsigned MCInst_getOpcode(const MCInst *inst)
+{
+       return inst->Opcode;
+}
+
+unsigned MCInst_getOpcodePub(const MCInst *inst)
+{
+       return inst->OpcodePub;
+}
+
+MCOperand *MCInst_getOperand(MCInst *inst, unsigned i)
+{
+       return &inst->Operands[i];
+}
+
+unsigned MCInst_getNumOperands(const MCInst *inst)
+{
+       return inst->size;
+}
+
+// This addOperand2 function doesnt free Op
+void MCInst_addOperand2(MCInst *inst, MCOperand *Op)
+{
+       inst->Operands[inst->size] = *Op;
+
+       inst->size++;
+}
+
+void MCOperand_Init(MCOperand *op)
+{
+       op->Kind = kInvalid;
+       op->FPImmVal = 0.0;
+}
+
+bool MCOperand_isValid(const MCOperand *op)
+{
+       return op->Kind != kInvalid;
+}
+
+bool MCOperand_isReg(const MCOperand *op)
+{
+       return op->Kind == kRegister;
+}
+
+bool MCOperand_isImm(const MCOperand *op)
+{
+       return op->Kind == kImmediate;
+}
+
+bool MCOperand_isFPImm(const MCOperand *op)
+{
+       return op->Kind == kFPImmediate;
+}
+
+/// getReg - Returns the register number.
+unsigned MCOperand_getReg(const MCOperand *op)
+{
+       return op->RegVal;
+}
+
+/// setReg - Set the register number.
+void MCOperand_setReg(MCOperand *op, unsigned Reg)
+{
+       op->RegVal = Reg;
+}
+
+int64_t MCOperand_getImm(MCOperand *op)
+{
+       return op->ImmVal;
+}
+
+void MCOperand_setImm(MCOperand *op, int64_t Val)
+{
+       op->ImmVal = Val;
+}
+
+double MCOperand_getFPImm(const MCOperand *op)
+{
+       return op->FPImmVal;
+}
+
+void MCOperand_setFPImm(MCOperand *op, double Val)
+{
+       op->FPImmVal = Val;
+}
+
+MCOperand *MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg)
+{
+       MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
+
+       op->Kind = kRegister;
+       op->RegVal = Reg;
+
+       return op;
+}
+
+void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
+{
+       MCOperand *op = &(mcInst->Operands[mcInst->size]);
+       mcInst->size++;
+
+       op->Kind = kRegister;
+       op->RegVal = Reg;
+}
+
+MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val)
+{
+       MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
+
+       op->Kind = kImmediate;
+       op->ImmVal = Val;
+
+       return op;
+}
+
+void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
+{
+       MCOperand *op = &(mcInst->Operands[mcInst->size]);
+       mcInst->size++;
+
+       op->Kind = kImmediate;
+       op->ImmVal = Val;
+}
diff --git a/Source/ThirdParty/capstone/Source/MCInst.h b/Source/ThirdParty/capstone/Source/MCInst.h
new file mode 100644 (file)
index 0000000..6a70741
--- /dev/null
@@ -0,0 +1,137 @@
+//===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCInst and MCOperand classes, which
+// is the basic representation used to represent low-level machine code
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_MCINST_H
+#define CS_MCINST_H
+
+#include "include/capstone/capstone.h"
+
+typedef struct MCInst MCInst;
+typedef struct cs_struct cs_struct;
+typedef struct MCOperand MCOperand;
+
+/// MCOperand - Instances of this class represent operands of the MCInst class.
+/// This is a simple discriminated union.
+struct MCOperand {
+       enum {
+               kInvalid = 0,                 ///< Uninitialized.
+               kRegister,                ///< Register operand.
+               kImmediate,               ///< Immediate operand.
+               kFPImmediate,             ///< Floating-point immediate operand.
+       } MachineOperandType;
+       unsigned char Kind;
+
+       union {
+               unsigned RegVal;
+               int64_t ImmVal;
+               double FPImmVal;
+       };
+};
+
+bool MCOperand_isValid(const MCOperand *op);
+
+bool MCOperand_isReg(const MCOperand *op);
+
+bool MCOperand_isImm(const MCOperand *op);
+
+bool MCOperand_isFPImm(const MCOperand *op);
+
+bool MCOperand_isInst(const MCOperand *op);
+
+void MCInst_clear(MCInst *m);
+
+/// getReg - Returns the register number.
+unsigned MCOperand_getReg(const MCOperand *op);
+
+/// setReg - Set the register number.
+void MCOperand_setReg(MCOperand *op, unsigned Reg);
+
+int64_t MCOperand_getImm(MCOperand *op);
+
+void MCOperand_setImm(MCOperand *op, int64_t Val);
+
+double MCOperand_getFPImm(const MCOperand *op);
+
+void MCOperand_setFPImm(MCOperand *op, double Val);
+
+const MCInst *MCOperand_getInst(const MCOperand *op);
+
+void MCOperand_setInst(MCOperand *op, const MCInst *Val);
+
+// create Reg operand in the next slot
+void MCOperand_CreateReg0(MCInst *inst, unsigned Reg);
+
+// create Reg operand use the last-unused slot
+MCOperand *MCOperand_CreateReg1(MCInst *inst, unsigned Reg);
+
+// create Imm operand in the next slot
+void MCOperand_CreateImm0(MCInst *inst, int64_t Val);
+
+// create Imm operand in the last-unused slot
+MCOperand *MCOperand_CreateImm1(MCInst *inst, int64_t Val);
+
+/// MCInst - Instances of this class represent a single low-level machine
+/// instruction.
+struct MCInst {
+       unsigned OpcodePub;
+       uint8_t size;   // number of operands
+       bool has_imm;   // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax
+       uint8_t op1_size; // size of 1st operand - for X86 Intel syntax
+       unsigned Opcode;
+       MCOperand Operands[48];
+       cs_insn *flat_insn;     // insn to be exposed to public
+       uint64_t address;       // address of this insn
+       cs_struct *csh; // save the main csh
+       uint8_t x86opsize;      // opsize for [mem] operand
+
+       // (Optional) instruction prefix, which can be up to 4 bytes.
+       // A prefix byte gets value 0 when irrelevant.
+       // This is copied from cs_x86 struct
+       uint8_t x86_prefix[4];
+       uint8_t imm_size;       // immediate size for X86_OP_IMM operand
+       bool writeback; // writeback for ARM
+       // operand access index for list of registers sharing the same access right (for ARM)
+       uint8_t ac_idx;
+       uint8_t popcode_adjust;   // Pseudo X86 instruction adjust
+       char assembly[8];       // for special instruction, so that we dont need printer
+       unsigned char evm_data[32];     // for EVM PUSH operand
+};
+
+void MCInst_Init(MCInst *inst);
+
+void MCInst_clear(MCInst *inst);
+
+// do not free operand after inserting
+void MCInst_insert0(MCInst *inst, int index, MCOperand *Op);
+
+void MCInst_setOpcode(MCInst *inst, unsigned Op);
+
+unsigned MCInst_getOpcode(const MCInst*);
+
+void MCInst_setOpcodePub(MCInst *inst, unsigned Op);
+
+unsigned MCInst_getOpcodePub(const MCInst*);
+
+MCOperand *MCInst_getOperand(MCInst *inst, unsigned i);
+
+unsigned MCInst_getNumOperands(const MCInst *inst);
+
+// This addOperand2 function doesnt free Op
+void MCInst_addOperand2(MCInst *inst, MCOperand *Op);
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/MCInstrDesc.c b/Source/ThirdParty/capstone/Source/MCInstrDesc.c
new file mode 100644 (file)
index 0000000..8186e1a
--- /dev/null
@@ -0,0 +1,18 @@
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#include "MCInstrDesc.h"
+
+/// isPredicate - Set if this is one of the operands that made up of
+/// the predicate operand that controls an isPredicable() instruction.
+bool MCOperandInfo_isPredicate(MCOperandInfo *m)
+{
+       return m->Flags & (1 << MCOI_Predicate);
+}
+
+/// isOptionalDef - Set if this operand is a optional def.
+///
+bool MCOperandInfo_isOptionalDef(MCOperandInfo *m)
+{
+       return m->Flags & (1 << MCOI_OptionalDef);
+}
diff --git a/Source/ThirdParty/capstone/Source/MCInstrDesc.h b/Source/ThirdParty/capstone/Source/MCInstrDesc.h
new file mode 100644 (file)
index 0000000..275ae77
--- /dev/null
@@ -0,0 +1,144 @@
+//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MCOperandInfo and MCInstrDesc classes, which
+// are used to describe target instructions and their operands.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_LLVM_MC_MCINSTRDESC_H
+#define CS_LLVM_MC_MCINSTRDESC_H
+
+#include "capstone/platform.h"
+
+//===----------------------------------------------------------------------===//
+// Machine Operand Flags and Description
+//===----------------------------------------------------------------------===//
+
+// Operand constraints
+enum MCOI_OperandConstraint {
+       MCOI_TIED_TO = 0,    // Must be allocated the same register as.
+       MCOI_EARLY_CLOBBER   // Operand is an early clobber register operand
+};
+
+/// OperandFlags - These are flags set on operands, but should be considered
+/// private, all access should go through the MCOperandInfo accessors.
+/// See the accessors for a description of what these are.
+enum MCOI_OperandFlags {
+       MCOI_LookupPtrRegClass = 0,
+       MCOI_Predicate,
+       MCOI_OptionalDef
+};
+
+/// Operand Type - Operands are tagged with one of the values of this enum.
+enum MCOI_OperandType {
+       MCOI_OPERAND_UNKNOWN,
+       MCOI_OPERAND_IMMEDIATE,
+       MCOI_OPERAND_REGISTER,
+       MCOI_OPERAND_MEMORY,
+       MCOI_OPERAND_PCREL
+};
+
+
+/// MCOperandInfo - This holds information about one operand of a machine
+/// instruction, indicating the register class for register operands, etc.
+///
+typedef struct MCOperandInfo {
+       /// RegClass - This specifies the register class enumeration of the operand
+       /// if the operand is a register.  If isLookupPtrRegClass is set, then this is
+       /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
+       /// get a dynamic register class.
+       int16_t RegClass;
+
+       /// Flags - These are flags from the MCOI::OperandFlags enum.
+       uint8_t Flags;
+
+       /// OperandType - Information about the type of the operand.
+       uint8_t OperandType;
+
+       /// Lower 16 bits are used to specify which constraints are set. The higher 16
+       /// bits are used to specify the value of constraints (4 bits each).
+       uint32_t Constraints;
+       /// Currently no other information.
+} MCOperandInfo;
+
+
+//===----------------------------------------------------------------------===//
+// Machine Instruction Flags and Description
+//===----------------------------------------------------------------------===//
+
+/// MCInstrDesc flags - These should be considered private to the
+/// implementation of the MCInstrDesc class.  Clients should use the predicate
+/// methods on MCInstrDesc, not use these directly.  These all correspond to
+/// bitfields in the MCInstrDesc::Flags field.
+enum {
+       MCID_Variadic = 0,
+       MCID_HasOptionalDef,
+       MCID_Pseudo,
+       MCID_Return,
+       MCID_Call,
+       MCID_Barrier,
+       MCID_Terminator,
+       MCID_Branch,
+       MCID_IndirectBranch,
+       MCID_Compare,
+       MCID_MoveImm,
+       MCID_Bitcast,
+       MCID_Select,
+       MCID_DelaySlot,
+       MCID_FoldableAsLoad,
+       MCID_MayLoad,
+       MCID_MayStore,
+       MCID_Predicable,
+       MCID_NotDuplicable,
+       MCID_UnmodeledSideEffects,
+       MCID_Commutable,
+       MCID_ConvertibleTo3Addr,
+       MCID_UsesCustomInserter,
+       MCID_HasPostISelHook,
+       MCID_Rematerializable,
+       MCID_CheapAsAMove,
+       MCID_ExtraSrcRegAllocReq,
+       MCID_ExtraDefRegAllocReq,
+       MCID_RegSequence,
+       MCID_ExtractSubreg,
+       MCID_InsertSubreg
+};
+
+/// MCInstrDesc - Describe properties that are true of each instruction in the
+/// target description file.  This captures information about side effects,
+/// register use and many other things.  There is one instance of this struct
+/// for each target instruction class, and the MachineInstr class points to
+/// this struct directly to describe itself.
+typedef struct MCInstrDesc {
+       unsigned short  Opcode;        // The opcode number
+       unsigned short  NumOperands;   // Num of args (may be more if variable_ops)
+       unsigned short  NumDefs;       // Num of args that are definitions
+       unsigned short  SchedClass;    // enum identifying instr sched class
+       unsigned short  Size;          // Number of bytes in encoding.
+       unsigned        Flags;         // Flags identifying machine instr class
+       uint64_t        TSFlags;       // Target Specific Flag values
+       uint16_t *ImplicitUses;  // Registers implicitly read by this instr
+       uint16_t *ImplicitDefs;  // Registers implicitly defined by this instr
+       MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands
+       uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any     
+       // A complex method to determine is a certain is deprecated or not, and return        
+       // the reason for deprecation.
+       //bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);           
+       unsigned ComplexDeprecationInfo;        // dummy field, just to satisfy initializer
+} MCInstrDesc;
+
+bool MCOperandInfo_isPredicate(MCOperandInfo *m);
+
+bool MCOperandInfo_isOptionalDef(MCOperandInfo *m);
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/MCRegisterInfo.c b/Source/ThirdParty/capstone/Source/MCRegisterInfo.c
new file mode 100644 (file)
index 0000000..026272b
--- /dev/null
@@ -0,0 +1,143 @@
+//=== MC/MCRegisterInfo.cpp - Target Register Description -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements MCRegisterInfo functions.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#include "MCRegisterInfo.h"
+
+/// DiffListIterator - Base iterator class that can traverse the
+/// differentially encoded register and regunit lists in DiffLists.
+/// Don't use this class directly, use one of the specialized sub-classes
+/// defined below.
+typedef struct DiffListIterator {
+       uint16_t Val;
+       MCPhysReg *List;
+} DiffListIterator;
+
+void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
+               MCRegisterDesc *D, unsigned NR,
+               unsigned RA, unsigned PC,
+               MCRegisterClass *C, unsigned NC,
+               uint16_t (*RURoots)[2], unsigned NRU,
+               MCPhysReg *DL,
+               char *Strings,
+               uint16_t *SubIndices, unsigned NumIndices,
+               uint16_t *RET)
+{
+       RI->Desc = D;
+       RI->NumRegs = NR;
+       RI->RAReg = RA;
+       RI->PCReg = PC;
+       RI->Classes = C;
+       RI->DiffLists = DL;
+       RI->RegStrings = Strings;
+       RI->NumClasses = NC;
+       RI->RegUnitRoots = RURoots;
+       RI->NumRegUnits = NRU;
+       RI->SubRegIndices = SubIndices;
+       RI->NumSubRegIndices = NumIndices;
+       RI->RegEncodingTable = RET;
+}
+
+static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, MCPhysReg *DiffList)
+{
+       d->Val = InitVal;
+       d->List = DiffList;
+}
+
+static uint16_t DiffListIterator_getVal(DiffListIterator *d)
+{
+       return d->Val;
+}
+
+static bool DiffListIterator_next(DiffListIterator *d)
+{
+       MCPhysReg D;
+
+       if (d->List == 0)
+               return false;
+
+       D = *d->List;
+       d->List++;
+       d->Val += D;
+
+       if (!D)
+               d->List = 0;
+
+       return (D != 0);
+}
+
+static bool DiffListIterator_isValid(DiffListIterator *d)
+{
+       return (d->List != 0);
+}
+
+unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, MCRegisterClass *RC)
+{
+       DiffListIterator iter;
+
+       if (Reg >= RI->NumRegs) {
+               return 0;
+       }
+
+       DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs);
+       DiffListIterator_next(&iter);
+
+       while(DiffListIterator_isValid(&iter)) {
+               uint16_t val = DiffListIterator_getVal(&iter);
+               if (MCRegisterClass_contains(RC, val) && Reg ==  MCRegisterInfo_getSubReg(RI, val, SubIdx))
+                       return val;
+
+               DiffListIterator_next(&iter);
+       }
+
+       return 0;
+}
+
+unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx)
+{
+       DiffListIterator iter;
+       uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;
+
+       DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs);
+       DiffListIterator_next(&iter);
+
+       while(DiffListIterator_isValid(&iter)) {
+               if (*SRI == Idx)
+                       return DiffListIterator_getVal(&iter);
+               DiffListIterator_next(&iter);
+               ++SRI;
+       }
+
+       return 0;
+}
+
+MCRegisterClass* MCRegisterInfo_getRegClass(MCRegisterInfo *RI, unsigned i)
+{
+       //assert(i < getNumRegClasses() && "Register Class ID out of range");
+       if (i >= RI->NumClasses)
+               return 0;
+       return &(RI->Classes[i]);
+}
+
+bool MCRegisterClass_contains(MCRegisterClass *c, unsigned Reg)
+{
+       unsigned InByte = Reg % 8;
+       unsigned Byte = Reg / 8;
+
+       if (Byte >= c->RegSetSize)
+               return false;
+
+       return (c->RegSet[Byte] & (1 << InByte)) != 0;
+}
diff --git a/Source/ThirdParty/capstone/Source/MCRegisterInfo.h b/Source/ThirdParty/capstone/Source/MCRegisterInfo.h
new file mode 100644 (file)
index 0000000..6d51e19
--- /dev/null
@@ -0,0 +1,116 @@
+//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file.  This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_LLVM_MC_MCREGISTERINFO_H
+#define CS_LLVM_MC_MCREGISTERINFO_H
+
+#include "capstone/platform.h"
+
+/// An unsigned integer type large enough to represent all physical registers,
+/// but not necessarily virtual registers.
+typedef uint16_t MCPhysReg;
+typedef MCPhysReg* iterator;
+
+typedef struct MCRegisterClass {
+       iterator RegsBegin;
+       uint8_t *RegSet;
+       uint32_t NameIdx;
+       uint16_t RegsSize;
+       uint16_t RegSetSize;
+       uint16_t ID;
+       uint16_t RegSize, Alignment; // Size & Alignment of register in bytes
+       int8_t CopyCost;
+       bool Allocatable;
+} MCRegisterClass;
+
+/// MCRegisterDesc - This record contains information about a particular
+/// register.  The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers
+/// of AX. The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are
+/// super-registers of AX.
+///
+typedef struct MCRegisterDesc {
+       uint32_t Name;      // Printable name for the reg (for debugging)
+       uint32_t SubRegs;   // Sub-register set, described above
+       uint32_t SuperRegs; // Super-register set, described above
+
+       // Offset into MCRI::SubRegIndices of a list of sub-register indices for each
+       // sub-register in SubRegs.
+       uint32_t SubRegIndices;
+
+       // RegUnits - Points to the list of register units. The low 4 bits holds the
+       // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
+       uint32_t RegUnits;
+
+       /// Index into list with lane mask sequences. The sequence contains a lanemask
+       /// for every register unit.
+       uint16_t RegUnitLaneMasks;
+} MCRegisterDesc;
+
+/// MCRegisterInfo base class - We assume that the target defines a static
+/// array of MCRegisterDesc objects that represent all of the machine
+/// registers that the target has.  As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+/// Note this class is designed to be a base class of TargetRegisterInfo, which
+/// is the interface used by codegen. However, specific targets *should never*
+/// specialize this class. MCRegisterInfo should only contain getters to access
+/// TableGen generated physical register data. It must not be extended with
+/// virtual methods.
+///
+typedef struct MCRegisterInfo {
+       MCRegisterDesc *Desc;                 // Pointer to the descriptor array
+       unsigned NumRegs;                           // Number of entries in the array
+       unsigned RAReg;                             // Return address register
+       unsigned PCReg;                             // Program counter register
+       MCRegisterClass *Classes;             // Pointer to the regclass array
+       unsigned NumClasses;                        // Number of entries in the array
+       unsigned NumRegUnits;                       // Number of regunits.
+       uint16_t (*RegUnitRoots)[2];          // Pointer to regunit root table.
+       MCPhysReg *DiffLists;                 // Pointer to the difflists array
+       char *RegStrings;                     // Pointer to the string table.
+       uint16_t *SubRegIndices;              // Pointer to the subreg lookup
+       // array.
+       unsigned NumSubRegIndices;                  // Number of subreg indices.
+       uint16_t *RegEncodingTable;           // Pointer to array of register
+       // encodings.
+} MCRegisterInfo;
+
+void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
+               MCRegisterDesc *D, unsigned NR, unsigned RA,
+               unsigned PC,
+               MCRegisterClass *C, unsigned NC,
+               uint16_t (*RURoots)[2],
+               unsigned NRU,
+               MCPhysReg *DL,
+               char *Strings,
+               uint16_t *SubIndices,
+               unsigned NumIndices,
+               uint16_t *RET);
+
+unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, MCRegisterClass *RC);
+
+unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx);
+
+MCRegisterClass* MCRegisterInfo_getRegClass(MCRegisterInfo *RI, unsigned i);
+
+bool MCRegisterClass_contains(MCRegisterClass *c, unsigned Reg);
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/Makefile b/Source/ThirdParty/capstone/Source/Makefile
new file mode 100644 (file)
index 0000000..e9838e2
--- /dev/null
@@ -0,0 +1,509 @@
+# Capstone Disassembly Engine
+# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014
+
+include config.mk
+include pkgconfig.mk   # package version
+include functions.mk
+
+# Verbose output?
+V ?= 0
+
+ifeq ($(PKG_EXTRA),)
+PKG_VERSION = $(PKG_MAJOR).$(PKG_MINOR)
+else
+PKG_VERSION = $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA)
+endif
+
+ifeq ($(CROSS),)
+CC ?= cc
+AR ?= ar
+RANLIB ?= ranlib
+STRIP ?= strip
+else
+CC = $(CROSS)gcc
+AR = $(CROSS)ar
+RANLIB = $(CROSS)ranlib
+STRIP = $(CROSS)strip
+endif
+
+ifneq (,$(findstring yes,$(CAPSTONE_DIET)))
+CFLAGS ?= -Os
+CFLAGS += -DCAPSTONE_DIET
+else
+CFLAGS ?= -O3
+endif
+
+ifneq (,$(findstring yes,$(CAPSTONE_X86_ATT_DISABLE)))
+CFLAGS += -DCAPSTONE_X86_ATT_DISABLE
+endif
+
+CFLAGS += -fPIC -Wall -Iinclude
+
+ifeq ($(CAPSTONE_USE_SYS_DYN_MEM),yes)
+CFLAGS += -DCAPSTONE_USE_SYS_DYN_MEM
+endif
+
+ifeq ($(CAPSTONE_HAS_OSXKERNEL), yes)
+CFLAGS += -DCAPSTONE_HAS_OSXKERNEL
+SDKROOT ?= $(shell xcodebuild -version -sdk macosx Path)
+CFLAGS += -mmacosx-version-min=10.5 \
+                 -isysroot$(SDKROOT) \
+                 -I$(SDKROOT)/System/Library/Frameworks/Kernel.framework/Headers \
+                 -mkernel \
+                 -fno-builtin
+endif
+
+PREFIX ?= /usr
+DESTDIR ?=
+ifndef BUILDDIR
+BLDIR = .
+OBJDIR = .
+else
+BLDIR = $(abspath $(BUILDDIR))
+OBJDIR = $(BLDIR)/obj
+endif
+INCDIR ?= $(PREFIX)/include
+
+UNAME_S := $(shell uname -s)
+
+LIBDIRARCH ?= lib
+# Uncomment the below line to installs x86_64 libs to lib64/ directory.
+# Or better, pass 'LIBDIRARCH=lib64' to 'make install/uninstall' via 'make.sh'.
+#LIBDIRARCH ?= lib64
+LIBDIR ?= $(PREFIX)/$(LIBDIRARCH)
+BINDIR = $(PREFIX)/bin
+
+LIBDATADIR ?= $(LIBDIR)
+
+# Don't redefine $LIBDATADIR when global environment variable
+# USE_GENERIC_LIBDATADIR is set. This is used by the pkgsrc framework.
+
+ifndef USE_GENERIC_LIBDATADIR
+ifeq ($(UNAME_S), FreeBSD)
+LIBDATADIR = $(PREFIX)/libdata
+endif
+ifeq ($(UNAME_S), DragonFly)
+LIBDATADIR = $(PREFIX)/libdata
+endif
+endif
+
+INSTALL_BIN ?= install
+INSTALL_DATA ?= $(INSTALL_BIN) -m0644
+INSTALL_LIB ?= $(INSTALL_BIN) -m0755
+
+LIBNAME = capstone
+
+
+DEP_ARM =
+DEP_ARM += $(wildcard arch/ARM/ARM*.inc)
+
+LIBOBJ_ARM =
+ifneq (,$(findstring arm,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_ARM
+       LIBSRC_ARM += $(wildcard arch/ARM/ARM*.c)
+       LIBOBJ_ARM += $(LIBSRC_ARM:%.c=$(OBJDIR)/%.o)
+endif
+
+DEP_ARM64 =
+DEP_ARM64 += $(wildcard arch/AArch64/AArch64*.inc)
+
+LIBOBJ_ARM64 =
+ifneq (,$(findstring aarch64,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_ARM64
+       LIBSRC_ARM64 += $(wildcard arch/AArch64/AArch64*.c)
+       LIBOBJ_ARM64 += $(LIBSRC_ARM64:%.c=$(OBJDIR)/%.o)
+endif
+
+
+DEP_M68K =
+DEP_M68K += $(wildcard arch/M68K/M68K*.h)
+
+LIBOBJ_M68K =
+ifneq (,$(findstring m68k,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_M68K
+       LIBSRC_M68K += $(wildcard arch/M68K/M68K*.c)
+       LIBOBJ_M68K += $(LIBSRC_M68K:%.c=$(OBJDIR)/%.o)
+endif
+
+DEP_MIPS =
+DEP_MIPS += $(wildcard arch/Mips/Mips*.inc)
+
+LIBOBJ_MIPS =
+ifneq (,$(findstring mips,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_MIPS
+       LIBSRC_MIPS += $(wildcard arch/Mips/Mips*.c)
+       LIBOBJ_MIPS += $(LIBSRC_MIPS:%.c=$(OBJDIR)/%.o)
+endif
+
+
+DEP_PPC =
+DEP_PPC += $(wildcard arch/PowerPC/PPC*.inc)
+
+LIBOBJ_PPC =
+ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_POWERPC
+       LIBSRC_PPC += $(wildcard arch/PowerPC/PPC*.c)
+       LIBOBJ_PPC += $(LIBSRC_PPC:%.c=$(OBJDIR)/%.o)
+endif
+
+
+DEP_SPARC =
+DEP_SPARC += $(wildcard arch/Sparc/Sparc*.inc)
+
+LIBOBJ_SPARC =
+ifneq (,$(findstring sparc,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_SPARC
+       LIBSRC_SPARC += $(wildcard arch/Sparc/Sparc*.c)
+       LIBOBJ_SPARC += $(LIBSRC_SPARC:%.c=$(OBJDIR)/%.o)
+endif
+
+
+DEP_SYSZ =
+DEP_SYSZ += $(wildcard arch/SystemZ/SystemZ*.inc)
+
+LIBOBJ_SYSZ =
+ifneq (,$(findstring systemz,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_SYSZ
+       LIBSRC_SYSZ += $(wildcard arch/SystemZ/SystemZ*.c)
+       LIBOBJ_SYSZ += $(LIBSRC_SYSZ:%.c=$(OBJDIR)/%.o)
+endif
+
+
+# by default, we compile full X86 instruction sets
+X86_REDUCE =
+ifneq (,$(findstring yes,$(CAPSTONE_X86_REDUCE)))
+X86_REDUCE = _reduce
+CFLAGS += -DCAPSTONE_X86_REDUCE -Os
+endif
+
+DEP_X86 =
+DEP_X86 += arch/X86/X86GenAsmWriter$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenAsmWriter1$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenDisassemblerTables$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenInstrInfo$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86GenRegisterInfo.inc
+DEP_X86 += arch/X86/X86MappingInsn$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86MappingInsnOp$(X86_REDUCE).inc
+DEP_X86 += arch/X86/X86ImmSize.inc
+
+LIBOBJ_X86 =
+ifneq (,$(findstring x86,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_X86
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86DisassemblerDecoder.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Disassembler.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86IntelInstPrinter.o
+# assembly syntax is irrelevant in Diet mode, when this info is suppressed
+ifeq (,$(findstring yes,$(CAPSTONE_DIET)))
+ifeq (,$(findstring yes,$(CAPSTONE_X86_ATT_DISABLE)))
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86ATTInstPrinter.o
+endif
+endif
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Mapping.o
+       LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Module.o
+endif
+
+
+DEP_XCORE =
+DEP_XCORE += $(wildcard arch/XCore/XCore*.inc)
+
+LIBOBJ_XCORE =
+ifneq (,$(findstring xcore,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_XCORE
+       LIBSRC_XCORE += $(wildcard arch/XCore/XCore*.c)
+       LIBOBJ_XCORE += $(LIBSRC_XCORE:%.c=$(OBJDIR)/%.o)
+endif
+
+
+DEP_TMS320C64X =
+DEP_TMS320C64X += $(wildcard arch/TMS320C64x/TMS320C64x*.inc)
+
+LIBOBJ_TMS320C64X =
+ifneq (,$(findstring tms320c64x,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_TMS320C64X
+       LIBSRC_TMS320C64X += $(wildcard arch/TMS320C64x/TMS320C64x*.c)
+       LIBOBJ_TMS320C64X += $(LIBSRC_TMS320C64X:%.c=$(OBJDIR)/%.o)
+endif
+
+DEP_M680X =
+DEP_M680X += $(wildcard arch/M680X/*.inc)
+DEP_M680X += $(wildcard arch/M680X/M680X*.h)
+
+LIBOBJ_M680X =
+ifneq (,$(findstring m680x,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_M680X
+       LIBSRC_M680X += $(wildcard arch/M680X/*.c)
+       LIBOBJ_M680X += $(LIBSRC_M680X:%.c=$(OBJDIR)/%.o)
+endif
+
+
+DEP_EVM =
+DEP_EVM += $(wildcard arch/EVM/EVM*.inc)
+
+LIBOBJ_EVM =
+ifneq (,$(findstring evm,$(CAPSTONE_ARCHS)))
+       CFLAGS += -DCAPSTONE_HAS_EVM
+       LIBSRC_EVM += $(wildcard arch/EVM/EVM*.c)
+       LIBOBJ_EVM += $(LIBSRC_EVM:%.c=$(OBJDIR)/%.o)
+endif
+
+
+LIBOBJ =
+LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o
+LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM)
+LIBOBJ += $(OBJDIR)/MCInst.o
+
+
+ifeq ($(PKG_EXTRA),)
+PKGCFGDIR = $(LIBDATADIR)/pkgconfig
+else
+PKGCFGDIR ?= $(LIBDATADIR)/pkgconfig
+ifeq ($(PKGCFGDIR),)
+PKGCFGDIR = $(LIBDATADIR)/pkgconfig
+endif
+endif
+
+API_MAJOR=$(shell echo `grep -e CS_API_MAJOR include/capstone/capstone.h | grep -v = | awk '{print $$3}'` | awk '{print $$1}')
+VERSION_EXT =
+
+IS_APPLE := $(shell $(CC) -dM -E - < /dev/null 2> /dev/null | grep __apple_build_version__ | wc -l | tr -d " ")
+ifeq ($(IS_APPLE),1)
+# on MacOS, compile in Universal format by default
+MACOS_UNIVERSAL ?= yes
+ifeq ($(MACOS_UNIVERSAL),yes)
+CFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch))
+LDFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch))
+endif
+EXT = dylib
+VERSION_EXT = $(API_MAJOR).$(EXT)
+$(LIBNAME)_LDFLAGS += -dynamiclib -install_name lib$(LIBNAME).$(VERSION_EXT) -current_version $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA) -compatibility_version $(PKG_MAJOR).$(PKG_MINOR)
+AR_EXT = a
+# Homebrew wants to make sure its formula does not disable FORTIFY_SOURCE
+# However, this is not really necessary because 'CAPSTONE_USE_SYS_DYN_MEM=yes' by default
+ifneq ($(HOMEBREW_CAPSTONE),1)
+ifneq ($(CAPSTONE_USE_SYS_DYN_MEM),yes)
+# remove string check because OSX kernel complains about missing symbols
+CFLAGS += -D_FORTIFY_SOURCE=0
+endif
+endif
+else
+CFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch))
+LDFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch))
+$(LIBNAME)_LDFLAGS += -shared
+# Cygwin?
+IS_CYGWIN := $(shell $(CC) -dumpmachine 2>/dev/null | grep -i cygwin | wc -l)
+ifeq ($(IS_CYGWIN),1)
+EXT = dll
+AR_EXT = lib
+# Cygwin doesn't like -fPIC
+CFLAGS := $(CFLAGS:-fPIC=)
+# On Windows we need the shared library to be executable
+else
+# mingw?
+IS_MINGW := $(shell $(CC) --version 2>/dev/null | grep -i mingw | wc -l)
+ifeq ($(IS_MINGW),1)
+EXT = dll
+AR_EXT = lib
+# mingw doesn't like -fPIC either
+CFLAGS := $(CFLAGS:-fPIC=)
+# On Windows we need the shared library to be executable
+else
+# Linux, *BSD
+EXT = so
+VERSION_EXT = $(EXT).$(API_MAJOR)
+AR_EXT = a
+$(LIBNAME)_LDFLAGS += -Wl,-soname,lib$(LIBNAME).$(VERSION_EXT)
+endif
+endif
+endif
+
+ifeq ($(CAPSTONE_SHARED),yes)
+ifeq ($(IS_MINGW),1)
+LIBRARY = $(BLDIR)/$(LIBNAME).$(VERSION_EXT)
+else ifeq ($(IS_CYGWIN),1)
+LIBRARY = $(BLDIR)/$(LIBNAME).$(VERSION_EXT)
+else   # *nix
+LIBRARY = $(BLDIR)/lib$(LIBNAME).$(VERSION_EXT)
+CFLAGS += -fvisibility=hidden
+endif
+endif
+
+ifeq ($(CAPSTONE_STATIC),yes)
+ifeq ($(IS_MINGW),1)
+ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT)
+else ifeq ($(IS_CYGWIN),1)
+ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT)
+else
+ARCHIVE = $(BLDIR)/lib$(LIBNAME).$(AR_EXT)
+endif
+endif
+
+PKGCFGF = $(BLDIR)/$(LIBNAME).pc
+
+.PHONY: all clean install uninstall dist
+
+all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF)
+ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
+       @V=$(V) CC=$(CC) $(MAKE) -C cstool
+ifndef BUILDDIR
+       cd tests && $(MAKE)
+else
+       cd tests && $(MAKE) BUILDDIR=$(BLDIR)
+endif
+       $(call install-library,$(BLDIR)/tests/)
+endif
+
+ifeq ($(CAPSTONE_SHARED),yes)
+$(LIBRARY): $(LIBOBJ)
+ifeq ($(V),0)
+       $(call log,LINK,$(@:$(BLDIR)/%=%))
+       @$(create-library)
+else
+       $(create-library)
+endif
+endif
+
+$(LIBOBJ): config.mk *.h include/capstone/*.h
+
+$(LIBOBJ_ARM): $(DEP_ARM)
+$(LIBOBJ_ARM64): $(DEP_ARM64)
+$(LIBOBJ_M68K): $(DEP_M68K)
+$(LIBOBJ_MIPS): $(DEP_MIPS)
+$(LIBOBJ_PPC): $(DEP_PPC)
+$(LIBOBJ_SPARC): $(DEP_SPARC)
+$(LIBOBJ_SYSZ): $(DEP_SYSZ)
+$(LIBOBJ_X86): $(DEP_X86)
+$(LIBOBJ_XCORE): $(DEP_XCORE)
+$(LIBOBJ_TMS320C64X): $(DEP_TMS320C64X)
+$(LIBOBJ_M680X): $(DEP_M680X)
+$(LIBOBJ_EVM): $(DEP_EVM)
+
+ifeq ($(CAPSTONE_STATIC),yes)
+$(ARCHIVE): $(LIBOBJ)
+       @rm -f $(ARCHIVE)
+ifeq ($(V),0)
+       $(call log,AR,$(@:$(BLDIR)/%=%))
+       @$(create-archive)
+else
+       $(create-archive)
+endif
+endif
+
+$(PKGCFGF):
+ifeq ($(V),0)
+       $(call log,GEN,$(@:$(BLDIR)/%=%))
+       @$(generate-pkgcfg)
+else
+       $(generate-pkgcfg)
+endif
+
+install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY)
+       mkdir -p $(DESTDIR)$(LIBDIR)
+       $(call install-library,$(DESTDIR)$(LIBDIR))
+ifeq ($(CAPSTONE_STATIC),yes)
+       $(INSTALL_DATA) $(ARCHIVE) $(DESTDIR)$(LIBDIR)
+endif
+       mkdir -p $(DESTDIR)$(INCDIR)/$(LIBNAME)
+       $(INSTALL_DATA) include/capstone/*.h $(DESTDIR)$(INCDIR)/$(LIBNAME)
+       mkdir -p $(DESTDIR)$(PKGCFGDIR)
+       $(INSTALL_DATA) $(PKGCFGF) $(DESTDIR)$(PKGCFGDIR)
+       mkdir -p $(DESTDIR)$(BINDIR)
+       $(INSTALL_LIB) cstool/cstool $(DESTDIR)$(BINDIR)
+
+uninstall:
+       rm -rf $(DESTDIR)$(INCDIR)/$(LIBNAME)
+       rm -f $(DESTDIR)$(LIBDIR)/lib$(LIBNAME).*
+       rm -f $(DESTDIR)$(PKGCFGDIR)/$(LIBNAME).pc
+       rm -f $(DESTDIR)$(BINDIR)/cstool
+
+clean:
+       rm -f $(LIBOBJ)
+       rm -f $(BLDIR)/lib$(LIBNAME).* $(BLDIR)/$(LIBNAME).pc
+       rm -f $(PKGCFGF)
+       $(MAKE) -C cstool clean
+
+ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
+       cd tests && $(MAKE) clean
+       rm -f $(BLDIR)/tests/lib$(LIBNAME).$(EXT)
+endif
+
+ifdef BUILDDIR
+       rm -rf $(BUILDDIR)
+endif
+
+ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY)))
+       cd bindings/python && $(MAKE) clean
+       cd bindings/java && $(MAKE) clean
+       cd bindings/ocaml && $(MAKE) clean
+endif
+
+
+TAG ?= HEAD
+ifeq ($(TAG), HEAD)
+DIST_VERSION = latest
+else
+DIST_VERSION = $(TAG)
+endif
+
+dist:
+       git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz
+       git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip
+
+
+TESTS = test_basic test_detail test_arm test_arm64 test_m68k test_mips test_ppc test_sparc
+TESTS += test_systemz test_x86 test_xcore test_iter
+TESTS += test_basic.static test_detail.static test_arm.static test_arm64.static
+TESTS += test_m68k.static test_mips.static test_ppc.static test_sparc.static
+TESTS += test_systemz.static test_x86.static test_xcore.static test_m680x.static
+TESTS += test_skipdata test_skipdata.static test_iter.static
+check:
+       @for t in $(TESTS); do \
+               echo Check $$t ... ; \
+               LD_LIBRARY_PATH=./tests ./tests/$$t > /dev/null && echo OK || echo FAILED; \
+       done
+
+$(OBJDIR)/%.o: %.c
+       @mkdir -p $(@D)
+ifeq ($(V),0)
+       $(call log,CC,$(@:$(OBJDIR)/%=%))
+       @$(compile)
+else
+       $(compile)
+endif
+
+
+ifeq ($(CAPSTONE_SHARED),yes)
+define install-library
+       $(INSTALL_LIB) $(LIBRARY) $1
+       $(if $(VERSION_EXT),
+               cd $1 && \
+               rm -f lib$(LIBNAME).$(EXT) && \
+               ln -s lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT))
+endef
+else
+define install-library
+endef
+endif
+
+
+define create-archive
+       $(AR) q $(ARCHIVE) $(LIBOBJ)
+       $(RANLIB) $(ARCHIVE)
+endef
+
+
+define create-library
+       $(CC) $(LDFLAGS) $($(LIBNAME)_LDFLAGS) $(LIBOBJ) -o $(LIBRARY)
+endef
+
+
+define generate-pkgcfg
+       mkdir -p $(BLDIR)
+       echo 'Name: capstone' > $(PKGCFGF)
+       echo 'Description: Capstone disassembly engine' >> $(PKGCFGF)
+       echo 'Version: $(PKG_VERSION)' >> $(PKGCFGF)
+       echo 'libdir=$(LIBDIR)' >> $(PKGCFGF)
+       echo 'includedir=$(INCDIR)' >> $(PKGCFGF)
+       echo 'archive=$${libdir}/libcapstone.a' >> $(PKGCFGF)
+       echo 'Libs: -L$${libdir} -lcapstone' >> $(PKGCFGF)
+       echo 'Cflags: -I$${includedir}' >> $(PKGCFGF)
+endef
diff --git a/Source/ThirdParty/capstone/Source/MathExtras.h b/Source/ThirdParty/capstone/Source/MathExtras.h
new file mode 100644 (file)
index 0000000..3292f73
--- /dev/null
@@ -0,0 +1,439 @@
+//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_LLVM_SUPPORT_MATHEXTRAS_H
+#define CS_LLVM_SUPPORT_MATHEXTRAS_H
+
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
+#include "windowsce/intrin.h"
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#endif
+
+#ifndef __cplusplus
+#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
+#define inline /* inline */
+#endif
+#endif
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+static inline uint32_t Hi_32(uint64_t Value) {
+       return (uint32_t)(Value >> 32);
+}
+
+/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+static inline uint32_t Lo_32(uint64_t Value) {
+       return (uint32_t)(Value);
+}
+
+/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
+/// bit width.
+static inline bool isUIntN(unsigned N, uint64_t x) {
+       return x == (x & (~0ULL >> (64 - N)));
+}
+
+/// isIntN - Checks if an signed integer fits into the given (dynamic)
+/// bit width.
+//static inline bool isIntN(unsigned N, int64_t x) {
+//  return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+//}
+
+/// isMask_32 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (32 bit
+/// version).   Ex. isMask_32(0x0000FFFFU) == true.
+static inline bool isMask_32(uint32_t Value) {
+       return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isMask_64 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (64 bit
+/// version).
+static inline bool isMask_64(uint64_t Value) {
+       return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isShiftedMask_32 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (32 bit version.)
+/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+static inline bool isShiftedMask_32(uint32_t Value) {
+       return isMask_32((Value - 1) | Value);
+}
+
+/// isShiftedMask_64 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (64 bit version.)
+static inline bool isShiftedMask_64(uint64_t Value) {
+       return isMask_64((Value - 1) | Value);
+}
+
+/// isPowerOf2_32 - This function returns true if the argument is a power of
+/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+static inline bool isPowerOf2_32(uint32_t Value) {
+       return Value && !(Value & (Value - 1));
+}
+
+/// CountLeadingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the most significant bit to the first one
+/// bit.  Ex. CountLeadingZeros_32(0x00F000FF) == 8.
+/// Returns 32 if the word is zero.
+static inline unsigned CountLeadingZeros_32(uint32_t Value) {
+       unsigned Count; // result
+#if __GNUC__ >= 4
+       // PowerPC is defined for __builtin_clz(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+       if (!Value) return 32;
+#endif
+       Count = __builtin_clz(Value);
+#else
+       unsigned Shift;
+       if (!Value) return 32;
+       Count = 0;
+       // bisection method for count leading zeros
+       for (Shift = 32 >> 1; Shift; Shift >>= 1) {
+               uint32_t Tmp = Value >> Shift;
+               if (Tmp) {
+                       Value = Tmp;
+               } else {
+                       Count |= Shift;
+               }
+       }
+#endif
+       return Count;
+}
+
+/// CountLeadingOnes_32 - this function performs the operation of
+/// counting the number of ones from the most significant bit to the first zero
+/// bit.  Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
+/// Returns 32 if the word is all ones.
+static inline unsigned CountLeadingOnes_32(uint32_t Value) {
+       return CountLeadingZeros_32(~Value);
+}
+
+/// CountLeadingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the most significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+static inline unsigned CountLeadingZeros_64(uint64_t Value) {
+       unsigned Count; // result
+#if __GNUC__ >= 4
+       // PowerPC is defined for __builtin_clzll(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+       if (!Value) return 64;
+#endif
+       Count = __builtin_clzll(Value);
+#else
+#ifndef _MSC_VER
+       unsigned Shift;
+       if (sizeof(long) == sizeof(int64_t))
+       {
+               if (!Value) return 64;
+               Count = 0;
+               // bisection method for count leading zeros
+               for (Shift = 64 >> 1; Shift; Shift >>= 1) {
+                       uint64_t Tmp = Value >> Shift;
+                       if (Tmp) {
+                               Value = Tmp;
+                       } else {
+                               Count |= Shift;
+                       }
+               }
+       }
+       else
+#endif
+       {
+               // get hi portion
+               uint32_t Hi = Hi_32(Value);
+
+               // if some bits in hi portion
+               if (Hi) {
+                       // leading zeros in hi portion plus all bits in lo portion
+                       Count = CountLeadingZeros_32(Hi);
+               } else {
+                       // get lo portion
+                       uint32_t Lo = Lo_32(Value);
+                       // same as 32 bit value
+                       Count = CountLeadingZeros_32(Lo)+32;
+               }
+       }
+#endif
+       return Count;
+}
+
+/// CountLeadingOnes_64 - This function performs the operation
+/// of counting the number of ones from the most significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+static inline unsigned CountLeadingOnes_64(uint64_t Value) {
+       return CountLeadingZeros_64(~Value);
+}
+
+/// CountTrailingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the least significant bit to the first one
+/// bit.  Ex. CountTrailingZeros_32(0xFF00FF00) == 8.
+/// Returns 32 if the word is zero.
+static inline unsigned CountTrailingZeros_32(uint32_t Value) {
+#if __GNUC__ >= 4
+       return Value ? __builtin_ctz(Value) : 32;
+#else
+       static const unsigned Mod37BitPosition[] = {
+               32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
+               4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
+               5, 20, 8, 19, 18
+       };
+       // Replace "-Value" by "1+~Value" in the following commented code to avoid 
+       // MSVC warning C4146
+       //    return Mod37BitPosition[(-Value & Value) % 37];
+       return Mod37BitPosition[((1 + ~Value) & Value) % 37];
+#endif
+}
+
+/// CountTrailingOnes_32 - this function performs the operation of
+/// counting the number of ones from the least significant bit to the first zero
+/// bit.  Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
+/// Returns 32 if the word is all ones.
+static inline unsigned CountTrailingOnes_32(uint32_t Value) {
+       return CountTrailingZeros_32(~Value);
+}
+
+/// CountTrailingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the least significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+static inline unsigned CountTrailingZeros_64(uint64_t Value) {
+#if __GNUC__ >= 4
+       return Value ? __builtin_ctzll(Value) : 64;
+#else
+       static const unsigned Mod67Position[] = {
+               64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54,
+               4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55,
+               47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27,
+               29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
+               7, 48, 35, 6, 34, 33, 0
+       };
+       // Replace "-Value" by "1+~Value" in the following commented code to avoid 
+       // MSVC warning C4146
+       //    return Mod67Position[(-Value & Value) % 67];
+       return Mod67Position[((1 + ~Value) & Value) % 67];
+#endif
+}
+
+/// CountTrailingOnes_64 - This function performs the operation
+/// of counting the number of ones from the least significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+static inline unsigned CountTrailingOnes_64(uint64_t Value) {
+       return CountTrailingZeros_64(~Value);
+}
+
+/// CountPopulation_32 - this function counts the number of set bits in a value.
+/// Ex. CountPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+static inline unsigned CountPopulation_32(uint32_t Value) {
+#if __GNUC__ >= 4
+       return __builtin_popcount(Value);
+#else
+       uint32_t v = Value - ((Value >> 1) & 0x55555555);
+       v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+       return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+/// CountPopulation_64 - this function counts the number of set bits in a value,
+/// (64 bit edition.)
+static inline unsigned CountPopulation_64(uint64_t Value) {
+#if __GNUC__ >= 4
+       return __builtin_popcountll(Value);
+#else
+       uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
+       v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+       v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+       return (uint64_t)((v * 0x0101010101010101ULL) >> 56);
+#endif
+}
+
+/// Log2_32 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (32 bit edition.)
+/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+static inline unsigned Log2_32(uint32_t Value) {
+       return 31 - CountLeadingZeros_32(Value);
+}
+
+/// Log2_64 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (64 bit edition.)
+static inline unsigned Log2_64(uint64_t Value) {
+       return 63 - CountLeadingZeros_64(Value);
+}
+
+/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 32 if the value is zero. (32 bit edition).
+/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+static inline unsigned Log2_32_Ceil(uint32_t Value) {
+       return 32-CountLeadingZeros_32(Value-1);
+}
+
+/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 64 if the value is zero. (64 bit edition.)
+static inline unsigned Log2_64_Ceil(uint64_t Value) {
+       return 64-CountLeadingZeros_64(Value-1);
+}
+
+/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
+/// values using Euclid's algorithm.
+static inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
+       while (B) {
+               uint64_t T = B;
+               B = A % B;
+               A = T;
+       }
+       return A;
+}
+
+/// BitsToDouble - This function takes a 64-bit integer and returns the bit
+/// equivalent double.
+static inline double BitsToDouble(uint64_t Bits) {
+       union {
+               uint64_t L;
+               double D;
+       } T;
+       T.L = Bits;
+       return T.D;
+}
+
+/// BitsToFloat - This function takes a 32-bit integer and returns the bit
+/// equivalent float.
+static inline float BitsToFloat(uint32_t Bits) {
+       union {
+               uint32_t I;
+               float F;
+       } T;
+       T.I = Bits;
+       return T.F;
+}
+
+/// DoubleToBits - This function takes a double and returns the bit
+/// equivalent 64-bit integer.  Note that copying doubles around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+static inline uint64_t DoubleToBits(double Double) {
+       union {
+               uint64_t L;
+               double D;
+       } T;
+       T.D = Double;
+       return T.L;
+}
+
+/// FloatToBits - This function takes a float and returns the bit
+/// equivalent 32-bit integer.  Note that copying floats around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+static inline uint32_t FloatToBits(float Float) {
+       union {
+               uint32_t I;
+               float F;
+       } T;
+       T.F = Float;
+       return T.I;
+}
+
+/// MinAlign - A and B are either alignments or offsets.  Return the minimum
+/// alignment that may be assumed after adding the two together.
+static inline uint64_t MinAlign(uint64_t A, uint64_t B) {
+       // The largest power of 2 that divides both A and B.
+       //
+       // Replace "-Value" by "1+~Value" in the following commented code to avoid 
+       // MSVC warning C4146
+       //    return (A | B) & -(A | B);
+       return (A | B) & (1 + ~(A | B));
+}
+
+/// NextPowerOf2 - Returns the next power of two (in 64-bits)
+/// that is strictly greater than A.  Returns zero on overflow.
+static inline uint64_t NextPowerOf2(uint64_t A) {
+       A |= (A >> 1);
+       A |= (A >> 2);
+       A |= (A >> 4);
+       A |= (A >> 8);
+       A |= (A >> 16);
+       A |= (A >> 32);
+       return A + 1;
+}
+
+/// Returns the next integer (mod 2**64) that is greater than or equal to
+/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
+///
+/// Examples:
+/// \code
+///   RoundUpToAlignment(5, 8) = 8
+///   RoundUpToAlignment(17, 8) = 24
+///   RoundUpToAlignment(~0LL, 8) = 0
+/// \endcode
+static inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
+       return ((Value + Align - 1) / Align) * Align;
+}
+
+/// Returns the offset to the next integer (mod 2**64) that is greater than
+/// or equal to \p Value and is a multiple of \p Align. \p Align must be
+/// non-zero.
+static inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
+       return RoundUpToAlignment(Value, Align) - Value;
+}
+
+/// abs64 - absolute value of a 64-bit int.  Not all environments support
+/// "abs" on whatever their name for the 64-bit int type is.  The absolute
+/// value of the largest negative number is undefined, as with "abs".
+static inline int64_t abs64(int64_t x) {
+       return (x < 0) ? -x : x;
+}
+
+/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
+/// Requires 0 < B <= 32.
+static inline int32_t SignExtend32(uint32_t X, unsigned B) {
+       return (int32_t)(X << (32 - B)) >> (32 - B);
+}
+
+/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
+/// Requires 0 < B <= 64.
+static inline int64_t SignExtend64(uint64_t X, unsigned B) {
+       return (int64_t)(X << (64 - B)) >> (64 - B);
+}
+
+/// \brief Count number of 0's from the most significant bit to the least
+///   stopping at the first 1.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
+///   valid arguments.
+static inline unsigned int countLeadingZeros(int x)
+{
+       unsigned count = 0;
+       int i;
+       const unsigned bits = sizeof(x) * 8;
+
+       for (i = bits; --i; ) {
+               if (x < 0) break;
+               count++;
+               x <<= 1;
+       }
+
+       return count;
+}
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/README.md b/Source/ThirdParty/capstone/Source/README.md
new file mode 100644 (file)
index 0000000..e25acef
--- /dev/null
@@ -0,0 +1,65 @@
+Capstone Engine
+===============
+
+[![Build Status](https://travis-ci.org/aquynh/capstone.svg?branch=next)](https://travis-ci.org/aquynh/capstone)
+[![Build status](https://ci.appveyor.com/api/projects/status/a4wvbn89wu3pinas/branch/next?svg=true)](https://ci.appveyor.com/project/aquynh/capstone/branch/next)
+
+Capstone is a disassembly framework with the target of becoming the ultimate
+disasm engine for binary analysis and reversing in the security community.
+
+Created by Nguyen Anh Quynh, then developed and maintained by a small community,
+Capstone offers some unparalleled features:
+
+- Support multiple hardware architectures: ARM, ARM64 (ARMv8), Ethereum VM, M68K,
+  Mips, PPC, Sparc, SystemZ, TMS320C64X, M680X, XCore and X86 (including X86_64).
+
+- Having clean/simple/lightweight/intuitive architecture-neutral API.
+
+- Provide details on disassembled instruction (called “decomposer” by others).
+
+- Provide semantics of the disassembled instruction, such as list of implicit
+  registers read & written.
+
+- Implemented in pure C language, with lightweight bindings for PHP, PowerShell,
+  Emacs, Haskell, Perl, Python, Ruby, C#, NodeJS, Java, GO, C++, OCaml, Lua,
+  Rust, Delphi, Free Pascal & Vala ready either in main code, or provided
+  externally by the community).
+
+- Native support for all popular platforms: Windows, Mac OSX, iOS, Android,
+  Linux, *BSD, Solaris, etc.
+
+- Thread-safe by design.
+
+- Special support for embedding into firmware or OS kernel.
+
+- High performance & suitable for malware analysis (capable of handling various
+  X86 malware tricks).
+
+- Distributed under the open source BSD license.
+
+Further information is available at http://www.capstone-engine.org
+
+
+Compile
+-------
+
+See COMPILE.TXT file for how to compile and install Capstone.
+
+
+Documentation
+-------------
+
+See docs/README for how to customize & program your own tools with Capstone.
+
+
+Hack
+----
+
+See HACK.TXT file for the structure of the source code.
+
+
+License
+-------
+
+This project is released under the BSD license. If you redistribute the binary
+or source code of Capstone, please attach file LICENSE.TXT with your products.
diff --git a/Source/ThirdParty/capstone/Source/RELEASE_NOTES b/Source/ThirdParty/capstone/Source/RELEASE_NOTES
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Source/ThirdParty/capstone/Source/SStream.c b/Source/ThirdParty/capstone/Source/SStream.c
new file mode 100644 (file)
index 0000000..a332f89
--- /dev/null
@@ -0,0 +1,166 @@
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#include <stdarg.h>
+#if defined(CAPSTONE_HAS_OSXKERNEL)
+#include <libkern/libkern.h>
+#else
+#include <stdio.h>
+#endif
+#include <string.h>
+
+#include <capstone/platform.h>
+
+#include "SStream.h"
+#include "cs_priv.h"
+#include "utils.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4996) // disable MSVC's warning on strcpy()
+#endif
+
+void SStream_Init(SStream *ss)
+{
+       ss->index = 0;
+       ss->buffer[0] = '\0';
+}
+
+void SStream_concat0(SStream *ss, char *s)
+{
+#ifndef CAPSTONE_DIET
+       unsigned int len = (unsigned int) strlen(s);
+
+       memcpy(ss->buffer + ss->index, s, len);
+       ss->index += len;
+       ss->buffer[ss->index] = '\0';
+#endif
+}
+
+void SStream_concat(SStream *ss, const char *fmt, ...)
+{
+#ifndef CAPSTONE_DIET
+       va_list ap;
+       int ret;
+
+       va_start(ap, fmt);
+       ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
+       va_end(ap);
+       ss->index += ret;
+#endif
+}
+
+// print number with prefix #
+void printInt64Bang(SStream *O, int64_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "#0x%"PRIx64, val);
+               else
+                       SStream_concat(O, "#%"PRIu64, val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "#-0x%"PRIx64, (uint64_t)-val);
+               else
+                       SStream_concat(O, "#-%"PRIu64, -val);
+       }
+}
+
+void printUInt64Bang(SStream *O, uint64_t val)
+{
+       if (val > HEX_THRESHOLD)
+               SStream_concat(O, "#0x%"PRIx64, val);
+       else
+               SStream_concat(O, "#%"PRIu64, val);
+}
+
+// print number
+void printInt64(SStream *O, int64_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "0x%"PRIx64, val);
+               else
+                       SStream_concat(O, "%"PRIu64, val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "-0x%"PRIx64, (uint64_t)-val);
+               else
+                       SStream_concat(O, "-%"PRIu64, -val);
+       }
+}
+
+// print number in decimal mode
+void printInt32BangDec(SStream *O, int32_t val)
+{
+       if (val >= 0)
+               SStream_concat(O, "#%u", val);
+       else
+               SStream_concat(O, "#-%u", (uint32_t)-val);
+}
+
+void printInt32Bang(SStream *O, int32_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "#0x%x", val);
+               else
+                       SStream_concat(O, "#%u", val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "#-0x%x", (uint32_t)-val);
+               else
+                       SStream_concat(O, "#-%u", -val);
+       }
+}
+
+void printInt32(SStream *O, int32_t val)
+{
+       if (val >= 0) {
+               if (val > HEX_THRESHOLD)
+                       SStream_concat(O, "0x%x", val);
+               else
+                       SStream_concat(O, "%u", val);
+       } else {
+               if (val <- HEX_THRESHOLD)
+                       SStream_concat(O, "-0x%x", (uint32_t)-val);
+               else
+                       SStream_concat(O, "-%u", -val);
+       }
+}
+
+void printUInt32Bang(SStream *O, uint32_t val)
+{
+       if (val > HEX_THRESHOLD)
+               SStream_concat(O, "#0x%x", val);
+       else
+               SStream_concat(O, "#%u", val);
+}
+
+void printUInt32(SStream *O, uint32_t val)
+{
+       if (val > HEX_THRESHOLD)
+               SStream_concat(O, "0x%x", val);
+       else
+               SStream_concat(O, "%u", val);
+}
+
+/*
+   int main()
+   {
+   SStream ss;
+   int64_t i;
+
+   SStream_Init(&ss);
+
+   SStream_concat(&ss, "hello ");
+   SStream_concat(&ss, "%d - 0x%x", 200, 16);
+
+   i = 123;
+   SStream_concat(&ss, " + %ld", i);
+   SStream_concat(&ss, "%s", "haaaaa");
+
+   printf("%s\n", ss.buffer);
+
+   return 0;
+   }
+ */
diff --git a/Source/ThirdParty/capstone/Source/SStream.h b/Source/ThirdParty/capstone/Source/SStream.h
new file mode 100644 (file)
index 0000000..9ccd351
--- /dev/null
@@ -0,0 +1,37 @@
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_SSTREAM_H_
+#define CS_SSTREAM_H_
+
+#include "include/capstone/platform.h"
+
+typedef struct SStream {
+       char buffer[512];
+       int index;
+} SStream;
+
+void SStream_Init(SStream *ss);
+
+void SStream_concat(SStream *ss, const char *fmt, ...);
+
+void SStream_concat0(SStream *ss, char *s);
+
+void printInt64Bang(SStream *O, int64_t val);
+
+void printUInt64Bang(SStream *O, uint64_t val);
+
+void printInt64(SStream *O, int64_t val);
+
+void printInt32Bang(SStream *O, int32_t val);
+
+void printInt32(SStream *O, int32_t val);
+
+void printUInt32Bang(SStream *O, uint32_t val);
+
+void printUInt32(SStream *O, uint32_t val);
+
+// print number in decimal mode
+void printInt32BangDec(SStream *O, int32_t val);
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/TODO b/Source/ThirdParty/capstone/Source/TODO
new file mode 100644 (file)
index 0000000..e7117ee
--- /dev/null
@@ -0,0 +1,16 @@
+Issues to be solved in next versions
+
+
+[Core]
+
+- X86 can already handle all the malware tricks we are aware of. If you find
+  any such instruction sequence that Capstone disassembles wrongly or fails
+  completely, please report. Fixing this issue is always the top priority of
+  our project.
+
+- More optimization for better performance.
+
+
+[Bindings]
+
+- OCaml binding is working, but still needs to support the core API better.
diff --git a/Source/ThirdParty/capstone/Source/arch/ARM/ARMAddressingModes.h b/Source/ThirdParty/capstone/Source/arch/ARM/ARMAddressingModes.h
new file mode 100644 (file)
index 0000000..d4540bb
--- /dev/null
@@ -0,0 +1,670 @@
+//===-- ARMAddressingModes.h - ARM Addressing Modes -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the ARM addressing mode implementation stuff.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
+#define CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
+
+#include "capstone/platform.h"
+#include "../../MathExtras.h"
+
+/// ARM_AM - ARM Addressing Mode Stuff
+typedef enum ARM_AM_ShiftOpc {
+       ARM_AM_no_shift = 0,
+       ARM_AM_asr,
+       ARM_AM_lsl,
+       ARM_AM_lsr,
+       ARM_AM_ror,
+       ARM_AM_rrx
+} ARM_AM_ShiftOpc;
+
+typedef enum ARM_AM_AddrOpc {
+       ARM_AM_sub = 0,
+       ARM_AM_add
+} ARM_AM_AddrOpc;
+
+static inline char *ARM_AM_getAddrOpcStr(ARM_AM_AddrOpc Op)
+{
+       return Op == ARM_AM_sub ? "-" : "";
+}
+
+static inline char *ARM_AM_getShiftOpcStr(ARM_AM_ShiftOpc Op)
+{
+       switch (Op) {
+               default: return "";     //llvm_unreachable("Unknown shift opc!");
+               case ARM_AM_asr: return "asr";
+               case ARM_AM_lsl: return "lsl";
+               case ARM_AM_lsr: return "lsr";
+               case ARM_AM_ror: return "ror";
+               case ARM_AM_rrx: return "rrx";
+       }
+}
+
+static inline unsigned ARM_AM_getShiftOpcEncoding(ARM_AM_ShiftOpc Op)
+{
+       switch (Op) {
+               default: return (unsigned int)-1;       //llvm_unreachable("Unknown shift opc!");
+               case ARM_AM_asr: return 2;
+               case ARM_AM_lsl: return 0;
+               case ARM_AM_lsr: return 1;
+               case ARM_AM_ror: return 3;
+       }
+}
+
+typedef enum ARM_AM_AMSubMode {
+       ARM_AM_bad_am_submode = 0,
+       ARM_AM_ia,
+       ARM_AM_ib,
+       ARM_AM_da,
+       ARM_AM_db
+} ARM_AM_AMSubMode;
+
+static inline const char *ARM_AM_getAMSubModeStr(ARM_AM_AMSubMode Mode)
+{
+       switch (Mode) {
+               default: return "";
+               case ARM_AM_ia: return "ia";
+               case ARM_AM_ib: return "ib";
+               case ARM_AM_da: return "da";
+               case ARM_AM_db: return "db";
+       }
+}
+
+/// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
+///
+static inline unsigned rotr32(unsigned Val, unsigned Amt)
+{
+       //assert(Amt < 32 && "Invalid rotate amount");
+       return (Val >> Amt) | (Val << ((32-Amt)&31));
+}
+
+/// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
+///
+static inline unsigned rotl32(unsigned Val, unsigned Amt)
+{
+       //assert(Amt < 32 && "Invalid rotate amount");
+       return (Val << Amt) | (Val >> ((32-Amt)&31));
+}
+
+//===--------------------------------------------------------------------===//
+// Addressing Mode #1: shift_operand with registers
+//===--------------------------------------------------------------------===//
+//
+// This 'addressing mode' is used for arithmetic instructions.  It can
+// represent things like:
+//   reg
+//   reg [asr|lsl|lsr|ror|rrx] reg
+//   reg [asr|lsl|lsr|ror|rrx] imm
+//
+// This is stored three operands [rega, regb, opc].  The first is the base
+// reg, the second is the shift amount (or reg0 if not present or imm).  The
+// third operand encodes the shift opcode and the imm if a reg isn't present.
+//
+static inline unsigned getSORegOpc(ARM_AM_ShiftOpc ShOp, unsigned Imm)
+{
+       return ShOp | (Imm << 3);
+}
+
+static inline unsigned getSORegOffset(unsigned Op)
+{
+       return Op >> 3;
+}
+
+static inline ARM_AM_ShiftOpc ARM_AM_getSORegShOp(unsigned Op)
+{
+       return (ARM_AM_ShiftOpc)(Op & 7);
+}
+
+/// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
+/// the 8-bit imm value.
+static inline unsigned getSOImmValImm(unsigned Imm)
+{
+       return Imm & 0xFF;
+}
+
+/// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
+/// the rotate amount.
+static inline unsigned getSOImmValRot(unsigned Imm)
+{
+       return (Imm >> 8) * 2;
+}
+
+/// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
+/// computing the rotate amount to use.  If this immediate value cannot be
+/// handled with a single shifter-op, determine a good rotate amount that will
+/// take a maximal chunk of bits out of the immediate.
+static inline unsigned getSOImmValRotate(unsigned Imm)
+{
+       unsigned TZ, RotAmt;
+       // 8-bit (or less) immediates are trivially shifter_operands with a rotate
+       // of zero.
+       if ((Imm & ~255U) == 0) return 0;
+
+       // Use CTZ to compute the rotate amount.
+       TZ = CountTrailingZeros_32(Imm);
+
+       // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits,
+       // not 9.
+       RotAmt = TZ & ~1;
+
+       // If we can handle this spread, return it.
+       if ((rotr32(Imm, RotAmt) & ~255U) == 0)
+               return (32-RotAmt)&31;  // HW rotates right, not left.
+
+       // For values like 0xF000000F, we should ignore the low 6 bits, then
+       // retry the hunt.
+       if (Imm & 63U) {
+               unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
+               unsigned RotAmt2 = TZ2 & ~1;
+               if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
+                       return (32-RotAmt2)&31;  // HW rotates right, not left.
+       }
+
+       // Otherwise, we have no way to cover this span of bits with a single
+       // shifter_op immediate.  Return a chunk of bits that will be useful to
+       // handle.
+       return (32-RotAmt)&31;  // HW rotates right, not left.
+}
+
+/// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
+/// into an shifter_operand immediate operand, return the 12-bit encoding for
+/// it.  If not, return -1.
+static inline int getSOImmVal(unsigned Arg)
+{
+       unsigned RotAmt;
+       // 8-bit (or less) immediates are trivially shifter_operands with a rotate
+       // of zero.
+       if ((Arg & ~255U) == 0) return Arg;
+
+       RotAmt = getSOImmValRotate(Arg);
+
+       // If this cannot be handled with a single shifter_op, bail out.
+       if (rotr32(~255U, RotAmt) & Arg)
+               return -1;
+
+       // Encode this correctly.
+       return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
+}
+
+/// isSOImmTwoPartVal - Return true if the specified value can be obtained by
+/// or'ing together two SOImmVal's.
+static inline bool isSOImmTwoPartVal(unsigned V)
+{
+       // If this can be handled with a single shifter_op, bail out.
+       V = rotr32(~255U, getSOImmValRotate(V)) & V;
+       if (V == 0)
+               return false;
+
+       // If this can be handled with two shifter_op's, accept.
+       V = rotr32(~255U, getSOImmValRotate(V)) & V;
+       return V == 0;
+}
+
+/// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
+/// return the first chunk of it.
+static inline unsigned getSOImmTwoPartFirst(unsigned V)
+{
+       return rotr32(255U, getSOImmValRotate(V)) & V;
+}
+
+/// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
+/// return the second chunk of it.
+static inline unsigned getSOImmTwoPartSecond(unsigned V)
+{
+       // Mask out the first hunk.
+       V = rotr32(~255U, getSOImmValRotate(V)) & V;
+
+       // Take what's left.
+       //assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
+       return V;
+}
+
+/// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
+/// by a left shift. Returns the shift amount to use.
+static inline unsigned getThumbImmValShift(unsigned Imm)
+{
+       // 8-bit (or less) immediates are trivially immediate operand with a shift
+       // of zero.
+       if ((Imm & ~255U) == 0) return 0;
+
+       // Use CTZ to compute the shift amount.
+       return CountTrailingZeros_32(Imm);
+}
+
+/// isThumbImmShiftedVal - Return true if the specified value can be obtained
+/// by left shifting a 8-bit immediate.
+static inline bool isThumbImmShiftedVal(unsigned V)
+{
+       // If this can be handled with
+       V = (~255U << getThumbImmValShift(V)) & V;
+       return V == 0;
+}
+
+/// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
+/// by a left shift. Returns the shift amount to use.
+static inline unsigned getThumbImm16ValShift(unsigned Imm)
+{
+       // 16-bit (or less) immediates are trivially immediate operand with a shift
+       // of zero.
+       if ((Imm & ~65535U) == 0) return 0;
+
+       // Use CTZ to compute the shift amount.
+       return CountTrailingZeros_32(Imm);
+}
+
+/// isThumbImm16ShiftedVal - Return true if the specified value can be
+/// obtained by left shifting a 16-bit immediate.
+static inline bool isThumbImm16ShiftedVal(unsigned V)
+{
+       // If this can be handled with
+       V = (~65535U << getThumbImm16ValShift(V)) & V;
+       return V == 0;
+}
+
+/// getThumbImmNonShiftedVal - If V is a value that satisfies
+/// isThumbImmShiftedVal, return the non-shiftd value.
+static inline unsigned getThumbImmNonShiftedVal(unsigned V)
+{
+       return V >> getThumbImmValShift(V);
+}
+
+
+/// getT2SOImmValSplat - Return the 12-bit encoded representation
+/// if the specified value can be obtained by splatting the low 8 bits
+/// into every other byte or every byte of a 32-bit value. i.e.,
+///     00000000 00000000 00000000 abcdefgh    control = 0
+///     00000000 abcdefgh 00000000 abcdefgh    control = 1
+///     abcdefgh 00000000 abcdefgh 00000000    control = 2
+///     abcdefgh abcdefgh abcdefgh abcdefgh    control = 3
+/// Return -1 if none of the above apply.
+/// See ARM Reference Manual A6.3.2.
+static inline int getT2SOImmValSplatVal(unsigned V)
+{
+       unsigned u, Vs, Imm;
+       // control = 0
+       if ((V & 0xffffff00) == 0)
+               return V;
+
+       // If the value is zeroes in the first byte, just shift those off
+       Vs = ((V & 0xff) == 0) ? V >> 8 : V;
+       // Any passing value only has 8 bits of payload, splatted across the word
+       Imm = Vs & 0xff;
+       // Likewise, any passing values have the payload splatted into the 3rd byte
+       u = Imm | (Imm << 16);
+
+       // control = 1 or 2
+       if (Vs == u)
+               return (((Vs == V) ? 1 : 2) << 8) | Imm;
+
+       // control = 3
+       if (Vs == (u | (u << 8)))
+               return (3 << 8) | Imm;
+
+       return -1;
+}
+
+/// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
+/// specified value is a rotated 8-bit value. Return -1 if no rotation
+/// encoding is possible.
+/// See ARM Reference Manual A6.3.2.
+static inline int getT2SOImmValRotateVal(unsigned V)
+{
+       unsigned RotAmt = CountLeadingZeros_32(V);
+       if (RotAmt >= 24)
+               return -1;
+
+       // If 'Arg' can be handled with a single shifter_op return the value.
+       if ((rotr32(0xff000000U, RotAmt) & V) == V)
+               return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);
+
+       return -1;
+}
+
+/// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
+/// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
+/// encoding for it.  If not, return -1.
+/// See ARM Reference Manual A6.3.2.
+static inline int getT2SOImmVal(unsigned Arg)
+{
+       int Rot;
+       // If 'Arg' is an 8-bit splat, then get the encoded value.
+       int Splat = getT2SOImmValSplatVal(Arg);
+       if (Splat != -1)
+               return Splat;
+
+       // If 'Arg' can be handled with a single shifter_op return the value.
+       Rot = getT2SOImmValRotateVal(Arg);
+       if (Rot != -1)
+               return Rot;
+
+       return -1;
+}
+
+static inline unsigned getT2SOImmValRotate(unsigned V)
+{
+       unsigned RotAmt;
+
+       if ((V & ~255U) == 0)
+               return 0;
+
+       // Use CTZ to compute the rotate amount.
+       RotAmt = CountTrailingZeros_32(V);
+       return (32 - RotAmt) & 31;
+}
+
+static inline bool isT2SOImmTwoPartVal (unsigned Imm)
+{
+       unsigned V = Imm;
+       // Passing values can be any combination of splat values and shifter
+       // values. If this can be handled with a single shifter or splat, bail
+       // out. Those should be handled directly, not with a two-part val.
+       if (getT2SOImmValSplatVal(V) != -1)
+               return false;
+       V = rotr32 (~255U, getT2SOImmValRotate(V)) & V;
+       if (V == 0)
+               return false;
+
+       // If this can be handled as an immediate, accept.
+       if (getT2SOImmVal(V) != -1) return true;
+
+       // Likewise, try masking out a splat value first.
+       V = Imm;
+       if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
+               V &= ~0xff00ff00U;
+       else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
+               V &= ~0x00ff00ffU;
+       // If what's left can be handled as an immediate, accept.
+       if (getT2SOImmVal(V) != -1) return true;
+
+       // Otherwise, do not accept.
+       return false;
+}
+
+static inline unsigned getT2SOImmTwoPartFirst(unsigned Imm)
+{
+       //assert (isT2SOImmTwoPartVal(Imm) &&
+       //        "Immedate cannot be encoded as two part immediate!");
+       // Try a shifter operand as one part
+       unsigned V = rotr32 (~(unsigned int)255, getT2SOImmValRotate(Imm)) & Imm;
+       // If the rest is encodable as an immediate, then return it.
+       if (getT2SOImmVal(V) != -1) return V;
+
+       // Try masking out a splat value first.
+       if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
+               return Imm & 0xff00ff00U;
+
+       // The other splat is all that's left as an option.
+       //assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1);
+       return Imm & 0x00ff00ffU;
+}
+
+static inline unsigned getT2SOImmTwoPartSecond(unsigned Imm)
+{
+       // Mask out the first hunk
+       Imm ^= getT2SOImmTwoPartFirst(Imm);
+       // Return what's left
+       //assert (getT2SOImmVal(Imm) != -1 &&
+       //        "Unable to encode second part of T2 two part SO immediate");
+       return Imm;
+}
+
+
+//===--------------------------------------------------------------------===//
+// Addressing Mode #2
+//===--------------------------------------------------------------------===//
+//
+// This is used for most simple load/store instructions.
+//
+// addrmode2 := reg +/- reg shop imm
+// addrmode2 := reg +/- imm12
+//
+// The first operand is always a Reg.  The second operand is a reg if in
+// reg/reg form, otherwise it's reg#0.  The third field encodes the operation
+// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
+// fourth operand 16-17 encodes the index mode.
+//
+// If this addressing mode is a frame index (before prolog/epilog insertion
+// and code rewriting), this operand will have the form:  FI#, reg0, <offs>
+// with no shift amount for the frame offset.
+//
+static inline unsigned ARM_AM_getAM2Opc(ARM_AM_AddrOpc Opc, unsigned Imm12, ARM_AM_ShiftOpc SO,
+               unsigned IdxMode)
+{
+       //assert(Imm12 < (1 << 12) && "Imm too large!");
+       bool isSub = Opc == ARM_AM_sub;
+       return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
+}
+
+static inline unsigned getAM2Offset(unsigned AM2Opc)
+{
+       return AM2Opc & ((1 << 12)-1);
+}
+
+static inline ARM_AM_AddrOpc getAM2Op(unsigned AM2Opc)
+{
+       return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
+}
+
+static inline ARM_AM_ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
+{
+       return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
+}
+
+static inline unsigned getAM2IdxMode(unsigned AM2Opc)
+{
+       return (AM2Opc >> 16);
+}
+
+//===--------------------------------------------------------------------===//
+// Addressing Mode #3
+//===--------------------------------------------------------------------===//
+//
+// This is used for sign-extending loads, and load/store-pair instructions.
+//
+// addrmode3 := reg +/- reg
+// addrmode3 := reg +/- imm8
+//
+// The first operand is always a Reg.  The second operand is a reg if in
+// reg/reg form, otherwise it's reg#0.  The third field encodes the operation
+// in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
+// index mode.
+
+/// getAM3Opc - This function encodes the addrmode3 opc field.
+static inline unsigned getAM3Opc(ARM_AM_AddrOpc Opc, unsigned char Offset,
+               unsigned IdxMode)
+{
+       bool isSub = Opc == ARM_AM_sub;
+       return ((int)isSub << 8) | Offset | (IdxMode << 9);
+}
+
+static inline unsigned char getAM3Offset(unsigned AM3Opc)
+{
+       return AM3Opc & 0xFF;
+}
+
+static inline ARM_AM_AddrOpc getAM3Op(unsigned AM3Opc)
+{
+       return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
+}
+
+static inline unsigned getAM3IdxMode(unsigned AM3Opc)
+{
+       return (AM3Opc >> 9);
+}
+
+//===--------------------------------------------------------------------===//
+// Addressing Mode #4
+//===--------------------------------------------------------------------===//
+//
+// This is used for load / store multiple instructions.
+//
+// addrmode4 := reg, <mode>
+//
+// The four modes are:
+//    IA - Increment after
+//    IB - Increment before
+//    DA - Decrement after
+//    DB - Decrement before
+// For VFP instructions, only the IA and DB modes are valid.
+
+static inline ARM_AM_AMSubMode getAM4SubMode(unsigned Mode)
+{
+       return (ARM_AM_AMSubMode)(Mode & 0x7);
+}
+
+static inline unsigned getAM4ModeImm(ARM_AM_AMSubMode SubMode)
+{
+       return (int)SubMode;
+}
+
+//===--------------------------------------------------------------------===//
+// Addressing Mode #5
+//===--------------------------------------------------------------------===//
+//
+// This is used for coprocessor instructions, such as FP load/stores.
+//
+// addrmode5 := reg +/- imm8*4
+//
+// The first operand is always a Reg.  The second operand encodes the
+// operation in bit 8 and the immediate in bits 0-7.
+
+/// getAM5Opc - This function encodes the addrmode5 opc field.
+static inline unsigned ARM_AM_getAM5Opc(ARM_AM_AddrOpc Opc, unsigned char Offset)
+{
+       bool isSub = Opc == ARM_AM_sub;
+       return ((int)isSub << 8) | Offset;
+}
+static inline unsigned char ARM_AM_getAM5Offset(unsigned AM5Opc)
+{
+       return AM5Opc & 0xFF;
+}
+static inline ARM_AM_AddrOpc ARM_AM_getAM5Op(unsigned AM5Opc)
+{
+       return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
+}
+
+//===--------------------------------------------------------------------===//
+// Addressing Mode #6
+//===--------------------------------------------------------------------===//
+//
+// This is used for NEON load / store instructions.
+//
+// addrmode6 := reg with optional alignment
+//
+// This is stored in two operands [regaddr, align].  The first is the
+// address register.  The second operand is the value of the alignment
+// specifier in bytes or zero if no explicit alignment.
+// Valid alignments depend on the specific instruction.
+
+//===--------------------------------------------------------------------===//
+// NEON Modified Immediates
+//===--------------------------------------------------------------------===//
+//
+// Several NEON instructions (e.g., VMOV) take a "modified immediate"
+// vector operand, where a small immediate encoded in the instruction
+// specifies a full NEON vector value.  These modified immediates are
+// represented here as encoded integers.  The low 8 bits hold the immediate
+// value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
+// the "Cmode" field of the instruction.  The interfaces below treat the
+// Op and Cmode values as a single 5-bit value.
+
+static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val)
+{
+       return (OpCmode << 8) | Val;
+}
+static inline unsigned getNEONModImmOpCmode(unsigned ModImm)
+{
+       return (ModImm >> 8) & 0x1f;
+}
+static inline unsigned getNEONModImmVal(unsigned ModImm)
+{
+       return ModImm & 0xff;
+}
+
+/// decodeNEONModImm - Decode a NEON modified immediate value into the
+/// element value and the element size in bits.  (If the element size is
+/// smaller than the vector, it is splatted into all the elements.)
+static inline uint64_t ARM_AM_decodeNEONModImm(unsigned ModImm, unsigned *EltBits)
+{
+       unsigned OpCmode = getNEONModImmOpCmode(ModImm);
+       unsigned Imm8 = getNEONModImmVal(ModImm);
+       uint64_t Val = 0;
+       unsigned ByteNum;
+
+       if (OpCmode == 0xe) {
+               // 8-bit vector elements
+               Val = Imm8;
+               *EltBits = 8;
+       } else if ((OpCmode & 0xc) == 0x8) {
+               // 16-bit vector elements
+               ByteNum = (OpCmode & 0x6) >> 1;
+               Val = (uint64_t)Imm8 << (8 * ByteNum);
+               *EltBits = 16;
+       } else if ((OpCmode & 0x8) == 0) {
+               // 32-bit vector elements, zero with one byte set
+               ByteNum = (OpCmode & 0x6) >> 1;
+               Val = (uint64_t)Imm8 << (8 * ByteNum);
+               *EltBits = 32;
+       } else if ((OpCmode & 0xe) == 0xc) {
+               // 32-bit vector elements, one byte with low bits set
+               ByteNum = 1 + (OpCmode & 0x1);
+               Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
+               *EltBits = 32;
+       } else if (OpCmode == 0x1e) {
+               // 64-bit vector elements
+               for (ByteNum = 0; ByteNum < 8; ++ByteNum) {
+                       if ((ModImm >> ByteNum) & 1)
+                               Val |= (uint64_t)0xff << (8 * ByteNum);
+               }
+               *EltBits = 64;
+       } else {
+               //llvm_unreachable("Unsupported NEON immediate");
+       }
+       return Val;
+}
+
+ARM_AM_AMSubMode getLoadStoreMultipleSubMode(int Opcode);
+
+//===--------------------------------------------------------------------===//
+// Floating-point Immediates
+//
+static inline float getFPImmFloat(unsigned Imm)
+{
+       // We expect an 8-bit binary encoding of a floating-point number here.
+       union {
+               uint32_t I;
+               float F;
+       } FPUnion;
+
+       uint8_t Sign = (Imm >> 7) & 0x1;
+       uint8_t Exp = (Imm >> 4) & 0x7;
+       uint8_t Mantissa = Imm & 0xf;
+
+       //   8-bit FP    iEEEE Float Encoding
+       //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
+       //
+       // where B = NOT(b);
+
+       FPUnion.I = 0;
+       FPUnion.I |= Sign << 31;
+       FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
+       FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
+       FPUnion.I |= (Exp & 0x3) << 23;
+       FPUnion.I |= Mantissa << 19;
+       return FPUnion.F;
+}
+
+#endif
+
diff --git a/Source/ThirdParty/capstone/Source/arch/ARM/ARMBaseInfo.h b/Source/ThirdParty/capstone/Source/arch/ARM/ARMBaseInfo.h
new file mode 100644 (file)
index 0000000..9fc4979
--- /dev/null
@@ -0,0 +1,432 @@
+//===-- ARMBaseInfo.h - Top level definitions for ARM -------- --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains small standalone helper functions and enum definitions for
+// the ARM target useful for the compiler back-end and the MC libraries.
+// As such, it deliberately does not include references to LLVM core
+// code gen types, passes, etc..
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifndef CS_ARMBASEINFO_H
+#define CS_ARMBASEINFO_H
+
+#include "capstone/arm.h"
+
+// Defines symbolic names for ARM registers.  This defines a mapping from
+// register name to register number.
+//
+#define GET_REGINFO_ENUM
+#include "ARMGenRegisterInfo.inc"
+
+// Enums corresponding to ARM condition codes
+// The CondCodes constants map directly to the 4-bit encoding of the
+// condition field for predicated instructions.
+typedef enum ARMCC_CondCodes { // Meaning (integer)          Meaning (floating-point)
+       ARMCC_EQ,            // Equal                      Equal
+       ARMCC_NE,            // Not equal                  Not equal, or unordered
+       ARMCC_HS,            // Carry set                  >, ==, or unordered
+       ARMCC_LO,            // Carry clear                Less than
+       ARMCC_MI,            // Minus, negative            Less than
+       ARMCC_PL,            // Plus, positive or zero     >, ==, or unordered
+       ARMCC_VS,            // Overflow                   Unordered
+       ARMCC_VC,            // No overflow                Not unordered
+       ARMCC_HI,            // Unsigned higher            Greater than, or unordered
+       ARMCC_LS,            // Unsigned lower or same     Less than or equal
+       ARMCC_GE,            // Greater than or equal      Greater than or equal
+       ARMCC_LT,            // Less than                  Less than, or unordered
+       ARMCC_GT,            // Greater than               Greater than
+       ARMCC_LE,            // Less than or equal         <, ==, or unordered
+       ARMCC_AL             // Always (unconditional)     Always (unconditional)
+} ARMCC_CondCodes;
+
+inline static ARMCC_CondCodes ARMCC_getOppositeCondition(ARMCC_CondCodes CC)
+{
+       switch (CC) {
+               case ARMCC_EQ: return ARMCC_NE;
+               case ARMCC_NE: return ARMCC_EQ;
+               case ARMCC_HS: return ARMCC_LO;
+               case ARMCC_LO: return ARMCC_HS;
+               case ARMCC_MI: return ARMCC_PL;
+               case ARMCC_PL: return ARMCC_MI;
+               case ARMCC_VS: return ARMCC_VC;
+               case ARMCC_VC: return ARMCC_VS;
+               case ARMCC_HI: return ARMCC_LS;
+               case ARMCC_LS: return ARMCC_HI;
+               case ARMCC_GE: return ARMCC_LT;
+               case ARMCC_LT: return ARMCC_GE;
+               case ARMCC_GT: return ARMCC_LE;
+               case ARMCC_LE: return ARMCC_GT;
+               default: return ARMCC_AL;
+       }
+}
+
+inline static char *ARMCC_ARMCondCodeToString(ARMCC_CondCodes CC)
+{
+       switch (CC) {
+               case ARMCC_EQ:  return "eq";
+               case ARMCC_NE:  return "ne";
+               case ARMCC_HS:  return "hs";
+               case ARMCC_LO:  return "lo";
+               case ARMCC_MI:  return "mi";
+               case ARMCC_PL:  return "pl";
+               case ARMCC_VS:  return "vs";
+               case ARMCC_VC:  return "vc";
+               case ARMCC_HI:  return "hi";
+               case ARMCC_LS:  return "ls";
+               case ARMCC_GE:  return "ge";
+               case ARMCC_LT:  return "lt";
+               case ARMCC_GT:  return "gt";
+               case ARMCC_LE:  return "le";
+               case ARMCC_AL:  return "al";
+               default: return "";
+       }
+}
+
+inline static char *ARM_PROC_IFlagsToString(unsigned val)
+{
+       switch (val) {
+               case ARM_CPSFLAG_F: return "f";
+               case ARM_CPSFLAG_I: return "i";
+               case ARM_CPSFLAG_A: return "a";
+               default: return "";
+       }
+}
+
+inline static char *ARM_PROC_IModToString(unsigned val)
+{
+       switch (val) {
+               case ARM_CPSMODE_IE: return "ie";
+               case ARM_CPSMODE_ID: return "id";
+               default: return "";
+       }
+}
+
+inline static char *ARM_MB_MemBOptToString(unsigned val, bool HasV8)
+{
+       switch (val) {
+               default: return "BUGBUG";
+               case ARM_MB_SY:    return "sy";
+               case ARM_MB_ST:    return "st";
+               case ARM_MB_LD: return HasV8 ? "ld" : "#0xd";
+               case ARM_MB_RESERVED_12: return "#0xc";
+               case ARM_MB_ISH:   return "ish";
+               case ARM_MB_ISHST: return "ishst";
+               case ARM_MB_ISHLD: return HasV8 ?  "ishld" : "#0x9";
+               case ARM_MB_RESERVED_8: return "#0x8";
+               case ARM_MB_NSH:   return "nsh";
+               case ARM_MB_NSHST: return "nshst";
+               case ARM_MB_NSHLD: return HasV8 ? "nshld" : "#0x5";
+               case ARM_MB_RESERVED_4: return "#0x4";
+               case ARM_MB_OSH:   return "osh";
+               case ARM_MB_OSHST: return "oshst";
+               case ARM_MB_OSHLD: return HasV8 ? "oshld" : "#0x1";
+               case ARM_MB_RESERVED_0: return "#0x0";
+       }
+}
+
+enum ARM_ISB_InstSyncBOpt {
+    ARM_ISB_RESERVED_0 = 0,
+    ARM_ISB_RESERVED_1 = 1,
+    ARM_ISB_RESERVED_2 = 2,
+    ARM_ISB_RESERVED_3 = 3,
+    ARM_ISB_RESERVED_4 = 4,
+    ARM_ISB_RESERVED_5 = 5,
+    ARM_ISB_RESERVED_6 = 6,
+    ARM_ISB_RESERVED_7 = 7,
+    ARM_ISB_RESERVED_8 = 8,
+    ARM_ISB_RESERVED_9 = 9,
+    ARM_ISB_RESERVED_10 = 10,
+    ARM_ISB_RESERVED_11 = 11,
+    ARM_ISB_RESERVED_12 = 12,
+    ARM_ISB_RESERVED_13 = 13,
+    ARM_ISB_RESERVED_14 = 14,
+    ARM_ISB_SY = 15
+};
+
+inline static char *ARM_ISB_InstSyncBOptToString(unsigned val)
+{
+       switch (val) {
+               default: // never reach
+               case ARM_ISB_RESERVED_0:  return "#0x0";
+               case ARM_ISB_RESERVED_1:  return "#0x1";
+               case ARM_ISB_RESERVED_2:  return "#0x2";
+               case ARM_ISB_RESERVED_3:  return "#0x3";
+               case ARM_ISB_RESERVED_4:  return "#0x4";
+               case ARM_ISB_RESERVED_5:  return "#0x5";
+               case ARM_ISB_RESERVED_6:  return "#0x6";
+               case ARM_ISB_RESERVED_7:  return "#0x7";
+               case ARM_ISB_RESERVED_8:  return "#0x8";
+               case ARM_ISB_RESERVED_9:  return "#0x9";
+               case ARM_ISB_RESERVED_10: return "#0xa";
+               case ARM_ISB_RESERVED_11: return "#0xb";
+               case ARM_ISB_RESERVED_12: return "#0xc";
+               case ARM_ISB_RESERVED_13: return "#0xd";
+               case ARM_ISB_RESERVED_14: return "#0xe";
+               case ARM_ISB_SY:          return "sy";
+       }
+}
+
+/// isARMLowRegister - Returns true if the register is a low register (r0-r7).
+///
+static inline bool isARMLowRegister(unsigned Reg)
+{
+       //using namespace ARM;
+       switch (Reg) {
+               case ARM_R0:  case ARM_R1:  case ARM_R2:  case ARM_R3:
+               case ARM_R4:  case ARM_R5:  case ARM_R6:  case ARM_R7:
+                       return true;
+               default:
+                       return false;
+       }
+}
+
+/// ARMII - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+/// ARM Index Modes
+enum ARMII_IndexMode {
+       ARMII_IndexModeNone  = 0,
+       ARMII_IndexModePre   = 1,
+       ARMII_IndexModePost  = 2,
+       ARMII_IndexModeUpd   = 3
+};
+
+/// ARM Addressing Modes
+typedef enum ARMII_AddrMode {
+       ARMII_AddrModeNone    = 0,
+       ARMII_AddrMode1       = 1,
+       ARMII_AddrMode2       = 2,
+       ARMII_AddrMode3       = 3,
+       ARMII_AddrMode4       = 4,
+       ARMII_AddrMode5       = 5,
+       ARMII_AddrMode6       = 6,
+       ARMII_AddrModeT1_1    = 7,
+       ARMII_AddrModeT1_2    = 8,
+       ARMII_AddrModeT1_4    = 9,
+       ARMII_AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
+       ARMII_AddrModeT2_i12  = 11,
+       ARMII_AddrModeT2_i8   = 12,
+       ARMII_AddrModeT2_so   = 13,
+       ARMII_AddrModeT2_pc   = 14, // +/- i12 for pc relative data
+       ARMII_AddrModeT2_i8s4 = 15, // i8 * 4
+       ARMII_AddrMode_i12    = 16
+} ARMII_AddrMode;
+
+inline static char *ARMII_AddrModeToString(ARMII_AddrMode addrmode)
+{
+       switch (addrmode) {
+               case ARMII_AddrModeNone:    return "AddrModeNone";
+               case ARMII_AddrMode1:       return "AddrMode1";
+               case ARMII_AddrMode2:       return "AddrMode2";
+               case ARMII_AddrMode3:       return "AddrMode3";
+               case ARMII_AddrMode4:       return "AddrMode4";
+               case ARMII_AddrMode5:       return "AddrMode5";
+               case ARMII_AddrMode6:       return "AddrMode6";
+               case ARMII_AddrModeT1_1:    return "AddrModeT1_1";
+               case ARMII_AddrModeT1_2:    return "AddrModeT1_2";
+               case ARMII_AddrModeT1_4:    return "AddrModeT1_4";
+               case ARMII_AddrModeT1_s:    return "AddrModeT1_s";
+               case ARMII_AddrModeT2_i12:  return "AddrModeT2_i12";
+               case ARMII_AddrModeT2_i8:   return "AddrModeT2_i8";
+               case ARMII_AddrModeT2_so:   return "AddrModeT2_so";
+               case ARMII_AddrModeT2_pc:   return "AddrModeT2_pc";
+               case ARMII_AddrModeT2_i8s4: return "AddrModeT2_i8s4";
+               case ARMII_AddrMode_i12:    return "AddrMode_i12";
+       }
+}
+
+/// Target Operand Flag enum.
+enum ARMII_TOF {
+       //===------------------------------------------------------------------===//
+       // ARM Specific MachineOperand flags.
+
+       ARMII_MO_NO_FLAG,
+
+       /// MO_LO16 - On a symbol operand, this represents a relocation containing
+       /// lower 16 bit of the address. Used only via movw instruction.
+       ARMII_MO_LO16,
+
+       /// MO_HI16 - On a symbol operand, this represents a relocation containing
+       /// higher 16 bit of the address. Used only via movt instruction.
+       ARMII_MO_HI16,
+
+       /// MO_LO16_NONLAZY - On a symbol operand "FOO", this represents a
+       /// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
+       /// i.e. "FOO$non_lazy_ptr".
+       /// Used only via movw instruction.
+       ARMII_MO_LO16_NONLAZY,
+
+       /// MO_HI16_NONLAZY - On a symbol operand "FOO", this represents a
+       /// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
+       /// i.e. "FOO$non_lazy_ptr". Used only via movt instruction.
+       ARMII_MO_HI16_NONLAZY,
+
+       /// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
+       /// relocation containing lower 16 bit of the PC relative address of the
+       /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
+       /// Used only via movw instruction.
+       ARMII_MO_LO16_NONLAZY_PIC,
+
+       /// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
+       /// relocation containing lower 16 bit of the PC relative address of the
+       /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
+       /// Used only via movt instruction.
+       ARMII_MO_HI16_NONLAZY_PIC,
+
+       /// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a
+       /// call operand.
+       ARMII_MO_PLT
+};
+
+enum {
+       //===------------------------------------------------------------------===//
+       // Instruction Flags.
+
+       //===------------------------------------------------------------------===//
+       // This four-bit field describes the addressing mode used.
+       ARMII_AddrModeMask  = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
+
+       // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
+       // and store ops only.  Generic "updating" flag is used for ld/st multiple.
+       // The index mode enums are declared in ARMBaseInfo.h
+       ARMII_IndexModeShift = 5,
+       ARMII_IndexModeMask  = 3 << ARMII_IndexModeShift,
+
+       //===------------------------------------------------------------------===//
+       // Instruction encoding formats.
+       //
+       ARMII_FormShift     = 7,
+       ARMII_FormMask      = 0x3f << ARMII_FormShift,
+
+       // Pseudo instructions
+       ARMII_Pseudo        = 0  << ARMII_FormShift,
+
+       // Multiply instructions
+       ARMII_MulFrm        = 1  << ARMII_FormShift,
+
+       // Branch instructions
+       ARMII_BrFrm         = 2  << ARMII_FormShift,
+       ARMII_BrMiscFrm     = 3  << ARMII_FormShift,
+
+       // Data Processing instructions
+       ARMII_DPFrm         = 4  << ARMII_FormShift,
+       ARMII_DPSoRegFrm    = 5  << ARMII_FormShift,
+
+       // Load and Store
+       ARMII_LdFrm         = 6  << ARMII_FormShift,
+       ARMII_StFrm         = 7  << ARMII_FormShift,
+       ARMII_LdMiscFrm     = 8  << ARMII_FormShift,
+       ARMII_StMiscFrm     = 9  << ARMII_FormShift,
+       ARMII_LdStMulFrm    = 10 << ARMII_FormShift,
+
+       ARMII_LdStExFrm     = 11 << ARMII_FormShift,
+
+       // Miscellaneous arithmetic instructions
+       ARMII_ArithMiscFrm  = 12 << ARMII_FormShift,
+       ARMII_SatFrm        = 13 << ARMII_FormShift,
+
+       // Extend instructions
+       ARMII_ExtFrm        = 14 << ARMII_FormShift,
+
+       // VFP formats
+       ARMII_VFPUnaryFrm   = 15 << ARMII_FormShift,
+       ARMII_VFPBinaryFrm  = 16 << ARMII_FormShift,
+       ARMII_VFPConv1Frm   = 17 << ARMII_FormShift,
+       ARMII_VFPConv2Frm   = 18 << ARMII_FormShift,
+       ARMII_VFPConv3Frm   = 19 << ARMII_FormShift,
+       ARMII_VFPConv4Frm   = 20 << ARMII_FormShift,
+       ARMII_VFPConv5Frm   = 21 << ARMII_FormShift,
+       ARMII_VFPLdStFrm    = 22 << ARMII_FormShift,
+       ARMII_VFPLdStMulFrm = 23 << ARMII_FormShift,
+       ARMII_VFPMiscFrm    = 24 << ARMII_FormShift,
+
+       // Thumb format
+       ARMII_ThumbFrm      = 25 << ARMII_FormShift,
+
+       // Miscelleaneous format
+       ARMII_MiscFrm       = 26 << ARMII_FormShift,
+
+       // NEON formats
+       ARMII_NGetLnFrm     = 27 << ARMII_FormShift,
+       ARMII_NSetLnFrm     = 28 << ARMII_FormShift,
+       ARMII_NDupFrm       = 29 << ARMII_FormShift,
+       ARMII_NLdStFrm      = 30 << ARMII_FormShift,
+       ARMII_N1RegModImmFrm= 31 << ARMII_FormShift,
+       ARMII_N2RegFrm      = 32 << ARMII_FormShift,
+       ARMII_NVCVTFrm      = 33 << ARMII_FormShift,
+       ARMII_NVDupLnFrm    = 34 << ARMII_FormShift,
+       ARMII_N2RegVShLFrm  = 35 << ARMII_FormShift,
+       ARMII_N2RegVShRFrm  = 36 << ARMII_FormShift,
+       ARMII_N3RegFrm      = 37 << ARMII_FormShift,
+       ARMII_N3RegVShFrm   = 38 << ARMII_FormShift,
+       ARMII_NVExtFrm      = 39 << ARMII_FormShift,
+       ARMII_NVMulSLFrm    = 40 << ARMII_FormShift,
+       ARMII_NVTBLFrm      = 41 << ARMII_FormShift,
+
+       //===------------------------------------------------------------------===//
+       // Misc flags.
+
+       // UnaryDP - Indicates this is a unary data processing instruction, i.e.
+       // it doesn't have a Rn operand.
+       ARMII_UnaryDP       = 1 << 13,
+
+       // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
+       // a 16-bit Thumb instruction if certain conditions are met.
+       ARMII_Xform16Bit    = 1 << 14,
+
+       // ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb
+       // instruction. Used by the parser to determine whether to require the 'S'
+       // suffix on the mnemonic (when not in an IT block) or preclude it (when
+       // in an IT block).
+       ARMII_ThumbArithFlagSetting = 1 << 18,
+
+       //===------------------------------------------------------------------===//
+       // Code domain.
+       ARMII_DomainShift   = 15,
+       ARMII_DomainMask    = 7 << ARMII_DomainShift,
+       ARMII_DomainGeneral = 0 << ARMII_DomainShift,
+       ARMII_DomainVFP     = 1 << ARMII_DomainShift,
+       ARMII_DomainNEON    = 2 << ARMII_DomainShift,
+       ARMII_DomainNEONA8  = 4 << ARMII_DomainShift,
+
+       //===------------------------------------------------------------------===//
+       // Field shifts - such shifts are used to set field while generating
+       // machine instructions.
+       //
+       // FIXME: This list will need adjusting/fixing as the MC code emitter
+       // takes shape and the ARMCodeEmitter.cpp bits go away.
+       ARMII_ShiftTypeShift = 4,
+
+       ARMII_M_BitShift     = 5,
+       ARMII_ShiftImmShift  = 5,
+       ARMII_ShiftShift     = 7,
+       ARMII_N_BitShift     = 7,
+       ARMII_ImmHiShift     = 8,
+       ARMII_SoRotImmShift  = 8,
+       ARMII_RegRsShift     = 8,
+       ARMII_ExtRotImmShift = 10,
+       ARMII_RegRdLoShift   = 12,
+       ARMII_RegRdShift     = 12,
+       ARMII_RegRdHiShift   = 16,
+       ARMII_RegRnShift     = 16,
+       ARMII_S_BitShift     = 20,
+       ARMII_W_BitShift     = 21,
+       ARMII_AM3_I_BitShift = 22,
+       ARMII_D_BitShift     = 22,
+       ARMII_U_BitShift     = 23,
+       ARMII_P_BitShift     = 24,
+       ARMII_I_BitShift     = 25,
+       ARMII_CondShift      = 28
+};
+
+#endif
diff --git a/Source/ThirdParty/capstone/Source/arch/ARM/ARMDisassembler.c b/Source/ThirdParty/capstone/Source/arch/ARM/ARMDisassembler.c
new file mode 100644 (file)
index 0000000..aeda429
--- /dev/null
@@ -0,0 +1,5212 @@
+//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifdef CAPSTONE_HAS_ARM
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <capstone/platform.h>
+
+#include "ARMAddressingModes.h"
+#include "ARMBaseInfo.h"
+#include "../../MCFixedLenDisassembler.h"
+#include "../../MCInst.h"
+#include "../../MCInstrDesc.h"
+#include "../../MCRegisterInfo.h"
+#include "../../LEB128.h"
+#include "../../MCDisassembler.h"
+#include "../../cs_priv.h"
+#include "../../utils.h"
+
+#include "ARMDisassembler.h"
+
+//#define GET_REGINFO_ENUM
+//#include "X86GenRegisterInfo.inc"
+
+#define GET_SUBTARGETINFO_ENUM
+#include "ARMGenSubtargetInfo.inc"
+
+#define GET_INSTRINFO_MC_DESC
+#include "ARMGenInstrInfo.inc"
+
+#define GET_INSTRINFO_ENUM
+#include "ARMGenInstrInfo.inc"
+
+static bool ITStatus_push_back(ARM_ITStatus *it, char v)
+{
+       if (it->size >= sizeof(it->ITStates)) {
+               // TODO: consider warning user.
+               it->size = 0;
+       }
+       it->ITStates[it->size] = v;
+       it->size++;
+
+       return true;
+}
+
+// Returns true if the current instruction is in an IT block
+static bool ITStatus_instrInITBlock(ARM_ITStatus *it)
+{
+       //return !ITStates.empty();
+       return (it->size > 0);
+}
+
+// Returns true if current instruction is the last instruction in an IT block
+static bool ITStatus_instrLastInITBlock(ARM_ITStatus *it)
+{
+       return (it->size == 1);
+}
+
+// Handles the condition code status of instructions in IT blocks
+
+// Returns the condition code for instruction in IT block
+static unsigned ITStatus_getITCC(ARM_ITStatus *it)
+{
+       unsigned CC = ARMCC_AL;
+       if (ITStatus_instrInITBlock(it))
+               //CC = ITStates.back();
+               CC = it->ITStates[it->size-1];
+       return CC;
+}
+
+// Advances the IT block state to the next T or E
+static void ITStatus_advanceITState(ARM_ITStatus *it)
+{
+       //ITStates.pop_back();
+       it->size--;
+}
+
+// Called when decoding an IT instruction. Sets the IT state for the following
+// instructions that for the IT block. Firstcond and Mask correspond to the 
+// fields in the IT instruction encoding.
+static void ITStatus_setITState(ARM_ITStatus *it, char Firstcond, char Mask)
+{
+       // (3 - the number of trailing zeros) is the number of then / else.
+       unsigned CondBit0 = Firstcond & 1;
+       unsigned NumTZ = CountTrailingZeros_32(Mask);
+       unsigned char CCBits = (unsigned char)Firstcond & 0xf;
+       unsigned Pos;
+       //assert(NumTZ <= 3 && "Invalid IT mask!");
+       // push condition codes onto the stack the correct order for the pops
+       for (Pos = NumTZ+1; Pos <= 3; ++Pos) {
+               bool T = ((Mask >> Pos) & 1) == (int)CondBit0;
+               if (T)
+                       ITStatus_push_back(it, CCBits);
+               else
+                       ITStatus_push_back(it, CCBits ^ 1);
+       }
+       ITStatus_push_back(it, CCBits);
+}
+
+/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
+
+static bool Check(DecodeStatus *Out, DecodeStatus In)
+{
+       switch (In) {
+               case MCDisassembler_Success:
+                       // Out stays the same.
+                       return true;
+               case MCDisassembler_SoftFail:
+                       *Out = In;
+                       return true;
+               case MCDisassembler_Fail:
+                       *Out = In;
+                       return false;
+               default:        // never reached
+                       return false;
+       }
+}
+
+// Forward declare these because the autogenerated code will reference them.
+// Definitions are further down.
+static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address, const void *Decoder);
+static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address, const void *Decoder);
+static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst,
+               unsigned Insn, uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst,unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst * Inst,
+               unsigned Insn, uint64_t Adddress, const void *Decoder);
+static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst,unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeNEONModImmInstruction(MCInst *Inst,unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeBankedReg(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void* Decoder);
+static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void* Decoder);
+static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void* Decoder);
+static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void* Decoder);
+static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst,unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeIT(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst,unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst,unsigned Insn,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2Adr(MCInst *Inst, uint32_t Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,
+               uint64_t Address, const void *Decoder);
+
+static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeMRRC2(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder);
+
+// Hacky: enable all features for disassembler
+uint64_t ARM_getFeatureBits(unsigned int mode)
+{
+       uint64_t Bits = (uint64_t)-1;   // everything by default
+
+       // FIXME: ARM_FeatureVFPOnlySP is conflicting with everything else??
+       Bits &= (~ARM_FeatureVFPOnlySP);
+
+       // FIXME: no Armv8 support?
+       //Bits -= ARM_HasV7Ops;
+       //Bits &= ~ARM_FeatureMP;
+       if ((mode & CS_MODE_V8) == 0)
+               Bits &= ~ARM_HasV8Ops;
+       //Bits &= ~ARM_HasV6Ops;
+
+       if ((mode & CS_MODE_MCLASS) == 0)
+               Bits &= (~ARM_FeatureMClass);
+
+       // some features are mutually exclusive
+       if (mode & CS_MODE_THUMB) {
+               //Bits &= ~ARM_HasV6Ops;
+               //Bits &= ~ARM_FeatureCRC;
+               //Bits &= ~ARM_HasV5TEOps;
+               //Bits &= ~ARM_HasV4TOps;
+               //Bits &= ~ARM_HasV6T2Ops;
+               //Bits &= ~ARM_FeatureDB;
+               //Bits &= ~ARM_FeatureHWDivARM;
+               //Bits &= ~ARM_FeatureNaClTrap;
+               //Bits &= ~ARM_FeatureMClass;
+               // ArmV8
+       } else {        // ARM mode
+               Bits &= ~ARM_ModeThumb;
+               Bits &= ~ARM_FeatureThumb2;
+       }
+
+       return Bits;
+}
+
+#include "ARMGenDisassemblerTables.inc"
+
+static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       if (Val == 0xF) return MCDisassembler_Fail;
+       // AL predicate is not allowed on Thumb1 branches.
+       if (MCInst_getOpcode(Inst) == ARM_tBcc && Val == 0xE)
+               return MCDisassembler_Fail;
+       MCOperand_CreateImm0(Inst, Val);
+       if (Val == ARMCC_AL) {
+               MCOperand_CreateReg0(Inst, 0);
+       } else
+               MCOperand_CreateReg0(Inst, ARM_CPSR);
+       return MCDisassembler_Success;
+}
+
+#define GET_REGINFO_MC_DESC
+#include "ARMGenRegisterInfo.inc"
+void ARM_init(MCRegisterInfo *MRI)
+{
+       /*
+          InitMCRegisterInfo(ARMRegDesc, 289,
+          RA, PC,
+          ARMMCRegisterClasses, 100,
+          ARMRegUnitRoots, 77, ARMRegDiffLists, ARMRegStrings,
+          ARMSubRegIdxLists, 57,
+          ARMSubRegIdxRanges, ARMRegEncodingTable);
+        */
+
+       MCRegisterInfo_InitMCRegisterInfo(MRI, ARMRegDesc, 289,
+                       0, 0, 
+                       ARMMCRegisterClasses, 100,
+                       0, 0, ARMRegDiffLists, 0, 
+                       ARMSubRegIdxLists, 57,
+                       0);
+}
+
+// Post-decoding checks
+static DecodeStatus checkDecodedInstruction(MCInst *MI,
+               uint32_t Insn,
+               DecodeStatus Result)
+{
+       switch (MCInst_getOpcode(MI)) {
+               case ARM_HVC: {
+                         // HVC is undefined if condition = 0xf otherwise upredictable
+                         // if condition != 0xe
+                         uint32_t Cond = (Insn >> 28) & 0xF;
+                         if (Cond == 0xF)
+                                 return MCDisassembler_Fail;
+                         if (Cond != 0xE)
+                                 return MCDisassembler_SoftFail;
+                         return Result;
+                 }
+               default:
+                          return Result;
+       }
+}
+
+static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
+               uint16_t *Size, uint64_t Address)
+{
+       uint32_t insn, i;
+       DecodeStatus result;
+
+       if (code_len < 4)
+               // not enough data
+               return MCDisassembler_Fail;
+
+       if (MI->flat_insn->detail) {
+               memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
+               for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
+                       MI->flat_insn->detail->arm.operands[i].vector_index = -1;
+                       MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
+               }
+       }
+
+       if (ud->big_endian)
+               insn = (code[3] << 0) |
+                       (code[2] << 8) |
+                       (code[1] <<  16) |
+                       (code[0] <<  24);
+       else
+               insn = (code[3] << 24) |
+                       (code[2] << 16) |
+                       (code[1] <<  8) |
+                       (code[0] <<  0);
+
+       // Calling the auto-generated decoder function.
+       result = decodeInstruction_4(DecoderTableARM32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               result = checkDecodedInstruction(MI, insn, result);
+               if (result != MCDisassembler_Fail)
+                       *Size = 4;
+               return result;
+       }
+
+       // VFP and NEON instructions, similarly, are shared between ARM
+       // and Thumb modes.
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableVFP32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableVFPV832, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableNEONData32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_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, NULL))
+                       return MCDisassembler_Fail;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_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, NULL))
+                       return MCDisassembler_Fail;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_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, NULL))
+                       return MCDisassembler_Fail;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTablev8NEON32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTablev8Crypto32, MI, insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       *Size = 0;
+       return MCDisassembler_Fail;
+}
+
+// Thumb1 instructions don't have explicit S bits.  Rather, they
+// implicitly set CPSR.  Since it's not represented in the encoding, the
+// auto-generated decoder won't inject the CPSR operand.  We need to fix
+// that as a post-pass.
+static void AddThumb1SBit(MCInst *MI, bool InITBlock)
+{
+       MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
+       unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
+       unsigned i;
+
+       for (i = 0; i < NumOps; ++i) {
+               if (i == MCInst_getNumOperands(MI)) break;
+               if (MCOperandInfo_isOptionalDef(&OpInfo[i]) && OpInfo[i].RegClass == ARM_CCRRegClassID) {
+                       if (i > 0 && MCOperandInfo_isPredicate(&OpInfo[i-1])) continue;
+                       MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));
+                       return;
+               }
+       }
+
+       //MI.insert(I, MCOperand_CreateReg0(Inst, InITBlock ? 0 : ARM_CPSR));
+       MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));
+}
+
+// Most Thumb instructions don't have explicit predicates in the
+// encoding, but rather get their predicates from IT context.  We need
+// to fix up the predicate operands using this context information as a
+// post-pass.
+static DecodeStatus AddThumbPredicate(cs_struct *ud, MCInst *MI)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       MCOperandInfo *OpInfo;
+       unsigned short NumOps;
+       unsigned int i;
+       unsigned CC;
+
+       // A few instructions actually have predicates encoded in them.  Don't
+       // try to overwrite it if we're seeing one of those.
+       switch (MCInst_getOpcode(MI)) {
+               case ARM_tBcc:
+               case ARM_t2Bcc:
+               case ARM_tCBZ:
+               case ARM_tCBNZ:
+               case ARM_tCPS:
+               case ARM_t2CPS3p:
+               case ARM_t2CPS2p:
+               case ARM_t2CPS1p:
+               case ARM_tMOVSr:
+               case ARM_tSETEND:
+                       // Some instructions (mostly conditional branches) are not
+                       // allowed in IT blocks.
+                       if (ITStatus_instrInITBlock(&(ud->ITBlock)))
+                               S = MCDisassembler_SoftFail;
+                       else
+                               return MCDisassembler_Success;
+                       break;
+               case ARM_tB:
+               case ARM_t2B:
+               case ARM_t2TBB:
+               case ARM_t2TBH:
+                       // Some instructions (mostly unconditional branches) can
+                       // only appears at the end of, or outside of, an IT.
+                       //if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
+                       if (ITStatus_instrInITBlock(&(ud->ITBlock)) && !ITStatus_instrLastInITBlock(&(ud->ITBlock)))
+                               S = MCDisassembler_SoftFail;
+                       break;
+               default:
+                       break;
+       }
+
+       // If we're in an IT block, base the predicate on that.  Otherwise,
+       // assume a predicate of AL.
+       CC = ITStatus_getITCC(&(ud->ITBlock));
+       if (CC == 0xF) 
+               CC = ARMCC_AL;
+       if (ITStatus_instrInITBlock(&(ud->ITBlock)))
+               ITStatus_advanceITState(&(ud->ITBlock));
+
+       OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
+       NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
+
+       for (i = 0; i < NumOps; ++i) {
+               if (i == MCInst_getNumOperands(MI)) break;
+               if (MCOperandInfo_isPredicate(&OpInfo[i])) {
+                       MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));
+                       if (CC == ARMCC_AL)
+                               MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, 0));
+                       else
+                               MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, ARM_CPSR));
+                       return S;
+               }
+       }
+
+       MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));
+       if (CC == ARMCC_AL)
+               MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, 0));
+       else
+               MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, ARM_CPSR));
+
+       return S;
+}
+
+// Thumb VFP instructions are a special case.  Because we share their
+// encodings between ARM and Thumb modes, and they are predicable in ARM
+// mode, the auto-generated decoder will give them an (incorrect)
+// predicate operand.  We need to rewrite these operands based on the IT
+// context as a post-pass.
+static void UpdateThumbVFPPredicate(cs_struct *ud, MCInst *MI)
+{
+       unsigned CC;
+       unsigned short NumOps;
+       MCOperandInfo *OpInfo;
+       unsigned i;
+
+       CC = ITStatus_getITCC(&(ud->ITBlock));
+       if (ITStatus_instrInITBlock(&(ud->ITBlock)))
+               ITStatus_advanceITState(&(ud->ITBlock));
+
+       OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
+       NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
+
+       for (i = 0; i < NumOps; ++i) {
+               if (MCOperandInfo_isPredicate(&OpInfo[i])) {
+                       MCOperand_setImm(MCInst_getOperand(MI, i), CC);
+                       if (CC == ARMCC_AL)
+                               MCOperand_setReg(MCInst_getOperand(MI, i+1), 0);
+                       else
+                               MCOperand_setReg(MCInst_getOperand(MI, i+1), ARM_CPSR);
+                       return;
+               }
+       }
+}
+
+static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
+               uint16_t *Size, uint64_t Address)
+{
+       uint16_t insn16;
+       DecodeStatus result;
+       bool InITBlock;
+       unsigned Firstcond, Mask; 
+       uint32_t NEONLdStInsn, insn32, NEONDataInsn, NEONCryptoInsn, NEONv8Insn;
+       size_t i;
+
+       // We want to read exactly 2 bytes of data.
+       if (code_len < 2)
+               // not enough data
+               return MCDisassembler_Fail;
+
+       if (MI->flat_insn->detail) {
+               memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
+               for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
+                       MI->flat_insn->detail->arm.operands[i].vector_index = -1;
+                       MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
+               }
+       }
+
+       if (ud->big_endian)
+               insn16 = (code[0] << 8) | code[1];
+       else
+               insn16 = (code[1] << 8) | code[0];
+
+       result = decodeInstruction_2(DecoderTableThumb16, MI, insn16, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 2;
+               Check(&result, AddThumbPredicate(ud, MI));
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_2(DecoderTableThumbSBit16, MI, insn16, Address, NULL, ud->mode);
+       if (result) {
+               *Size = 2;
+               InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
+               Check(&result, AddThumbPredicate(ud, MI));
+               AddThumb1SBit(MI, InITBlock);
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_2(DecoderTableThumb216, MI, insn16, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 2;
+
+               // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
+               // the Thumb predicate.
+               if (MCInst_getOpcode(MI) == ARM_t2IT && ITStatus_instrInITBlock(&(ud->ITBlock)))
+                       return MCDisassembler_SoftFail;
+               Check(&result, AddThumbPredicate(ud, MI));
+
+               // If we find an IT instruction, we need to parse its condition
+               // code and mask operands so that we can apply them correctly
+               // to the subsequent instructions.
+               if (MCInst_getOpcode(MI) == ARM_t2IT) {
+
+                       Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 0));
+                       Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 1));
+                       ITStatus_setITState(&(ud->ITBlock), (char)Firstcond, (char)Mask);
+               }
+
+               return result;
+       }
+
+       // We want to read exactly 4 bytes of data.
+       if (code_len < 4)
+               // not enough data
+               return MCDisassembler_Fail;
+
+       if (ud->big_endian)
+               insn32 = (code[3] <<  0) |
+                       (code[2] <<  8) |
+                       (code[1] << 16) |
+                       (code[0] << 24);
+       else
+               insn32 = (code[3] <<  8) |
+                       (code[2] <<  0) |
+                       (code[1] << 24) |
+                       (code[0] << 16);
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableThumb32, MI, insn32, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
+               Check(&result, AddThumbPredicate(ud, MI));
+               AddThumb1SBit(MI, InITBlock);
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableThumb232, MI, insn32, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               Check(&result, AddThumbPredicate(ud, MI));
+               return result;
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               UpdateThumbVFPPredicate(ud, MI);
+               return result;
+       }
+
+       if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {
+               MCInst_clear(MI);
+               result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, NULL, ud->mode);
+               if (result != MCDisassembler_Fail) {
+                       *Size = 4;
+                       UpdateThumbVFPPredicate(ud, MI);
+                       return result;
+               }
+       }
+
+       MCInst_clear(MI);
+       result = decodeInstruction_4(DecoderTableVFPV832, MI, insn32, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {
+               MCInst_clear(MI);
+               result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn32, Address, NULL, ud->mode);
+               if (result != MCDisassembler_Fail) {
+                       *Size = 4;
+                       Check(&result, AddThumbPredicate(ud, MI));
+                       return result;
+               }
+       }
+
+       if (fieldFromInstruction_4(insn32, 24, 8) == 0xF9) {
+               MCInst_clear(MI);
+               NEONLdStInsn = insn32;
+               NEONLdStInsn &= 0xF0FFFFFF;
+               NEONLdStInsn |= 0x04000000;
+               result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, Address, NULL, ud->mode);
+               if (result != MCDisassembler_Fail) {
+                       *Size = 4;
+                       Check(&result, AddThumbPredicate(ud, MI));
+                       return result;
+               }
+       }
+
+       if (fieldFromInstruction_4(insn32, 24, 4) == 0xF) {
+               MCInst_clear(MI);
+               NEONDataInsn = insn32;
+               NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
+               NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
+               NEONDataInsn |= 0x12000000; // Set bits 28 and 25
+               result = decodeInstruction_4(DecoderTableNEONData32, MI, NEONDataInsn, Address, NULL, ud->mode);
+               if (result != MCDisassembler_Fail) {
+                       *Size = 4;
+                       Check(&result, AddThumbPredicate(ud, MI));
+                       return result;
+               }
+       }
+
+       MCInst_clear(MI);
+       NEONCryptoInsn = insn32;
+       NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
+       NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
+       NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
+       result = decodeInstruction_4(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
+                       Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       NEONv8Insn = insn32;
+       NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
+       result = decodeInstruction_4(DecoderTablev8NEON32, MI, NEONv8Insn, Address, NULL, ud->mode);
+       if (result != MCDisassembler_Fail) {
+               *Size = 4;
+               return result;
+       }
+
+       MCInst_clear(MI);
+       *Size = 0;
+       return MCDisassembler_Fail;
+}
+
+bool Thumb_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
+               uint16_t *size, uint64_t address, void *info)
+{
+       DecodeStatus status = _Thumb_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);
+
+       //return status == MCDisassembler_Success;
+       return status != MCDisassembler_Fail;
+}
+
+bool ARM_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
+               uint16_t *size, uint64_t address, void *info)
+{
+       DecodeStatus status = _ARM_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);
+
+       //return status == MCDisassembler_Success;
+       return status != MCDisassembler_Fail;
+}
+
+static const uint16_t GPRDecoderTable[] = {
+       ARM_R0, ARM_R1, ARM_R2, ARM_R3,
+       ARM_R4, ARM_R5, ARM_R6, ARM_R7,
+       ARM_R8, ARM_R9, ARM_R10, ARM_R11,
+       ARM_R12, ARM_SP, ARM_LR, ARM_PC
+};
+
+static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned Register;
+       if (RegNo > 15)
+               return MCDisassembler_Fail;
+
+       Register = GPRDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return MCDisassembler_Success;
+}
+
+static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       if (RegNo == 15) 
+               S = MCDisassembler_SoftFail;
+
+       Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
+
+       return S;
+}
+
+static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       if (RegNo == 15) {
+               MCOperand_CreateReg0(Inst, ARM_APSR_NZCV);
+               return MCDisassembler_Success;
+       }
+
+       Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
+       return S;
+}
+
+static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       if (RegNo > 7)
+               return MCDisassembler_Fail;
+       return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
+}
+
+static const uint16_t GPRPairDecoderTable[] = {
+       ARM_R0_R1, ARM_R2_R3,   ARM_R4_R5,  ARM_R6_R7,
+       ARM_R8_R9, ARM_R10_R11, ARM_R12_SP
+};
+
+static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned RegisterPair;
+       DecodeStatus S = MCDisassembler_Success;
+
+       if (RegNo > 13)
+               return MCDisassembler_Fail;
+
+       if ((RegNo & 1) || RegNo == 0xe)
+               S = MCDisassembler_SoftFail;
+
+       RegisterPair = GPRPairDecoderTable[RegNo/2];
+       MCOperand_CreateReg0(Inst, RegisterPair);
+       return S;
+}
+
+static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned Register = 0;
+       switch (RegNo) {
+               case 0:
+                       Register = ARM_R0;
+                       break;
+               case 1:
+                       Register = ARM_R1;
+                       break;
+               case 2:
+                       Register = ARM_R2;
+                       break;
+               case 3:
+                       Register = ARM_R3;
+                       break;
+               case 9:
+                       Register = ARM_R9;
+                       break;
+               case 12:
+                       Register = ARM_R12;
+                       break;
+               default:
+                       return MCDisassembler_Fail;
+       }
+
+       MCOperand_CreateReg0(Inst, Register);
+       return MCDisassembler_Success;
+}
+
+static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       if (RegNo == 13 || RegNo == 15)
+               S = MCDisassembler_SoftFail;
+       Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
+       return S;
+}
+
+static const uint16_t SPRDecoderTable[] = {
+       ARM_S0,  ARM_S1,  ARM_S2,  ARM_S3,
+       ARM_S4,  ARM_S5,  ARM_S6,  ARM_S7,
+       ARM_S8,  ARM_S9, ARM_S10, ARM_S11,
+       ARM_S12, ARM_S13, ARM_S14, ARM_S15,
+       ARM_S16, ARM_S17, ARM_S18, ARM_S19,
+       ARM_S20, ARM_S21, ARM_S22, ARM_S23,
+       ARM_S24, ARM_S25, ARM_S26, ARM_S27,
+       ARM_S28, ARM_S29, ARM_S30, ARM_S31
+};
+
+static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned Register;
+       if (RegNo > 31)
+               return MCDisassembler_Fail;
+
+       Register = SPRDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return MCDisassembler_Success;
+}
+
+static const uint16_t DPRDecoderTable[] = {
+       ARM_D0,  ARM_D1,  ARM_D2,  ARM_D3,
+       ARM_D4,  ARM_D5,  ARM_D6,  ARM_D7,
+       ARM_D8,  ARM_D9, ARM_D10, ARM_D11,
+       ARM_D12, ARM_D13, ARM_D14, ARM_D15,
+       ARM_D16, ARM_D17, ARM_D18, ARM_D19,
+       ARM_D20, ARM_D21, ARM_D22, ARM_D23,
+       ARM_D24, ARM_D25, ARM_D26, ARM_D27,
+       ARM_D28, ARM_D29, ARM_D30, ARM_D31
+};
+
+static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned Register;
+
+       //uint64_t featureBits = ARM_getFeatureBits(Inst->csh->mode);
+       //bool hasD16 = featureBits & ARM_FeatureD16;
+
+       //if (RegNo > 31 || (hasD16 && RegNo > 15))     // FIXME
+       if (RegNo > 31)
+               return MCDisassembler_Fail;
+
+       Register = DPRDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+
+       return MCDisassembler_Success;
+}
+
+static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       if (RegNo > 7)
+               return MCDisassembler_Fail;
+       return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
+}
+
+       static DecodeStatus
+DecodeDPR_VFP2RegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       if (RegNo > 15)
+               return MCDisassembler_Fail;
+       return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
+}
+
+static const uint16_t QPRDecoderTable[] = {
+       ARM_Q0,  ARM_Q1,  ARM_Q2,  ARM_Q3,
+       ARM_Q4,  ARM_Q5,  ARM_Q6,  ARM_Q7,
+       ARM_Q8,  ARM_Q9, ARM_Q10, ARM_Q11,
+       ARM_Q12, ARM_Q13, ARM_Q14, ARM_Q15
+};
+
+static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned Register;
+       if (RegNo > 31 || (RegNo & 1) != 0)
+               return MCDisassembler_Fail;
+       RegNo >>= 1;
+
+       Register = QPRDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return MCDisassembler_Success;
+}
+
+static const uint16_t DPairDecoderTable[] = {
+       ARM_Q0,  ARM_D1_D2,   ARM_Q1,  ARM_D3_D4,   ARM_Q2,  ARM_D5_D6,
+       ARM_Q3,  ARM_D7_D8,   ARM_Q4,  ARM_D9_D10,  ARM_Q5,  ARM_D11_D12,
+       ARM_Q6,  ARM_D13_D14, ARM_Q7,  ARM_D15_D16, ARM_Q8,  ARM_D17_D18,
+       ARM_Q9,  ARM_D19_D20, ARM_Q10, ARM_D21_D22, ARM_Q11, ARM_D23_D24,
+       ARM_Q12, ARM_D25_D26, ARM_Q13, ARM_D27_D28, ARM_Q14, ARM_D29_D30,
+       ARM_Q15
+};
+
+static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned Register;
+       if (RegNo > 30)
+               return MCDisassembler_Fail;
+
+       Register = DPairDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return MCDisassembler_Success;
+}
+
+static const uint16_t DPairSpacedDecoderTable[] = {
+       ARM_D0_D2,   ARM_D1_D3,   ARM_D2_D4,   ARM_D3_D5,
+       ARM_D4_D6,   ARM_D5_D7,   ARM_D6_D8,   ARM_D7_D9,
+       ARM_D8_D10,  ARM_D9_D11,  ARM_D10_D12, ARM_D11_D13,
+       ARM_D12_D14, ARM_D13_D15, ARM_D14_D16, ARM_D15_D17,
+       ARM_D16_D18, ARM_D17_D19, ARM_D18_D20, ARM_D19_D21,
+       ARM_D20_D22, ARM_D21_D23, ARM_D22_D24, ARM_D23_D25,
+       ARM_D24_D26, ARM_D25_D27, ARM_D26_D28, ARM_D27_D29,
+       ARM_D28_D30, ARM_D29_D31
+};
+
+static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
+               unsigned RegNo, uint64_t Address, const void *Decoder)
+{
+       unsigned Register;
+       if (RegNo > 29)
+               return MCDisassembler_Fail;
+
+       Register = DPairSpacedDecoderTable[RegNo];
+       MCOperand_CreateReg0(Inst, Register);
+       return MCDisassembler_Success;
+}
+
+static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       if (Val)
+               MCOperand_CreateReg0(Inst, ARM_CPSR);
+       else
+               MCOperand_CreateReg0(Inst, 0);
+       return MCDisassembler_Success;
+}
+
+static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       ARM_AM_ShiftOpc Shift;
+       unsigned Op;
+       unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
+       unsigned type = fieldFromInstruction_4(Val, 5, 2);
+       unsigned imm = fieldFromInstruction_4(Val, 7, 5);
+
+       // Register-immediate
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       Shift = ARM_AM_lsl;
+       switch (type) {
+               case 0:
+                       Shift = ARM_AM_lsl;
+                       break;
+               case 1:
+                       Shift = ARM_AM_lsr;
+                       break;
+               case 2:
+                       Shift = ARM_AM_asr;
+                       break;
+               case 3:
+                       Shift = ARM_AM_ror;
+                       break;
+       }
+
+       if (Shift == ARM_AM_ror && imm == 0)
+               Shift = ARM_AM_rrx;
+
+       Op = Shift | (imm << 3);
+       MCOperand_CreateImm0(Inst, Op);
+
+       return S;
+}
+
+static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       ARM_AM_ShiftOpc Shift;
+
+       unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
+       unsigned type = fieldFromInstruction_4(Val, 5, 2);
+       unsigned Rs = fieldFromInstruction_4(Val, 8, 4);
+
+       // Register-register
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       Shift = ARM_AM_lsl;
+       switch (type) {
+               case 0:
+                       Shift = ARM_AM_lsl;
+                       break;
+               case 1:
+                       Shift = ARM_AM_lsr;
+                       break;
+               case 2:
+                       Shift = ARM_AM_asr;
+                       break;
+               case 3:
+                       Shift = ARM_AM_ror;
+                       break;
+       }
+
+       MCOperand_CreateImm0(Inst, Shift);
+
+       return S;
+}
+
+static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned i;
+       DecodeStatus S = MCDisassembler_Success;
+       unsigned opcode;
+
+       bool NeedDisjointWriteback = false;
+       unsigned WritebackReg = 0;
+
+       opcode = MCInst_getOpcode(Inst);
+       switch (opcode) {
+               default:
+                       break;
+               case ARM_LDMIA_UPD:
+               case ARM_LDMDB_UPD:
+               case ARM_LDMIB_UPD:
+               case ARM_LDMDA_UPD:
+               case ARM_t2LDMIA_UPD:
+               case ARM_t2LDMDB_UPD:
+               case ARM_t2STMIA_UPD:
+               case ARM_t2STMDB_UPD:
+                       NeedDisjointWriteback = true;
+                       WritebackReg = MCOperand_getReg(MCInst_getOperand(Inst, 0));
+                       break;
+       }
+
+       // Empty register lists are not allowed.
+       if (Val == 0) return MCDisassembler_Fail;
+       for (i = 0; i < 16; ++i) {
+               if (Val & (1 << i)) {
+                       if (!Check(&S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       // Writeback not allowed if Rn is in the target list.
+                       if (NeedDisjointWriteback && WritebackReg == MCOperand_getReg(&(Inst->Operands[Inst->size-1])))
+                               Check(&S, MCDisassembler_SoftFail);
+               }
+       }
+
+       if (opcode == ARM_t2LDMIA_UPD && WritebackReg == ARM_SP) {
+               if (Val & (1 << 13) || ((Val & (1 << 15)) && (Val & (1 << 14)))) {
+                       // invalid thumb2 pop
+                       // needs no sp in reglist and not both pc and lr set at the same time
+                       return MCDisassembler_Fail;
+               }
+       }
+
+       return S;
+}
+
+static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       unsigned i;
+       unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
+       unsigned regs = fieldFromInstruction_4(Val, 0, 8);
+
+       // In case of unpredictable encoding, tweak the operands.
+       if (regs == 0 || (Vd + regs) > 32) {
+               regs = Vd + regs > 32 ? 32 - Vd : regs;
+               regs = (1u > regs? 1u : regs);
+               S = MCDisassembler_SoftFail;
+       }
+
+       if (!Check(&S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
+               return MCDisassembler_Fail;
+       for (i = 0; i < (regs - 1); ++i) {
+               if (!Check(&S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
+                       return MCDisassembler_Fail;
+       }
+
+       return S;
+}
+
+static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       unsigned i;
+       unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
+       unsigned regs = fieldFromInstruction_4(Val, 1, 7);
+
+       // In case of unpredictable encoding, tweak the operands.
+       if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
+               regs = Vd + regs > 32 ? 32 - Vd : regs;
+               regs = (1u > regs? 1u : regs);
+               regs = (16u > regs? regs : 16u);
+               S = MCDisassembler_SoftFail;
+       }
+
+       if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       for (i = 0; i < (regs - 1); ++i) {
+               if (!Check(&S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
+                       return MCDisassembler_Fail;
+       }
+
+       return S;
+}
+
+static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       // This operand encodes a mask of contiguous zeros between a specified MSB
+       // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
+       // the mask of all bits LSB-and-lower, and then xor them to create
+       // the mask of that's all ones on [msb, lsb].  Finally we not it to
+       // create the final mask.
+       unsigned msb = fieldFromInstruction_4(Val, 5, 5);
+       unsigned lsb = fieldFromInstruction_4(Val, 0, 5);
+       uint32_t lsb_mask, msb_mask;
+
+       DecodeStatus S = MCDisassembler_Success;
+       if (lsb > msb) {
+               Check(&S, MCDisassembler_SoftFail);
+               // The check above will cause the warning for the "potentially undefined
+               // instruction encoding" but we can't build a bad MCOperand value here
+               // with a lsb > msb or else printing the MCInst will cause a crash.
+               lsb = msb;
+       }
+
+       msb_mask = 0xFFFFFFFF;
+       if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
+       lsb_mask = (1U << lsb) - 1;
+
+       MCOperand_CreateImm0(Inst, ~(msb_mask ^ lsb_mask));
+       return S;
+}
+
+static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+       unsigned CRd = fieldFromInstruction_4(Insn, 12, 4);
+       unsigned coproc = fieldFromInstruction_4(Insn, 8, 4);
+       unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
+       unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned U = fieldFromInstruction_4(Insn, 23, 1);
+
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_LDC_OFFSET:
+               case ARM_LDC_PRE:
+               case ARM_LDC_POST:
+               case ARM_LDC_OPTION:
+               case ARM_LDCL_OFFSET:
+               case ARM_LDCL_PRE:
+               case ARM_LDCL_POST:
+               case ARM_LDCL_OPTION:
+               case ARM_STC_OFFSET:
+               case ARM_STC_PRE:
+               case ARM_STC_POST:
+               case ARM_STC_OPTION:
+               case ARM_STCL_OFFSET:
+               case ARM_STCL_PRE:
+               case ARM_STCL_POST:
+               case ARM_STCL_OPTION:
+               case ARM_t2LDC_OFFSET:
+               case ARM_t2LDC_PRE:
+               case ARM_t2LDC_POST:
+               case ARM_t2LDC_OPTION:
+               case ARM_t2LDCL_OFFSET:
+               case ARM_t2LDCL_PRE:
+               case ARM_t2LDCL_POST:
+               case ARM_t2LDCL_OPTION:
+               case ARM_t2STC_OFFSET:
+               case ARM_t2STC_PRE:
+               case ARM_t2STC_POST:
+               case ARM_t2STC_OPTION:
+               case ARM_t2STCL_OFFSET:
+               case ARM_t2STCL_PRE:
+               case ARM_t2STCL_POST:
+               case ARM_t2STCL_OPTION:
+                       if (coproc == 0xA || coproc == 0xB)
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       MCOperand_CreateImm0(Inst, coproc);
+       MCOperand_CreateImm0(Inst, CRd);
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_t2LDC2_OFFSET:
+               case ARM_t2LDC2L_OFFSET:
+               case ARM_t2LDC2_PRE:
+               case ARM_t2LDC2L_PRE:
+               case ARM_t2STC2_OFFSET:
+               case ARM_t2STC2L_OFFSET:
+               case ARM_t2STC2_PRE:
+               case ARM_t2STC2L_PRE:
+               case ARM_LDC2_OFFSET:
+               case ARM_LDC2L_OFFSET:
+               case ARM_LDC2_PRE:
+               case ARM_LDC2L_PRE:
+               case ARM_STC2_OFFSET:
+               case ARM_STC2L_OFFSET:
+               case ARM_STC2_PRE:
+               case ARM_STC2L_PRE:
+               case ARM_t2LDC_OFFSET:
+               case ARM_t2LDCL_OFFSET:
+               case ARM_t2LDC_PRE:
+               case ARM_t2LDCL_PRE:
+               case ARM_t2STC_OFFSET:
+               case ARM_t2STCL_OFFSET:
+               case ARM_t2STC_PRE:
+               case ARM_t2STCL_PRE:
+               case ARM_LDC_OFFSET:
+               case ARM_LDCL_OFFSET:
+               case ARM_LDC_PRE:
+               case ARM_LDCL_PRE:
+               case ARM_STC_OFFSET:
+               case ARM_STCL_OFFSET:
+               case ARM_STC_PRE:
+               case ARM_STCL_PRE:
+                       imm = ARM_AM_getAM5Opc(U ? ARM_AM_add : ARM_AM_sub, (unsigned char)imm);
+                       MCOperand_CreateImm0(Inst, imm);
+                       break;
+               case ARM_t2LDC2_POST:
+               case ARM_t2LDC2L_POST:
+               case ARM_t2STC2_POST:
+               case ARM_t2STC2L_POST:
+               case ARM_LDC2_POST:
+               case ARM_LDC2L_POST:
+               case ARM_STC2_POST:
+               case ARM_STC2L_POST:
+               case ARM_t2LDC_POST:
+               case ARM_t2LDCL_POST:
+               case ARM_t2STC_POST:
+               case ARM_t2STCL_POST:
+               case ARM_LDC_POST:
+               case ARM_LDCL_POST:
+               case ARM_STC_POST:
+               case ARM_STCL_POST:
+                       imm |= U << 8;
+                       // fall through.
+               default:
+                       // The 'option' variant doesn't encode 'U' in the immediate since
+                       // the immediate is unsigned [0,255].
+                       MCOperand_CreateImm0(Inst, imm);
+                       break;
+       }
+
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_LDC_OFFSET:
+               case ARM_LDC_PRE:
+               case ARM_LDC_POST:
+               case ARM_LDC_OPTION:
+               case ARM_LDCL_OFFSET:
+               case ARM_LDCL_PRE:
+               case ARM_LDCL_POST:
+               case ARM_LDCL_OPTION:
+               case ARM_STC_OFFSET:
+               case ARM_STC_PRE:
+               case ARM_STC_POST:
+               case ARM_STC_OPTION:
+               case ARM_STCL_OFFSET:
+               case ARM_STCL_PRE:
+               case ARM_STCL_POST:
+               case ARM_STCL_OPTION:
+                       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       return S;
+}
+
+static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       ARM_AM_AddrOpc Op;
+       ARM_AM_ShiftOpc Opc;
+       bool writeback;
+       unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
+       unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
+       unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+       unsigned reg = fieldFromInstruction_4(Insn, 25, 1);
+       unsigned P = fieldFromInstruction_4(Insn, 24, 1);
+       unsigned W = fieldFromInstruction_4(Insn, 21, 1);
+       unsigned idx_mode = 0, amt, tmp;
+
+       // On stores, the writeback operand precedes Rt.
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_STR_POST_IMM:
+               case ARM_STR_POST_REG:
+               case ARM_STRB_POST_IMM:
+               case ARM_STRB_POST_REG:
+               case ARM_STRT_POST_REG:
+               case ARM_STRT_POST_IMM:
+               case ARM_STRBT_POST_REG:
+               case ARM_STRBT_POST_IMM:
+                       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       // On loads, the writeback operand comes after Rt.
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_LDR_POST_IMM:
+               case ARM_LDR_POST_REG:
+               case ARM_LDRB_POST_IMM:
+               case ARM_LDRB_POST_REG:
+               case ARM_LDRBT_POST_REG:
+               case ARM_LDRBT_POST_IMM:
+               case ARM_LDRT_POST_REG:
+               case ARM_LDRT_POST_IMM:
+                       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       Op = ARM_AM_add;
+       if (!fieldFromInstruction_4(Insn, 23, 1))
+               Op = ARM_AM_sub;
+
+       writeback = (P == 0) || (W == 1);
+       if (P && writeback)
+               idx_mode = ARMII_IndexModePre;
+       else if (!P && writeback)
+               idx_mode = ARMII_IndexModePost;
+
+       if (writeback && (Rn == 15 || Rn == Rt))
+               S = MCDisassembler_SoftFail; // UNPREDICTABLE
+
+       if (reg) {
+               if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
+                       return MCDisassembler_Fail;
+               Opc = ARM_AM_lsl;
+               switch( fieldFromInstruction_4(Insn, 5, 2)) {
+                       case 0:
+                               Opc = ARM_AM_lsl;
+                               break;
+                       case 1:
+                               Opc = ARM_AM_lsr;
+                               break;
+                       case 2:
+                               Opc = ARM_AM_asr;
+                               break;
+                       case 3:
+                               Opc = ARM_AM_ror;
+                               break;
+                       default:
+                               return MCDisassembler_Fail;
+               }
+               amt = fieldFromInstruction_4(Insn, 7, 5);
+               if (Opc == ARM_AM_ror && amt == 0)
+                       Opc = ARM_AM_rrx;
+               imm = ARM_AM_getAM2Opc(Op, amt, Opc, idx_mode);
+
+               MCOperand_CreateImm0(Inst, imm);
+       } else {
+               MCOperand_CreateReg0(Inst, 0);
+               tmp = ARM_AM_getAM2Opc(Op, imm, ARM_AM_lsl, idx_mode);
+               MCOperand_CreateImm0(Inst, tmp);
+       }
+
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       ARM_AM_ShiftOpc ShOp;
+       unsigned shift;
+       unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
+       unsigned Rm = fieldFromInstruction_4(Val,  0, 4);
+       unsigned type = fieldFromInstruction_4(Val, 5, 2);
+       unsigned imm = fieldFromInstruction_4(Val, 7, 5);
+       unsigned U = fieldFromInstruction_4(Val, 12, 1);
+
+       ShOp = ARM_AM_lsl;
+       switch (type) {
+               case 0:
+                       ShOp = ARM_AM_lsl;
+                       break;
+               case 1:
+                       ShOp = ARM_AM_lsr;
+                       break;
+               case 2:
+                       ShOp = ARM_AM_asr;
+                       break;
+               case 3:
+                       ShOp = ARM_AM_ror;
+                       break;
+       }
+
+       if (ShOp == ARM_AM_ror && imm == 0)
+               ShOp = ARM_AM_rrx;
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (U)
+               shift = ARM_AM_getAM2Opc(ARM_AM_add, imm, ShOp, 0);
+       else
+               shift = ARM_AM_getAM2Opc(ARM_AM_sub, imm, ShOp, 0);
+       MCOperand_CreateImm0(Inst, shift);
+
+       return S;
+}
+
+static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
+       unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
+       unsigned type = fieldFromInstruction_4(Insn, 22, 1);
+       unsigned imm = fieldFromInstruction_4(Insn, 8, 4);
+       unsigned U = ((~fieldFromInstruction_4(Insn, 23, 1)) & 1) << 8;
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+       unsigned W = fieldFromInstruction_4(Insn, 21, 1);
+       unsigned P = fieldFromInstruction_4(Insn, 24, 1);
+       unsigned Rt2 = Rt + 1;
+
+       bool writeback = (W == 1) | (P == 0);
+
+       // For {LD,ST}RD, Rt must be even, else undefined.
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_STRD:
+               case ARM_STRD_PRE:
+               case ARM_STRD_POST:
+               case ARM_LDRD:
+               case ARM_LDRD_PRE:
+               case ARM_LDRD_POST:
+                       if (Rt & 0x1) S = MCDisassembler_SoftFail;
+                       break;
+               default:
+                       break;
+       }
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_STRD:
+               case ARM_STRD_PRE:
+               case ARM_STRD_POST:
+                       if (P == 0 && W == 1)
+                               S = MCDisassembler_SoftFail;
+
+                       if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
+                               S = MCDisassembler_SoftFail;
+                       if (type && Rm == 15)
+                               S = MCDisassembler_SoftFail;
+                       if (Rt2 == 15)
+                               S = MCDisassembler_SoftFail;
+                       if (!type && fieldFromInstruction_4(Insn, 8, 4))
+                               S = MCDisassembler_SoftFail;
+                       break;
+               case ARM_STRH:
+               case ARM_STRH_PRE:
+               case ARM_STRH_POST:
+                       if (Rt == 15)
+                               S = MCDisassembler_SoftFail;
+                       if (writeback && (Rn == 15 || Rn == Rt))
+                               S = MCDisassembler_SoftFail;
+                       if (!type && Rm == 15)
+                               S = MCDisassembler_SoftFail;
+                       break;
+               case ARM_LDRD:
+               case ARM_LDRD_PRE:
+               case ARM_LDRD_POST:
+                       if (type && Rn == 15){
+                               if (Rt2 == 15)
+                                       S = MCDisassembler_SoftFail;
+                               break;
+                       }
+                       if (P == 0 && W == 1)
+                               S = MCDisassembler_SoftFail;
+                       if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
+                               S = MCDisassembler_SoftFail;
+                       if (!type && writeback && Rn == 15)
+                               S = MCDisassembler_SoftFail;
+                       if (writeback && (Rn == Rt || Rn == Rt2))
+                               S = MCDisassembler_SoftFail;
+                       break;
+               case ARM_LDRH:
+               case ARM_LDRH_PRE:
+               case ARM_LDRH_POST:
+                       if (type && Rn == 15){
+                               if (Rt == 15)
+                                       S = MCDisassembler_SoftFail;
+                               break;
+                       }
+                       if (Rt == 15)
+                               S = MCDisassembler_SoftFail;
+                       if (!type && Rm == 15)
+                               S = MCDisassembler_SoftFail;
+                       if (!type && writeback && (Rn == 15 || Rn == Rt))
+                               S = MCDisassembler_SoftFail;
+                       break;
+               case ARM_LDRSH:
+               case ARM_LDRSH_PRE:
+               case ARM_LDRSH_POST:
+               case ARM_LDRSB:
+               case ARM_LDRSB_PRE:
+               case ARM_LDRSB_POST:
+                       if (type && Rn == 15){
+                               if (Rt == 15)
+                                       S = MCDisassembler_SoftFail;
+                               break;
+                       }
+                       if (type && (Rt == 15 || (writeback && Rn == Rt)))
+                               S = MCDisassembler_SoftFail;
+                       if (!type && (Rt == 15 || Rm == 15))
+                               S = MCDisassembler_SoftFail;
+                       if (!type && writeback && (Rn == 15 || Rn == Rt))
+                               S = MCDisassembler_SoftFail;
+                       break;
+               default:
+                       break;
+       }
+
+       if (writeback) { // Writeback
+               Inst->writeback = true;
+               if (P)
+                       U |= ARMII_IndexModePre << 9;
+               else
+                       U |= ARMII_IndexModePost << 9;
+
+               // On stores, the writeback operand precedes Rt.
+               switch (MCInst_getOpcode(Inst)) {
+                       case ARM_STRD:
+                       case ARM_STRD_PRE:
+                       case ARM_STRD_POST:
+                       case ARM_STRH:
+                       case ARM_STRH_PRE:
+                       case ARM_STRH_POST:
+                               if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+                                       return MCDisassembler_Fail;
+                               break;
+                       default:
+                               break;
+               }
+       }
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
+               return MCDisassembler_Fail;
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_STRD:
+               case ARM_STRD_PRE:
+               case ARM_STRD_POST:
+               case ARM_LDRD:
+               case ARM_LDRD_PRE:
+               case ARM_LDRD_POST:
+                       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       if (writeback) {
+               // On loads, the writeback operand comes after Rt.
+               switch (MCInst_getOpcode(Inst)) {
+                       case ARM_LDRD:
+                       case ARM_LDRD_PRE:
+                       case ARM_LDRD_POST:
+                       case ARM_LDRH:
+                       case ARM_LDRH_PRE:
+                       case ARM_LDRH_POST:
+                       case ARM_LDRSH:
+                       case ARM_LDRSH_PRE:
+                       case ARM_LDRSH_POST:
+                       case ARM_LDRSB:
+                       case ARM_LDRSB_PRE:
+                       case ARM_LDRSB_POST:
+                       case ARM_LDRHTr:
+                       case ARM_LDRSBTr:
+                               if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+                                       return MCDisassembler_Fail;
+                               break;
+                       default:
+                               break;
+               }
+       }
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       if (type) {
+               MCOperand_CreateReg0(Inst, 0);
+               MCOperand_CreateImm0(Inst, U | (imm << 4) | Rm);
+       } else {
+               if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
+                       return MCDisassembler_Fail;
+               MCOperand_CreateImm0(Inst, U);
+       }
+
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+static DecodeStatus DecodeRFEInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned mode = fieldFromInstruction_4(Insn, 23, 2);
+
+       switch (mode) {
+               case 0:
+                       mode = ARM_AM_da;
+                       break;
+               case 1:
+                       mode = ARM_AM_ia;
+                       break;
+               case 2:
+                       mode = ARM_AM_db;
+                       break;
+               case 3:
+                       mode = ARM_AM_ib;
+                       break;
+       }
+
+       MCOperand_CreateImm0(Inst, mode);
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
+       unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
+       unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+
+       if (pred == 0xF)
+               return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
+
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+       return S;
+}
+
+static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst *Inst,
+               unsigned Insn, uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+       unsigned reglist = fieldFromInstruction_4(Insn, 0, 16);
+
+       if (pred == 0xF) {
+               // Ambiguous with RFE and SRS
+               switch (MCInst_getOpcode(Inst)) {
+                       case ARM_LDMDA:
+                               MCInst_setOpcode(Inst, ARM_RFEDA);
+                               break;
+                       case ARM_LDMDA_UPD:
+                               MCInst_setOpcode(Inst, ARM_RFEDA_UPD);
+                               break;
+                       case ARM_LDMDB:
+                               MCInst_setOpcode(Inst, ARM_RFEDB);
+                               break;
+                       case ARM_LDMDB_UPD:
+                               MCInst_setOpcode(Inst, ARM_RFEDB_UPD);
+                               break;
+                       case ARM_LDMIA:
+                               MCInst_setOpcode(Inst, ARM_RFEIA);
+                               break;
+                       case ARM_LDMIA_UPD:
+                               MCInst_setOpcode(Inst, ARM_RFEIA_UPD);
+                               break;
+                       case ARM_LDMIB:
+                               MCInst_setOpcode(Inst, ARM_RFEIB);
+                               break;
+                       case ARM_LDMIB_UPD:
+                               MCInst_setOpcode(Inst, ARM_RFEIB_UPD);
+                               break;
+                       case ARM_STMDA:
+                               MCInst_setOpcode(Inst, ARM_SRSDA);
+                               break;
+                       case ARM_STMDA_UPD:
+                               MCInst_setOpcode(Inst, ARM_SRSDA_UPD);
+                               break;
+                       case ARM_STMDB:
+                               MCInst_setOpcode(Inst, ARM_SRSDB);
+                               break;
+                       case ARM_STMDB_UPD:
+                               MCInst_setOpcode(Inst, ARM_SRSDB_UPD);
+                               break;
+                       case ARM_STMIA:
+                               MCInst_setOpcode(Inst, ARM_SRSIA);
+                               break;
+                       case ARM_STMIA_UPD:
+                               MCInst_setOpcode(Inst, ARM_SRSIA_UPD);
+                               break;
+                       case ARM_STMIB:
+                               MCInst_setOpcode(Inst, ARM_SRSIB);
+                               break;
+                       case ARM_STMIB_UPD:
+                               MCInst_setOpcode(Inst, ARM_SRSIB_UPD);
+                               break;
+                       default:
+                               return MCDisassembler_Fail;
+               }
+
+               // For stores (which become SRS's, the only operand is the mode.
+               if (fieldFromInstruction_4(Insn, 20, 1) == 0) {
+                       // Check SRS encoding constraints
+                       if (!(fieldFromInstruction_4(Insn, 22, 1) == 1 &&
+                                               fieldFromInstruction_4(Insn, 20, 1) == 0))
+                               return MCDisassembler_Fail;
+
+                       MCOperand_CreateImm0(Inst, fieldFromInstruction_4(Insn, 0, 4));
+                       return S;
+               }
+
+               return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
+       }
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail; // Tied
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned imod = fieldFromInstruction_4(Insn, 18, 2);
+       unsigned M = fieldFromInstruction_4(Insn, 17, 1);
+       unsigned iflags = fieldFromInstruction_4(Insn, 6, 3);
+       unsigned mode = fieldFromInstruction_4(Insn, 0, 5);
+
+       DecodeStatus S = MCDisassembler_Success;
+
+       // This decoder is called from multiple location that do not check
+       // the full encoding is valid before they do.
+       if (fieldFromInstruction_4(Insn, 5, 1) != 0 ||
+                       fieldFromInstruction_4(Insn, 16, 1) != 0 ||
+                       fieldFromInstruction_4(Insn, 20, 8) != 0x10)
+               return MCDisassembler_Fail;
+
+       // imod == '01' --> UNPREDICTABLE
+       // NOTE: Even though this is technically UNPREDICTABLE, we choose to
+       // return failure here.  The '01' imod value is unprintable, so there's
+       // nothing useful we could do even if we returned UNPREDICTABLE.
+
+       if (imod == 1) return MCDisassembler_Fail;
+
+       if (imod && M) {
+               MCInst_setOpcode(Inst, ARM_CPS3p);
+               MCOperand_CreateImm0(Inst, imod);
+               MCOperand_CreateImm0(Inst, iflags);
+               MCOperand_CreateImm0(Inst, mode);
+       } else if (imod && !M) {
+               MCInst_setOpcode(Inst, ARM_CPS2p);
+               MCOperand_CreateImm0(Inst, imod);
+               MCOperand_CreateImm0(Inst, iflags);
+               if (mode) S = MCDisassembler_SoftFail;
+       } else if (!imod && M) {
+               MCInst_setOpcode(Inst, ARM_CPS1p);
+               MCOperand_CreateImm0(Inst, mode);
+               if (iflags) S = MCDisassembler_SoftFail;
+       } else {
+               // imod == '00' && M == '0' --> UNPREDICTABLE
+               MCInst_setOpcode(Inst, ARM_CPS1p);
+               MCOperand_CreateImm0(Inst, mode);
+               S = MCDisassembler_SoftFail;
+       }
+
+       return S;
+}
+
+static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       unsigned imod = fieldFromInstruction_4(Insn, 9, 2);
+       unsigned M = fieldFromInstruction_4(Insn, 8, 1);
+       unsigned iflags = fieldFromInstruction_4(Insn, 5, 3);
+       unsigned mode = fieldFromInstruction_4(Insn, 0, 5);
+
+       DecodeStatus S = MCDisassembler_Success;
+
+       // imod == '01' --> UNPREDICTABLE
+       // NOTE: Even though this is technically UNPREDICTABLE, we choose to
+       // return failure here.  The '01' imod value is unprintable, so there's
+       // nothing useful we could do even if we returned UNPREDICTABLE.
+
+       if (imod == 1) return MCDisassembler_Fail;
+
+       if (imod && M) {
+               MCInst_setOpcode(Inst, ARM_t2CPS3p);
+               MCOperand_CreateImm0(Inst, imod);
+               MCOperand_CreateImm0(Inst, iflags);
+               MCOperand_CreateImm0(Inst, mode);
+       } else if (imod && !M) {
+               MCInst_setOpcode(Inst, ARM_t2CPS2p);
+               MCOperand_CreateImm0(Inst, imod);
+               MCOperand_CreateImm0(Inst, iflags);
+               if (mode) S = MCDisassembler_SoftFail;
+       } else if (!imod && M) {
+               MCInst_setOpcode(Inst, ARM_t2CPS1p);
+               MCOperand_CreateImm0(Inst, mode);
+               if (iflags) S = MCDisassembler_SoftFail;
+       } else {
+               // imod == '00' && M == '0' --> this is a HINT instruction
+               int imm = fieldFromInstruction_4(Insn, 0, 8);
+               // HINT are defined only for immediate in [0..4]
+               if(imm > 4) return MCDisassembler_Fail;
+               MCInst_setOpcode(Inst, ARM_t2HINT);
+               MCOperand_CreateImm0(Inst, imm);
+       }
+
+       return S;
+}
+
+static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rd = fieldFromInstruction_4(Insn, 8, 4);
+       unsigned imm = 0;
+
+       imm |= (fieldFromInstruction_4(Insn, 0, 8) << 0);
+       imm |= (fieldFromInstruction_4(Insn, 12, 3) << 8);
+       imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);
+       imm |= (fieldFromInstruction_4(Insn, 26, 1) << 11);
+
+       if (MCInst_getOpcode(Inst) == ARM_t2MOVTi16)
+               if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
+                       return MCDisassembler_Fail;
+       if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       MCOperand_CreateImm0(Inst, imm);
+
+       return S;
+}
+
+static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+       unsigned imm = 0;
+
+       imm |= (fieldFromInstruction_4(Insn, 0, 12) << 0);
+       imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);
+
+       if (MCInst_getOpcode(Inst) == ARM_MOVTi16)
+               if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
+                       return MCDisassembler_Fail;
+
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       MCOperand_CreateImm0(Inst, imm);
+
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rd = fieldFromInstruction_4(Insn, 16, 4);
+       unsigned Rn = fieldFromInstruction_4(Insn, 0, 4);
+       unsigned Rm = fieldFromInstruction_4(Insn, 8, 4);
+       unsigned Ra = fieldFromInstruction_4(Insn, 12, 4);
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+
+       if (pred == 0xF)
+               return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
+
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned add = fieldFromInstruction_4(Val, 12, 1);
+       unsigned imm = fieldFromInstruction_4(Val, 0, 12);
+       unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       if (!add) imm *= (unsigned int)-1;
+       if (imm == 0 && !add) imm = (unsigned int)INT32_MIN;
+       MCOperand_CreateImm0(Inst, imm);
+       //if (Rn == 15)
+       //  tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
+
+       return S;
+}
+
+static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
+       unsigned U = fieldFromInstruction_4(Val, 8, 1);
+       unsigned imm = fieldFromInstruction_4(Val, 0, 8);
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       if (U)
+               MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_add, (unsigned char)imm));
+       else
+               MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_sub, (unsigned char)imm));
+
+       return S;
+}
+
+static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
+}
+
+static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus Status = MCDisassembler_Success;
+
+       // Note the J1 and J2 values are from the encoded instruction.  So here
+       // change them to I1 and I2 values via as documented:
+       // I1 = NOT(J1 EOR S);
+       // I2 = NOT(J2 EOR S);
+       // and build the imm32 with one trailing zero as documented:
+       // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
+       unsigned S = fieldFromInstruction_4(Insn, 26, 1);
+       unsigned J1 = fieldFromInstruction_4(Insn, 13, 1);
+       unsigned J2 = fieldFromInstruction_4(Insn, 11, 1);
+       unsigned I1 = !(J1 ^ S);
+       unsigned I2 = !(J2 ^ S);
+       unsigned imm10 = fieldFromInstruction_4(Insn, 16, 10);
+       unsigned imm11 = fieldFromInstruction_4(Insn, 0, 11);
+       unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
+       int imm32 = SignExtend32(tmp << 1, 25);
+       MCOperand_CreateImm0(Inst, imm32);
+
+       return Status;
+}
+
+static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
+       unsigned imm = fieldFromInstruction_4(Insn, 0, 24) << 2;
+
+       if (pred == 0xF) {
+               MCInst_setOpcode(Inst, ARM_BLXi);
+               imm |= fieldFromInstruction_4(Insn, 24, 1) << 1;
+               MCOperand_CreateImm0(Inst, SignExtend32(imm, 26));
+               return S;
+       }
+
+       MCOperand_CreateImm0(Inst, SignExtend32(imm, 26));
+       if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       return S;
+}
+
+
+static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+
+       unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
+       unsigned align = fieldFromInstruction_4(Val, 4, 2);
+
+       if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
+               return MCDisassembler_Fail;
+       if (!align)
+               MCOperand_CreateImm0(Inst, 0);
+       else
+               MCOperand_CreateImm0(Inst, 4 << align);
+
+       return S;
+}
+
+static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Insn,
+               uint64_t Address, const void *Decoder)
+{
+       DecodeStatus S = MCDisassembler_Success;
+       unsigned wb, Rn, Rm;
+       unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
+       Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
+       wb = fieldFromInstruction_4(Insn, 16, 4);
+       Rn = fieldFromInstruction_4(Insn, 16, 4);
+       Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
+       Rm = fieldFromInstruction_4(Insn, 0, 4);
+
+       // First output register
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_VLD1q16: case ARM_VLD1q32: case ARM_VLD1q64: case ARM_VLD1q8:
+               case ARM_VLD1q16wb_fixed: case ARM_VLD1q16wb_register:
+               case ARM_VLD1q32wb_fixed: case ARM_VLD1q32wb_register:
+               case ARM_VLD1q64wb_fixed: case ARM_VLD1q64wb_register:
+               case ARM_VLD1q8wb_fixed: case ARM_VLD1q8wb_register:
+               case ARM_VLD2d16: case ARM_VLD2d32: case ARM_VLD2d8:
+               case ARM_VLD2d16wb_fixed: case ARM_VLD2d16wb_register:
+               case ARM_VLD2d32wb_fixed: case ARM_VLD2d32wb_register:
+               case ARM_VLD2d8wb_fixed: case ARM_VLD2d8wb_register:
+                       if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               case ARM_VLD2b16:
+               case ARM_VLD2b32:
+               case ARM_VLD2b8:
+               case ARM_VLD2b16wb_fixed:
+               case ARM_VLD2b16wb_register:
+               case ARM_VLD2b32wb_fixed:
+               case ARM_VLD2b32wb_register:
+               case ARM_VLD2b8wb_fixed:
+               case ARM_VLD2b8wb_register:
+                       if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
+                               return MCDisassembler_Fail;
+       }
+
+       // Second output register
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_VLD3d8:
+               case ARM_VLD3d16:
+               case ARM_VLD3d32:
+               case ARM_VLD3d8_UPD:
+               case ARM_VLD3d16_UPD:
+               case ARM_VLD3d32_UPD:
+               case ARM_VLD4d8:
+               case ARM_VLD4d16:
+               case ARM_VLD4d32:
+               case ARM_VLD4d8_UPD:
+               case ARM_VLD4d16_UPD:
+               case ARM_VLD4d32_UPD:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               case ARM_VLD3q8:
+               case ARM_VLD3q16:
+               case ARM_VLD3q32:
+               case ARM_VLD3q8_UPD:
+               case ARM_VLD3q16_UPD:
+               case ARM_VLD3q32_UPD:
+               case ARM_VLD4q8:
+               case ARM_VLD4q16:
+               case ARM_VLD4q32:
+               case ARM_VLD4q8_UPD:
+               case ARM_VLD4q16_UPD:
+               case ARM_VLD4q32_UPD:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
+                               return MCDisassembler_Fail;
+               default:
+                       break;
+       }
+
+       // Third output register
+       switch(MCInst_getOpcode(Inst)) {
+               case ARM_VLD3d8:
+               case ARM_VLD3d16:
+               case ARM_VLD3d32:
+               case ARM_VLD3d8_UPD:
+               case ARM_VLD3d16_UPD:
+               case ARM_VLD3d32_UPD:
+               case ARM_VLD4d8:
+               case ARM_VLD4d16:
+               case ARM_VLD4d32:
+               case ARM_VLD4d8_UPD:
+               case ARM_VLD4d16_UPD:
+               case ARM_VLD4d32_UPD:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               case ARM_VLD3q8:
+               case ARM_VLD3q16:
+               case ARM_VLD3q32:
+               case ARM_VLD3q8_UPD:
+               case ARM_VLD3q16_UPD:
+               case ARM_VLD3q32_UPD:
+               case ARM_VLD4q8:
+               case ARM_VLD4q16:
+               case ARM_VLD4q32:
+               case ARM_VLD4q8_UPD:
+               case ARM_VLD4q16_UPD:
+               case ARM_VLD4q32_UPD:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       // Fourth output register
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_VLD4d8:
+               case ARM_VLD4d16:
+               case ARM_VLD4d32:
+               case ARM_VLD4d8_UPD:
+               case ARM_VLD4d16_UPD:
+               case ARM_VLD4d32_UPD:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               case ARM_VLD4q8:
+               case ARM_VLD4q16:
+               case ARM_VLD4q32:
+               case ARM_VLD4q8_UPD:
+               case ARM_VLD4q16_UPD:
+               case ARM_VLD4q32_UPD:
+                       if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       // Writeback operand
+       switch (MCInst_getOpcode(Inst)) {
+               case ARM_VLD1d8wb_fixed:
+               case ARM_VLD1d16wb_fixed:
+               case ARM_VLD1d32wb_fixed:
+               case ARM_VLD1d64wb_fixed:
+               case ARM_VLD1d8wb_register:
+               case ARM_VLD1d16wb_register:
+               case ARM_VLD1d32wb_register:
+               case ARM_VLD1d64wb_register:
+               case ARM_VLD1q8wb_fixed:
+               case ARM_VLD1q16wb_fixed:
+               case ARM_VLD1q32wb_fixed:
+               case ARM_VLD1q64wb_fixed:
+               case ARM_VLD1q8wb_register:
+               case ARM_VLD1q16wb_register:
+               case ARM_VLD1q32wb_register:
+               case ARM_VLD1q64wb_register:
+               case ARM_VLD1d8Twb_fixed:
+               case ARM_VLD1d8Twb_register:
+               case ARM_VLD1d16Twb_fixed:
+               case ARM_VLD1d16Twb_register:
+               case ARM_VLD1d32Twb_fixed:
+               case ARM_VLD1d32Twb_register:
+               case ARM_VLD1d64Twb_fixed:
+               case ARM_VLD1d64Twb_register:
+               case ARM_VLD1d8Qwb_fixed:
+               case ARM_VLD1d8Qwb_register:
+               case ARM_VLD1d16Qwb_fixed:
+               case ARM_VLD1d16Qwb_register:
+               case ARM_VLD1d32Qwb_fixed:
+               case ARM_VLD1d32Qwb_register:
+               case ARM_VLD1d64Qwb_fixed:
+               case ARM_VLD1d64Qwb_register:
+               case ARM_VLD2d8wb_fixed:
+               case ARM_VLD2d16wb_fixed:
+               case ARM_VLD2d32wb_fixed:
+               case ARM_VLD2q8wb_fixed:
+               case ARM_VLD2q16wb_fixed:
+               case ARM_VLD2q32wb_fixed:
+               case ARM_VLD2d8wb_register:
+               case ARM_VLD2d16wb_register:
+               case ARM_VLD2d32wb_register:
+               case ARM_VLD2q8wb_register:
+               case ARM_VLD2q16wb_register:
+               case ARM_VLD2q32wb_register:
+               case ARM_VLD2b8wb_fixed:
+               case ARM_VLD2b16wb_fixed:
+               case ARM_VLD2b32wb_fixed:
+               case ARM_VLD2b8wb_register:
+               case ARM_VLD2b16wb_register:
+               case ARM_VLD2b32wb_register:
+                       MCOperand_CreateImm0(Inst, 0);
+                       break;
+               case ARM_VLD3d8_UPD:
+               case ARM_VLD3d16_UPD:
+               case ARM_VLD3d32_UPD:
+               case ARM_VLD3q8_UPD:
+               case ARM_VLD3q16_UPD:
+               case ARM_VLD3q32_UPD:
+               case ARM_VLD4d8_UPD:
+               case ARM_VLD4d16_UPD:
+               case ARM_VLD4d32_UPD:
+               case ARM_VLD4q8_UPD:
+               case ARM_VLD4q16_UPD:
+               case ARM_VLD4q32_UPD:
+                       if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
+                               return MCDisassembler_Fail;
+                       break;
+               default:
+                       break;
+       }
+
+       // AddrMode6 Base (register+alignment)
+       if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
+               return MCDisassembler_Fail;
+
+       // AddrMode6 Offset (register)
+       switch (MCInst_getOpcode(Inst)) {
+               default:
+                       // The below have been updated to have explicit am6offset split
+                       // between fixed and register offset. For those instructions not
+   &