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

Evan Cheng evan.cheng at apple.com
Tue Aug 9 17:45:36 PDT 2011


Awesome. Thanks for doing this!

Evan

On Aug 10, 2011, at 4:55 AM, Owen Anderson <resistor at mac.com> wrote:

> Author: resistor
> Date: Tue Aug  9 15:55:18 2011
> New Revision: 137144
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=137144&view=rev
> Log:
> Replace the existing ARM disassembler with a new one based on the FixedLenDecoderEmitter.
> This new disassembler can correctly decode all the testcases that the old one did, though
> some "expected failure" testcases are XFAIL'd for now because it is not (yet) as strict in
> operand checking as the old one was.
> 
> Removed:
>    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
>    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
>    llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>    llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
>    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
>    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
>    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
>    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.h
>    llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt
>    llvm/trunk/lib/Target/ARM/Makefile
>    llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-BFI-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-DSB-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-LSL-regform.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-MCR-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-RSC-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-SRS-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt
>    llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt
>    llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Tue Aug  9 15:55:18 2011
> @@ -152,6 +152,7 @@
>                                      (ops (i32 14), (i32 zero_reg))> {
>   let PrintMethod = "printPredicateOperand";
>   let ParserMatchClass = CondCodeOperand;
> +    let DecoderMethod = "DecodePredicateOperand";
> }
> 
> // Conditional code result for instructions whose 's' bit is set, e.g. subs.
> @@ -160,6 +161,7 @@
>   let EncoderMethod = "getCCOutOpValue";
>   let PrintMethod = "printSBitModifierOperand";
>   let ParserMatchClass = CCOutOperand;
> +    let DecoderMethod = "DecodeCCOutOperand";
> }
> 
> // Same as cc_out except it defaults to setting CPSR.
> @@ -167,6 +169,7 @@
>   let EncoderMethod = "getCCOutOpValue";
>   let PrintMethod = "printSBitModifierOperand";
>   let ParserMatchClass = CCOutOperand;
> +    let DecoderMethod = "DecodeCCOutOperand";
> }
> 
> // ARM special operands for disassembly only.
> @@ -199,15 +202,19 @@
> //     64       64 - <imm> is encoded in imm6<5:0>
> def shr_imm8  : Operand<i32> {
>   let EncoderMethod = "getShiftRight8Imm";
> +  let DecoderMethod = "DecodeShiftRight8Imm";
> }
> def shr_imm16 : Operand<i32> {
>   let EncoderMethod = "getShiftRight16Imm";
> +  let DecoderMethod = "DecodeShiftRight16Imm";
> }
> def shr_imm32 : Operand<i32> {
>   let EncoderMethod = "getShiftRight32Imm";
> +  let DecoderMethod = "DecodeShiftRight32Imm";
> }
> def shr_imm64 : Operand<i32> {
>   let EncoderMethod = "getShiftRight64Imm";
> +  let DecoderMethod = "DecodeShiftRight64Imm";
> }
> 
> //===----------------------------------------------------------------------===//
> @@ -579,6 +586,8 @@
>   let Inst{11-8}  = addr{7-4};    // imm7_4/zero
>   let Inst{7-4}   = op;
>   let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
> +
> +  let DecoderMethod = "DecodeAddrMode3Instruction";
> }
> 
> class AI3ldstidx<bits<4> op, bit op20, bit isLd, bit isPre, dag oops, dag iops,
> @@ -1265,6 +1274,7 @@
>   let AsmString = !strconcat(opc, "${p}", asm);
>   let Pattern = pattern;
>   let PostEncoderMethod = "VFPThumb2PostEncoder";
> +  let DecoderNamespace = "VFP";
>   list<Predicate> Predicates = [HasVFP2];
> }
> 
> @@ -1280,6 +1290,7 @@
>   let AsmString = asm;
>   let Pattern = pattern;
>   let PostEncoderMethod = "VFPThumb2PostEncoder";
> +  let DecoderNamespace = "VFP";
>   list<Predicate> Predicates = [HasVFP2];
> }
> 
> @@ -1597,6 +1608,7 @@
>   let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
>   let Pattern = pattern;
>   list<Predicate> Predicates = [HasNEON];
> +  let DecoderNamespace = "NEON";
> }
> 
> // Same as NeonI except it does not have a "data type" specifier.
> @@ -1609,6 +1621,7 @@
>   let AsmString = !strconcat(opc, "${p}", "\t", asm);
>   let Pattern = pattern;
>   list<Predicate> Predicates = [HasNEON];
> +  let DecoderNamespace = "NEON";
> }
> 
> class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
> @@ -1700,6 +1713,7 @@
>   let Inst{24}    = SIMM{7};
>   let Inst{18-16} = SIMM{6-4};
>   let Inst{3-0}   = SIMM{3-0};
> +  let DecoderMethod = "DecodeNEONModImmInstruction";
> }
> 
> // NEON 2 vector register format.
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Aug  9 15:55:18 2011
> @@ -315,6 +315,7 @@
> def brtarget : Operand<OtherVT> {
>   let EncoderMethod = "getBranchTargetOpValue";
>   let OperandType = "OPERAND_PCREL";
> +  let DecoderMethod = "DecodeT2BROperand";
> }
> 
> // FIXME: get rid of this one?
> @@ -343,6 +344,7 @@
>   // Encoded the same as branch targets.
>   let EncoderMethod = "getARMBranchTargetOpValue";
>   let OperandType = "OPERAND_PCREL";
> +    let DecoderMethod = "DecodeBLTargetOperand";
> }
> 
> 
> @@ -352,6 +354,7 @@
>   let EncoderMethod = "getRegisterListOpValue";
>   let ParserMatchClass = RegListAsmOperand;
>   let PrintMethod = "printRegisterList";
> +  let DecoderMethod = "DecodeRegListOperand";
> }
> 
> def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; }
> @@ -359,6 +362,7 @@
>   let EncoderMethod = "getRegisterListOpValue";
>   let ParserMatchClass = DPRRegListAsmOperand;
>   let PrintMethod = "printRegisterList";
> +  let DecoderMethod = "DecodeDPRRegListOperand";
> }
> 
> def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; }
> @@ -366,6 +370,7 @@
>   let EncoderMethod = "getRegisterListOpValue";
>   let ParserMatchClass = SPRRegListAsmOperand;
>   let PrintMethod = "printRegisterList";
> +  let DecoderMethod = "DecodeSPRRegListOperand";
> }
> 
> // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
> @@ -385,6 +390,7 @@
> 
> def neon_vcvt_imm32 : Operand<i32> {
>   let EncoderMethod = "getNEONVcvtImm32OpValue";
> +  let DecoderMethod = "DecodeVCVTImmOperand";
> }
> 
> // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
> @@ -431,6 +437,7 @@
>                                 [shl, srl, sra, rotr]> {
>   let EncoderMethod = "getSORegRegOpValue";
>   let PrintMethod = "printSORegRegOperand";
> +  let DecoderMethod = "DecodeSORegRegOperand";
>   let ParserMatchClass = ShiftedRegAsmOperand;
>   let MIOperandInfo = (ops GPR, GPR, i32imm);
> }
> @@ -441,6 +448,7 @@
>                                 [shl, srl, sra, rotr]> {
>   let EncoderMethod = "getSORegImmOpValue";
>   let PrintMethod = "printSORegImmOperand";
> +  let DecoderMethod = "DecodeSORegImmOperand";
>   let ParserMatchClass = ShiftedImmAsmOperand;
>   let MIOperandInfo = (ops GPR, i32imm);
> }
> @@ -451,6 +459,7 @@
>                                   [shl,srl,sra,rotr]> {
>   let EncoderMethod = "getSORegRegOpValue";
>   let PrintMethod = "printSORegRegOperand";
> +  let DecoderMethod = "DecodeSORegRegOperand";
>   let MIOperandInfo = (ops GPR, GPR, i32imm);
> }
> 
> @@ -460,6 +469,7 @@
>                                   [shl,srl,sra,rotr]> {
>   let EncoderMethod = "getSORegImmOpValue";
>   let PrintMethod = "printSORegImmOperand";
> +  let DecoderMethod = "DecodeSORegImmOperand";
>   let MIOperandInfo = (ops GPR, i32imm);
> }
> 
> @@ -472,6 +482,7 @@
>   }]> {
>   let EncoderMethod = "getSOImmOpValue";
>   let ParserMatchClass = SOImmAsmOperand;
> +    let DecoderMethod = "DecodeSOImmOperand";
> }
> 
> // Break so_imm's up into two pieces.  This handles immediates with up to 16
> @@ -552,6 +563,7 @@
> }] > {
>   let EncoderMethod = "getBitfieldInvertedMaskOpValue";
>   let PrintMethod = "printBitfieldInvMaskImmOperand";
> +  let DecoderMethod = "DecodeBitfieldMaskOperand";
>   let ParserMatchClass = BitfieldAsmOperand;
> }
> 
> @@ -599,6 +611,7 @@
> 
>   let EncoderMethod = "getAddrModeImm12OpValue";
>   let PrintMethod = "printAddrModeImm12Operand";
> +  let DecoderMethod = "DecodeAddrModeImm12Operand";
>   let ParserMatchClass = MemImm12OffsetAsmOperand;
>   let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
> }
> @@ -610,6 +623,7 @@
>   let EncoderMethod = "getLdStSORegOpValue";
>   // FIXME: Simplify the printer
>   let PrintMethod = "printAddrMode2Operand";
> +  let DecoderMethod = "DecodeSORegMemOperand";
>   let ParserMatchClass = MemRegOffsetAsmOperand;
>   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$shift);
> }
> @@ -645,6 +659,7 @@
> }
> def postidx_reg : Operand<i32> {
>   let EncoderMethod = "getPostIdxRegOpValue";
> +  let DecoderMethod = "DecodePostIdxReg";
>   let PrintMethod = "printPostIdxRegOperand";
>   let ParserMatchClass = PostIdxRegAsmOperand;
>   let MIOperandInfo = (ops GPR, i32imm);
> @@ -707,6 +722,7 @@
>                 ComplexPattern<i32, 2, "SelectAddrMode3Offset",
>                                [], [SDNPWantRoot]> {
>   let EncoderMethod = "getAddrMode3OffsetOpValue";
> +  let DecoderMethod = "DecodeAddrMode3Offset";
>   let PrintMethod = "printAddrMode3OffsetOperand";
>   let MIOperandInfo = (ops GPR, i32imm);
> }
> @@ -725,6 +741,7 @@
>                 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
>   let PrintMethod = "printAddrMode5Operand";
>   let EncoderMethod = "getAddrMode5OpValue";
> +  let DecoderMethod = "DecodeAddrMode5Operand";
>   let ParserMatchClass = AddrMode5AsmOperand;
>   let MIOperandInfo = (ops GPR:$base, i32imm);
> }
> @@ -736,6 +753,7 @@
>   let PrintMethod = "printAddrMode6Operand";
>   let MIOperandInfo = (ops GPR:$addr, i32imm);
>   let EncoderMethod = "getAddrMode6AddressOpValue";
> +  let DecoderMethod = "DecodeAddrMode6Operand";
> }
> 
> def am6offset : Operand<i32>,
> @@ -744,6 +762,7 @@
>   let PrintMethod = "printAddrMode6OffsetOperand";
>   let MIOperandInfo = (ops GPR);
>   let EncoderMethod = "getAddrMode6OffsetOpValue";
> +  let DecoderMethod = "DecodeGPRRegisterClass";
> }
> 
> // Special version of addrmode6 to handle alignment encoding for VST1/VLD1
> @@ -778,6 +797,7 @@
> def addr_offset_none : Operand<i32>,
>                        ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> {
>   let PrintMethod = "printAddrMode7Operand";
> +  let DecoderMethod = "DecodeAddrMode7Operand";
>   let ParserMatchClass = MemNoOffsetAsmOperand;
>   let MIOperandInfo = (ops GPR:$base);
> }
> @@ -793,6 +813,7 @@
> def p_imm : Operand<i32> {
>   let PrintMethod = "printPImmediate";
>   let ParserMatchClass = CoprocNumAsmOperand;
> +  let DecoderMethod = "DecodeCoprocessor";
> }
> 
> def CoprocRegAsmOperand : AsmOperandClass {
> @@ -1654,6 +1675,7 @@
>                [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
>     bits<24> target;
>     let Inst{23-0} = target;
> +    let DecoderMethod = "DecodeBranchImmInstruction";
>   }
> 
>   let isBarrier = 1 in {
> @@ -1917,6 +1939,7 @@
>     let Inst{23} = addr{12};
>     let Inst{19-16} = addr{17-14};
>     let Inst{11-0} = addr{11-0};
> +    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
>     let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
>   }
> 
> @@ -1933,6 +1956,8 @@
>      let Inst{23} = offset{12};
>      let Inst{19-16} = addr;
>      let Inst{11-0} = offset{11-0};
> +
> +    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
>    }
> 
>    def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
> @@ -1948,7 +1973,10 @@
>     let Inst{23} = offset{12};
>     let Inst{19-16} = addr;
>     let Inst{11-0} = offset{11-0};
> +
> +    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
>   }
> +
> }
> 
> let mayLoad = 1, neverHasSideEffects = 1 in {
> @@ -2019,20 +2047,39 @@
> 
> // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
> let mayLoad = 1, neverHasSideEffects = 1 in {
> -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
> -                   (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
> +def LDRTr : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
> +                   (ins ldst_so_reg:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
> +                   "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
> +  // {17-14}  Rn
> +  // {13}     1 == Rm, 0 == imm12
> +  // {12}     isAdd
> +  // {11-0}   imm12/Rm
> +  bits<18> addr;
> +  let Inst{25} = 1;
> +  let Inst{23} = addr{12};
> +  let Inst{21} = 1; // overwrite
> +  let Inst{19-16} = addr{17-14};
> +  let Inst{11-5} = addr{11-5};
> +  let Inst{4} = 0;
> +  let Inst{3-0} = addr{3-0};
> +  let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> +}
> +def LDRTi : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
> +                   (ins addrmode_imm12:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
>                    "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
>   // {17-14}  Rn
>   // {13}     1 == Rm, 0 == imm12
>   // {12}     isAdd
>   // {11-0}   imm12/Rm
>   bits<18> addr;
> -  let Inst{25} = addr{13};
> +  let Inst{25} = 0;
>   let Inst{23} = addr{12};
>   let Inst{21} = 1; // overwrite
>   let Inst{19-16} = addr{17-14};
>   let Inst{11-0} = addr{11-0};
>   let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
> @@ -2049,6 +2096,7 @@
>   let Inst{21} = 1; // overwrite
>   let Inst{19-16} = addr;
>   let Inst{11-0} = offset{11-0};
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> def LDRBT_POST_IMM : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
> @@ -2065,6 +2113,7 @@
>   let Inst{21} = 1; // overwrite
>   let Inst{19-16} = addr;
>   let Inst{11-0} = offset{11-0};
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> multiclass AI3ldrT<bits<4> op, string opc> {
> @@ -2151,6 +2200,8 @@
>      let Inst{23} = offset{12};
>      let Inst{19-16} = addr;
>      let Inst{11-0} = offset{11-0};
> +
> +    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
>    }
> 
>    def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
> @@ -2166,6 +2217,8 @@
>     let Inst{23} = offset{12};
>     let Inst{19-16} = addr;
>     let Inst{11-0} = offset{11-0};
> +
> +    let DecoderMethod = "DecodeAddrMode2IdxInstruction";
>   }
> }
> 
> @@ -2287,6 +2340,7 @@
>   let Inst{21} = 1; // overwrite
>   let Inst{4} = 0;
>   let AsmMatchConverter = "cvtStWriteBackRegAddrMode2";
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> def STRTi : AI2stridxT<0, 0, (outs GPR:$Rn_wb),
> @@ -2297,6 +2351,7 @@
>   let Inst{25} = 0;
>   let Inst{21} = 1; // overwrite
>   let AsmMatchConverter = "cvtStWriteBackRegAddrMode2";
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> 
> @@ -2309,6 +2364,7 @@
>   let Inst{21} = 1; // overwrite
>   let Inst{4} = 0;
>   let AsmMatchConverter = "cvtStWriteBackRegAddrMode2";
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> def STRBTi : AI2stridxT<1, 0, (outs GPR:$Rn_wb),
> @@ -2319,6 +2375,7 @@
>   let Inst{25} = 0;
>   let Inst{21} = 1; // overwrite
>   let AsmMatchConverter = "cvtStWriteBackRegAddrMode2";
> +  let DecoderMethod = "DecodeAddrMode2IdxInstruction";
> }
> 
> multiclass AI3strT<bits<4> op, string opc> {
> @@ -2373,6 +2430,8 @@
>     let Inst{24-23} = 0b01;       // Increment After
>     let Inst{21}    = 1;          // Writeback
>     let Inst{20}    = L_bit;
> +
> +    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
>   }
>   def DA :
>     AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
> @@ -2389,6 +2448,8 @@
>     let Inst{24-23} = 0b00;       // Decrement After
>     let Inst{21}    = 1;          // Writeback
>     let Inst{20}    = L_bit;
> +
> +    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
>   }
>   def DB :
>     AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
> @@ -2405,6 +2466,8 @@
>     let Inst{24-23} = 0b10;       // Decrement Before
>     let Inst{21}    = 1;          // Writeback
>     let Inst{20}    = L_bit;
> +
> +    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
>   }
>   def IB :
>     AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
> @@ -2421,6 +2484,8 @@
>     let Inst{24-23} = 0b11;       // Increment Before
>     let Inst{21}    = 1;          // Writeback
>     let Inst{20}    = L_bit;
> +
> +    let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
>   }
> }
> 
> @@ -2504,8 +2569,6 @@
>   let Inst{25} = 0;
> }
> 
> -
> -
> let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
> def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
>                 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
> @@ -3383,6 +3446,7 @@
> 
> 
> multiclass AI_smla<string opc, PatFrag opnode> {
> +  let DecoderMethod = "DecodeSMLAInstruction" in {
>   def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd),
>               (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
>               IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
> @@ -3425,6 +3489,7 @@
>               [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
>                                         (sra GPR:$Rm, (i32 16))), (i32 16))))]>,
>             Requires<[IsARM, HasV5TE]>;
> +  }
> }
> 
> defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
> @@ -3989,7 +4054,7 @@
> }
> 
> multiclass LdStCop<bits<4> op31_28, bit load, dag ops, string opc, string cond>{
> -
> +  let DecoderNamespace = "Common" in {
>   def _OFFSET : ACI<(outs),
>       !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops),
>       !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr"> {
> @@ -3998,6 +4063,7 @@
>     let Inst{21} = 0; // W = 0
>     let Inst{22} = 0; // D = 0
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def _PRE : ACI<(outs),
> @@ -4008,6 +4074,7 @@
>     let Inst{21} = 1; // W = 1
>     let Inst{22} = 0; // D = 0
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def _POST : ACI<(outs),
> @@ -4018,6 +4085,7 @@
>     let Inst{21} = 1; // W = 1
>     let Inst{22} = 0; // D = 0
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def _OPTION : ACI<(outs),
> @@ -4030,6 +4098,7 @@
>     let Inst{21} = 0; // W = 0
>     let Inst{22} = 0; // D = 0
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def L_OFFSET : ACI<(outs),
> @@ -4040,6 +4109,7 @@
>     let Inst{21} = 0; // W = 0
>     let Inst{22} = 1; // D = 1
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def L_PRE : ACI<(outs),
> @@ -4051,6 +4121,7 @@
>     let Inst{21} = 1; // W = 1
>     let Inst{22} = 1; // D = 1
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def L_POST : ACI<(outs),
> @@ -4063,6 +4134,7 @@
>     let Inst{21} = 1; // W = 1
>     let Inst{22} = 1; // D = 1
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
>   }
> 
>   def L_OPTION : ACI<(outs),
> @@ -4076,6 +4148,8 @@
>     let Inst{21} = 0; // W = 0
>     let Inst{22} = 1; // D = 1
>     let Inst{20} = load;
> +    let DecoderMethod = "DecodeCopMemInstruction";
> +  }
>   }
> }
> 
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Tue Aug  9 15:55:18 2011
> @@ -191,6 +191,7 @@
>           "vld1", Dt, "\\{$Vd\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> class VLD1Q<bits<4> op7_4, string Dt>
>   : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$Vd, DPR:$dst2),
> @@ -198,6 +199,7 @@
>           "vld1", Dt, "\\{$Vd, $dst2\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def  VLD1d8   : VLD1D<{0,0,0,?}, "8">;
> @@ -222,6 +224,7 @@
>           "vld1", Dt, "\\{$Vd\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> class VLD1QWB<bits<4> op7_4, string Dt>
>   : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb),
> @@ -229,6 +232,7 @@
>           "vld1", Dt, "\\{$Vd, $dst2\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def VLD1d8_UPD  : VLD1DWB<{0,0,0,?}, "8">;
> @@ -253,12 +257,14 @@
>           "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> class VLD1D3WB<bits<4> op7_4, string Dt>
>   : NLdSt<0,0b10,0b0110,op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb),
>           (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD1x3u, "vld1", Dt,
>           "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm", "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def VLD1d8T      : VLD1D3<{0,0,0,?}, "8">;
> @@ -281,6 +287,7 @@
>           "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> class VLD1D4WB<bits<4> op7_4, string Dt>
>   : NLdSt<0,0b10,0b0010,op7_4,
> @@ -289,6 +296,7 @@
>           "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", "$Rn.addr = $wb",
>           []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def VLD1d8Q      : VLD1D4<{0,0,?,?}, "8">;
> @@ -311,6 +319,7 @@
>           "vld2", Dt, "\\{$Vd, $dst2\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> class VLD2Q<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b10, 0b0011, op7_4,
> @@ -319,6 +328,7 @@
>           "vld2", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def  VLD2d8   : VLD2D<0b1000, {0,0,?,?}, "8">;
> @@ -344,6 +354,7 @@
>           "vld2", Dt, "\\{$Vd, $dst2\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> class VLD2QWB<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b10, 0b0011, op7_4,
> @@ -352,6 +363,7 @@
>           "vld2", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def VLD2d8_UPD  : VLD2DWB<0b1000, {0,0,?,?}, "8">;
> @@ -385,6 +397,7 @@
>           "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def  VLD3d8   : VLD3D<0b0100, {0,0,0,?}, "8">;
> @@ -403,6 +416,7 @@
>           "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def VLD3d8_UPD  : VLD3DWB<0b0100, {0,0,0,?}, "8">;
> @@ -442,6 +456,7 @@
>           "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def  VLD4d8   : VLD4D<0b0000, {0,0,?,?}, "8">;
> @@ -460,6 +475,7 @@
>           "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVLDInstruction";
> }
> 
> def VLD4d8_UPD  : VLD4DWB<0b0000, {0,0,?,?}, "8">;
> @@ -826,6 +842,7 @@
>           [(set DPR:$Vd, (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD1DupInstruction";
> }
> class VLD1QDUPPseudo<ValueType Ty, PatFrag LoadOp> : VLDQPseudo<IIC_VLD1dup> {
>   let Pattern = [(set QPR:$dst,
> @@ -853,6 +870,7 @@
>           "vld1", Dt, "\\{$Vd[], $dst2[]\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD1DupInstruction";
> }
> 
> def VLD1DUPq8  : VLD1QDUP<{0,0,1,0}, "8">;
> @@ -865,12 +883,14 @@
>           (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD1dupu,
>           "vld1", Dt, "\\{$Vd[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD1DupInstruction";
> }
> class VLD1QDUPWB<bits<4> op7_4, string Dt>
>   : NLdSt<1, 0b10, 0b1100, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb),
>           (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD1dupu,
>           "vld1", Dt, "\\{$Vd[], $dst2[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD1DupInstruction";
> }
> 
> def VLD1DUPd8_UPD  : VLD1DUPWB<{0,0,0,0}, "8">;
> @@ -892,6 +912,7 @@
>           "vld2", Dt, "\\{$Vd[], $dst2[]\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD2DupInstruction";
> }
> 
> def VLD2DUPd8  : VLD2DUP<{0,0,0,?}, "8">;
> @@ -913,6 +934,7 @@
>           (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD2dupu,
>           "vld2", Dt, "\\{$Vd[], $dst2[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD2DupInstruction";
> }
> 
> def VLD2DUPd8_UPD  : VLD2DUPWB<{0,0,0,0}, "8">;
> @@ -934,6 +956,7 @@
>           "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD3DupInstruction";
> }
> 
> def VLD3DUPd8  : VLD3DUP<{0,0,0,?}, "8">;
> @@ -956,6 +979,7 @@
>           "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD3DupInstruction";
> }
> 
> def VLD3DUPd8_UPD  : VLD3DUPWB<{0,0,0,0}, "8">;
> @@ -978,6 +1002,7 @@
>           "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD4DupInstruction";
> }
> 
> def VLD4DUPd8  : VLD4DUP<{0,0,0,?}, "8">;
> @@ -1001,6 +1026,7 @@
>           "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVLD4DupInstruction";
> }
> 
> def VLD4DUPd8_UPD  : VLD4DUPWB<{0,0,0,0}, "8">;
> @@ -1046,6 +1072,7 @@
>           IIC_VST1, "vst1", Dt, "\\{$Vd\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> class VST1Q<bits<4> op7_4, string Dt>
>   : NLdSt<0,0b00,0b1010,op7_4, (outs),
> @@ -1053,6 +1080,7 @@
>           "vst1", Dt, "\\{$Vd, $src2\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def  VST1d8   : VST1D<{0,0,0,?}, "8">;
> @@ -1076,6 +1104,7 @@
>           (ins addrmode6:$Rn, am6offset:$Rm, DPR:$Vd), IIC_VST1u,
>           "vst1", Dt, "\\{$Vd\\}, $Rn$Rm", "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> class VST1QWB<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b00, 0b1010, op7_4, (outs GPR:$wb),
> @@ -1083,6 +1112,7 @@
>           IIC_VST1x2u, "vst1", Dt, "\\{$Vd, $src2\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def VST1d8_UPD  : VST1DWB<{0,0,0,?}, "8">;
> @@ -1107,6 +1137,7 @@
>           IIC_VST1x3, "vst1", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> class VST1D3WB<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b00, 0b0110, op7_4, (outs GPR:$wb),
> @@ -1115,6 +1146,7 @@
>           IIC_VST1x3u, "vst1", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def VST1d8T      : VST1D3<{0,0,0,?}, "8">;
> @@ -1138,6 +1170,7 @@
>           []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> class VST1D4WB<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b00, 0b0010, op7_4, (outs GPR:$wb),
> @@ -1146,6 +1179,7 @@
>           "vst1", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def VST1d8Q      : VST1D4<{0,0,?,?}, "8">;
> @@ -1168,6 +1202,7 @@
>           IIC_VST2, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> class VST2Q<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b00, 0b0011, op7_4, (outs),
> @@ -1176,6 +1211,7 @@
>           "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def  VST2d8   : VST2D<0b1000, {0,0,?,?}, "8">;
> @@ -1201,6 +1237,7 @@
>           IIC_VST2u, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> class VST2QWB<bits<4> op7_4, string Dt>
>   : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),
> @@ -1209,6 +1246,7 @@
>           "vst2", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def VST2d8_UPD  : VST2DWB<0b1000, {0,0,?,?}, "8">;
> @@ -1242,6 +1280,7 @@
>           "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> {
>   let Rm = 0b1111;
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def  VST3d8   : VST3D<0b0100, {0,0,0,?}, "8">;
> @@ -1260,6 +1299,7 @@
>           "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{4} = Rn{4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def VST3d8_UPD  : VST3DWB<0b0100, {0,0,0,?}, "8">;
> @@ -1299,6 +1339,7 @@
>           "", []> {
>   let Rm = 0b1111;
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def  VST4d8   : VST4D<0b0000, {0,0,?,?}, "8">;
> @@ -1317,6 +1358,7 @@
>            "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",
>           "$Rn.addr = $wb", []> {
>   let Inst{5-4} = Rn{5-4};
> +  let DecoderMethod = "DecodeVSTInstruction";
> }
> 
> def VST4d8_UPD  : VST4DWB<0b0000, {0,0,?,?}, "8">;
> @@ -4040,6 +4082,7 @@
>   : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt,
>            ResTy, OpTy, OpNode> {
>   let Inst{21-16} = op21_16;
> +  let DecoderMethod = "DecodeVSHLMaxInstruction";
> }
> def  VSHLLi8  : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8",
>                           v8i16, v8i8, NEONvshlli>;
> @@ -4754,6 +4797,7 @@
> // Vector Table Lookup and Table Extension.
> 
> //   VTBL     : Vector Table Lookup
> +let DecoderMethod = "DecodeTBLInstruction" in {
> def  VTBL1
>   : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd),
>         (ins DPR:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1,
> @@ -4816,6 +4860,7 @@
> def  VTBX4Pseudo
>   : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src),
>                 IIC_VTBX4, "$orig = $dst", []>;
> +} // DecoderMethod = "DecodeTBLInstruction"
> 
> //===----------------------------------------------------------------------===//
> // NEON instructions for single-precision FP math
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Aug  9 15:55:18 2011
> @@ -82,14 +82,17 @@
> let OperandType = "OPERAND_PCREL" in {
> def t_brtarget : Operand<OtherVT> {
>   let EncoderMethod = "getThumbBRTargetOpValue";
> +  let DecoderMethod = "DecodeThumbBROperand";
> }
> 
> def t_bcctarget : Operand<i32> {
>   let EncoderMethod = "getThumbBCCTargetOpValue";
> +  let DecoderMethod = "DecodeThumbBCCTargetOperand";
> }
> 
> def t_cbtarget : Operand<i32> {
>   let EncoderMethod = "getThumbCBTargetOpValue";
> +  let DecoderMethod = "DecodeThumbCmpBROperand";
> }
> 
> def t_bltarget : Operand<i32> {
> @@ -119,12 +122,14 @@
>                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S1", []> {
>   let EncoderMethod = "getThumbAddrModeRegRegOpValue";
>   let PrintMethod = "printThumbAddrModeRROperand";
> +  let DecoderMethod = "DecodeThumbAddrModeRR";
>   let ParserMatchClass = t_addrmode_rr_asm_operand;
>   let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
> }
> def t_addrmode_rrs2 : Operand<i32>,
>                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S2", []> {
>   let EncoderMethod = "getThumbAddrModeRegRegOpValue";
> +  let DecoderMethod = "DecodeThumbAddrModeRR";
>   let PrintMethod = "printThumbAddrModeRROperand";
>   let ParserMatchClass = t_addrmode_rr_asm_operand;
>   let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
> @@ -132,6 +137,7 @@
> def t_addrmode_rrs4 : Operand<i32>,
>                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S4", []> {
>   let EncoderMethod = "getThumbAddrModeRegRegOpValue";
> +  let DecoderMethod = "DecodeThumbAddrModeRR";
>   let PrintMethod = "printThumbAddrModeRROperand";
>   let ParserMatchClass = t_addrmode_rr_asm_operand;
>   let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
> @@ -142,6 +148,7 @@
> def t_addrmode_is4 : Operand<i32>,
>                      ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S4", []> {
>   let EncoderMethod = "getAddrModeISOpValue";
> +  let DecoderMethod = "DecodeThumbAddrModeIS";
>   let PrintMethod = "printThumbAddrModeImm5S4Operand";
>   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
> }
> @@ -151,6 +158,7 @@
> def t_addrmode_is2 : Operand<i32>,
>                      ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S2", []> {
>   let EncoderMethod = "getAddrModeISOpValue";
> +  let DecoderMethod = "DecodeThumbAddrModeIS";
>   let PrintMethod = "printThumbAddrModeImm5S2Operand";
>   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
> }
> @@ -160,6 +168,7 @@
> def t_addrmode_is1 : Operand<i32>,
>                      ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S1", []> {
>   let EncoderMethod = "getAddrModeISOpValue";
> +  let DecoderMethod = "DecodeThumbAddrModeIS";
>   let PrintMethod = "printThumbAddrModeImm5S1Operand";
>   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
> }
> @@ -178,6 +187,7 @@
> //
> def t_addrmode_pc : Operand<i32> {
>   let EncoderMethod = "getAddrModePCOpValue";
> +  let DecoderMethod = "DecodeThumbAddrModePC";
> }
> 
> //===----------------------------------------------------------------------===//
> @@ -259,6 +269,7 @@
>   let Inst{4}   = imod;
>   let Inst{3}   = 0;
>   let Inst{2-0} = iflags;
> +  let DecoderMethod = "DecodeThumbCPS";
> }
> 
> // For both thumb1 and thumb2.
> @@ -272,17 +283,6 @@
>   let Inst{2-0} = dst;
> }
> 
> -// PC relative add (ADR).
> -def tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi,
> -                   "add\t$dst, pc, $rhs", []>,
> -               T1Encoding<{1,0,1,0,0,?}> {
> -  // A6.2 & A8.6.10
> -  bits<3> dst;
> -  bits<8> rhs;
> -  let Inst{10-8} = dst;
> -  let Inst{7-0}  = rhs;
> -}
> -
> // ADD <Rd>, sp, #<imm8>
> // This is rematerializable, which is particularly useful for taking the
> // address of locals.
> @@ -295,6 +295,7 @@
>   bits<8> rhs;
>   let Inst{10-8} = dst;
>   let Inst{7-0}  = rhs;
> +  let DecoderMethod = "DecodeThumbAddSpecialReg";
> }
> 
> // ADD sp, sp, #<imm7>
> @@ -304,6 +305,7 @@
>   // A6.2.5 & A8.6.8
>   bits<7> rhs;
>   let Inst{6-0} = rhs;
> +  let DecoderMethod = "DecodeThumbAddSPImm";
> }
> 
> // SUB sp, sp, #<imm7>
> @@ -314,6 +316,7 @@
>   // A6.2.5 & A8.6.214
>   bits<7> rhs;
>   let Inst{6-0} = rhs;
> +  let DecoderMethod = "DecodeThumbAddSPImm";
> }
> 
> // ADD <Rm>, sp
> @@ -325,6 +328,7 @@
>   let Inst{7}   = dst{3};
>   let Inst{6-3} = 0b1101;
>   let Inst{2-0} = dst{2-0};
> +  let DecoderMethod = "DecodeThumbAddSPReg";
> }
> 
> // ADD sp, <Rm>
> @@ -336,6 +340,7 @@
>   let Inst{7} = 1;
>   let Inst{6-3} = dst;
>   let Inst{2-0} = 0b101;
> +  let DecoderMethod = "DecodeThumbAddSPReg";
> }
> 
> //===----------------------------------------------------------------------===//
> @@ -1189,6 +1194,7 @@
>   bits<8> addr;
>   let Inst{10-8} = Rd;
>   let Inst{7-0} = addr;
> +  let DecoderMethod = "DecodeThumbAddSpecialReg";
> }
> 
> let neverHasSideEffects = 1, isReMaterializable = 1 in
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Tue Aug  9 15:55:18 2011
> @@ -50,6 +50,7 @@
>   }]> {
>   let ParserMatchClass = t2_so_imm_asmoperand;
>   let EncoderMethod = "getT2SOImmOpValue";
> +  let DecoderMethod = "DecodeT2SOImm";
> }
> 
> // t2_so_imm_not - Match an immediate that is a complement
> @@ -100,6 +101,7 @@
>                        ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
>   let PrintMethod = "printAddrModeImm12Operand";
>   let EncoderMethod = "getAddrModeImm12OpValue";
> +  let DecoderMethod = "DecodeT2AddrModeImm12";
>   let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
> }
> 
> @@ -121,6 +123,7 @@
>                       ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
>   let PrintMethod = "printT2AddrModeImm8Operand";
>   let EncoderMethod = "getT2AddrModeImm8OpValue";
> +  let DecoderMethod = "DecodeT2AddrModeImm8";
>   let ParserMatchClass = MemImm8OffsetAsmOperand;
>   let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
> }
> @@ -130,12 +133,14 @@
>                                       [], [SDNPWantRoot]> {
>   let PrintMethod = "printT2AddrModeImm8OffsetOperand";
>   let EncoderMethod = "getT2AddrModeImm8OffsetOpValue";
> +  let DecoderMethod = "DecodeT2Imm8";
> }
> 
> // t2addrmode_imm8s4  := reg +/- (imm8 << 2)
> def t2addrmode_imm8s4 : Operand<i32> {
>   let PrintMethod = "printT2AddrModeImm8s4Operand";
>   let EncoderMethod = "getT2AddrModeImm8s4OpValue";
> +  let DecoderMethod = "DecodeT2AddrModeImm8s4";
>   let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
> }
> 
> @@ -149,6 +154,7 @@
>                         ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
>   let PrintMethod = "printT2AddrModeSoRegOperand";
>   let EncoderMethod = "getT2AddrModeSORegOpValue";
> +  let DecoderMethod = "DecodeT2AddrModeSOReg";
>   let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
> }
> 
> @@ -158,6 +164,7 @@
> //
> def t2addrmode_reg : Operand<i32> {
>   let PrintMethod = "printAddrMode7Operand";
> +  let DecoderMethod = "DecodeGPRRegisterClass";
>   let MIOperandInfo = (ops GPR);
> }
> 
> @@ -892,6 +899,8 @@
>     let Inst{19-16} = addr{9-6}; // Rn
>     let Inst{3-0}   = addr{5-2}; // Rm
>     let Inst{5-4}   = addr{1-0}; // imm
> +
> +    let DecoderMethod = "DecodeT2LoadShift";
>   }
> 
>   // FIXME: Is the pci variant actually needed?
> @@ -1430,6 +1439,8 @@
>     let Inst{19-16} = addr{9-6}; // Rn
>     let Inst{3-0}   = addr{5-2}; // Rm
>     let Inst{5-4}   = addr{1-0}; // imm2
> +
> +    let DecoderMethod = "DecodeT2LoadShift";
>   }
> }
> 
> @@ -2994,6 +3005,8 @@
>   let Inst{13} = target{18};
>   let Inst{21-16} = target{17-12};
>   let Inst{10-0} = target{11-1};
> +
> +  let DecoderMethod = "DecodeThumb2BCCInstruction";
> }
> 
> // Tail calls. The Darwin version of thumb tail calls uses a t2 branch, so
> 
> Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Tue Aug  9 15:55:18 2011
> @@ -6,584 +6,2328 @@
> // License. See LICENSE.TXT for details.
> //
> //===----------------------------------------------------------------------===//
> -//
> -// This file is part of the ARM Disassembler.
> -// It contains code to implement the public interfaces of ARMDisassembler and
> -// ThumbDisassembler, both of which are instances of MCDisassembler.
> -//
> -//===----------------------------------------------------------------------===//
> 
> #define DEBUG_TYPE "arm-disassembler"
> 
> #include "ARMDisassembler.h"
> -#include "ARMDisassemblerCore.h"
> -
> -#include "llvm/ADT/OwningPtr.h"
> +#include "ARM.h"
> +#include "ARMRegisterInfo.h"
> +#include "MCTargetDesc/ARMAddressingModes.h"
> +#include "MCTargetDesc/ARMBaseInfo.h"
> #include "llvm/MC/EDInstInfo.h"
> #include "llvm/MC/MCInst.h"
> +#include "llvm/MC/MCExpr.h"
> +#include "llvm/MC/MCContext.h"
> #include "llvm/Target/TargetRegistry.h"
> #include "llvm/Support/Debug.h"
> #include "llvm/Support/MemoryObject.h"
> #include "llvm/Support/ErrorHandling.h"
> #include "llvm/Support/raw_ostream.h"
> 
> -//#define DEBUG(X) do { X; } while (0)
> -
> -/// ARMGenDecoderTables.inc - ARMDecoderTables.inc is tblgen'ed from
> -/// ARMDecoderEmitter.cpp TableGen backend.  It contains:
> -///
> -/// o Mappings from opcode to ARM/Thumb instruction format
> -///
> -/// o static uint16_t decodeInstruction(uint32_t insn) - the decoding function
> -/// for an ARM instruction.
> -///
> -/// o static uint16_t decodeThumbInstruction(field_t insn) - the decoding
> -/// function for a Thumb instruction.
> -///
> -#include "ARMGenDecoderTables.inc"
> +// Forward declare these because the autogenerated code will reference them.
> +// Definitions are further down.
> +static bool DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +static bool DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder);
> +
> +static bool DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeDPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +
> +static bool DecodeBitfieldMaskOperand(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrMode2IdxInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeSORegMemOperand(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrMode3Instruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +
> +static bool DecodeMemMultipleWritebackInstruction(llvm::MCInst & Inst,
> +                                                  unsigned Insn,
> +                                                  uint64_t Adddress,
> +                                                  const void *Decoder);
> +static bool DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVCVTImmOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVLD1DupInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVLD3DupInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVLD4DupInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeNEONModImmInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVSHLMaxInstruction(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeShiftRight8Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeShiftRight16Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeShiftRight32Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeShiftRight64Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeTBLInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeVFPfpImm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodePostIdxReg(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeCoprocessor(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeAddrMode3Offset(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder);
> +
> +
> +static bool DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbAddrModeRR(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbAddrModeIS(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbAddrModePC(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbAddrModeSP(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2AddrModeSOReg(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2LoadShift(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2Imm8S4(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2AddrModeImm8s4(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2Imm8(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeT2AddrModeImm8(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbAddSPImm(llvm::MCInst &Inst, uint16_t Val,
> +                               uint64_t Address, const void *Decoder);
> +static bool DecodeThumbAddSPReg(llvm::MCInst &Inst, uint16_t Insn,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeThumbCPS(llvm::MCInst &Inst, uint16_t Insn,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Insn,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeThumbSRImm(llvm::MCInst &Inst, unsigned Val,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Val,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val,
> +                                uint64_t Address, const void *Decoder);
> +static bool DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
> +                                uint64_t Address, const void *Decoder);
> 
> +#include "ARMGenDisassemblerTables.inc"
> +#include "ARMGenInstrInfo.inc"
> #include "ARMGenEDInfo.inc"
> 
> using namespace llvm;
> 
> -/// showBitVector - Use the raw_ostream to log a diagnostic message describing
> -/// the inidividual bits of the instruction.
> -///
> -static inline void showBitVector(raw_ostream &os, const uint32_t &insn) {
> -  // Split the bit position markers into more than one lines to fit 80 columns.
> -  os << " 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11"
> -     << " 10  9  8  7  6  5  4  3  2  1  0 \n";
> -  os << "---------------------------------------------------------------"
> -     << "----------------------------------\n";
> -  os << '|';
> -  for (unsigned i = 32; i != 0; --i) {
> -    if (insn >> (i - 1) & 0x01)
> -      os << " 1";
> -    else
> -      os << " 0";
> -    os << (i%4 == 1 ? '|' : ':');
> +static MCDisassembler *createARMDisassembler(const Target &T) {
> +  return new ARMDisassembler;
> +}
> +
> +static MCDisassembler *createThumbDisassembler(const Target &T) {
> +  return new ThumbDisassembler;
> +}
> +
> +EDInstInfo *ARMDisassembler::getEDInfo() const {
> +  return instInfoARM;
> +}
> +
> +EDInstInfo *ThumbDisassembler::getEDInfo() const {
> +  return instInfoARM;
> +}
> +
> +
> +bool ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
> +                                     const MemoryObject &Region,
> +                                     uint64_t Address,raw_ostream &os) const {
> +  uint8_t bytes[4];
> +
> +  // We want to read exactly 4 bytes of data.
> +  if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1)
> +    return false;
> +
> +  // Encoded as a small-endian 32-bit word in the stream.
> +  uint32_t insn = (bytes[3] << 24) |
> +                  (bytes[2] << 16) |
> +                  (bytes[1] <<  8) |
> +                  (bytes[0] <<  0);
> +
> +  // Calling the auto-generated decoder function.
> +  bool result = decodeARMInstruction32(MI, insn, Address, this);
> +  if (result) {
> +    Size = 4;
> +    return true;
>   }
> -  os << '\n';
> -  // Split the bit position markers into more than one lines to fit 80 columns.
> -  os << "---------------------------------------------------------------"
> -     << "----------------------------------\n";
> -  os << '\n';
> -}
> -
> -/// decodeARMInstruction is a decorator function which tries special cases of
> -/// instruction matching before calling the auto-generated decoder function.
> -static unsigned decodeARMInstruction(uint32_t &insn) {
> -  if (slice(insn, 31, 28) == 15)
> -    goto AutoGenedDecoder;
> -
> -  // Special case processing, if any, goes here....
> -
> -  // LLVM combines the offset mode of A8.6.197 & A8.6.198 into STRB.
> -  // The insufficient encoding information of the combined instruction confuses
> -  // the decoder wrt BFC/BFI.  Therefore, we try to recover here.
> -  // For BFC, Inst{27-21} = 0b0111110 & Inst{6-0} = 0b0011111.
> -  // For BFI, Inst{27-21} = 0b0111110 & Inst{6-4} = 0b001 & Inst{3-0} =! 0b1111.
> -  if (slice(insn, 27, 21) == 0x3e && slice(insn, 6, 4) == 1) {
> -    if (slice(insn, 3, 0) == 15)
> -      return ARM::BFC;
> -    else
> -      return ARM::BFI;
> +
> +  // Instructions that are shared between ARM and Thumb modes.
> +  // FIXME: This shouldn't really exist.  It's an artifact of the
> +  // fact that we fail to encode a few instructions properly for Thumb.
> +  MI.clear();
> +  result = decodeCommonInstruction32(MI, insn, Address, this);
> +  if (result) {
> +    Size = 4;
> +    return true;
>   }
> 
> -  // Ditto for STRBT, which is a super-instruction for A8.6.199 Encodings
> -  // A1 & A2.
> -  // As a result, the decoder fails to deocode USAT properly.
> -  if (slice(insn, 27, 21) == 0x37 && slice(insn, 5, 4) == 1)
> -    return ARM::USAT;
> -  // As a result, the decoder fails to deocode UQADD16 properly.
> -  if (slice(insn, 27, 20) == 0x66 && slice(insn, 7, 4) == 1)
> -    return ARM::UQADD16;
> -
> -  // Ditto for ADDSrs, which is a super-instruction for A8.6.7 & A8.6.8.
> -  // As a result, the decoder fails to decode UMULL properly.
> -  if (slice(insn, 27, 21) == 0x04 && slice(insn, 7, 4) == 9) {
> -    return ARM::UMULL;
> -  }
> -
> -  // Ditto for STR_PRE, which is a super-instruction for A8.6.194 & A8.6.195.
> -  // As a result, the decoder fails to decode SBFX properly.
> -  if (slice(insn, 27, 21) == 0x3d && slice(insn, 6, 4) == 5)
> -    return ARM::SBFX;
> -
> -  // And STRB_PRE, which is a super-instruction for A8.6.197 & A8.6.198.
> -  // As a result, the decoder fails to decode UBFX properly.
> -  if (slice(insn, 27, 21) == 0x3f && slice(insn, 6, 4) == 5)
> -    return ARM::UBFX;
> -
> -  // Ditto for STRT, which is a super-instruction for A8.6.210 Encoding A1 & A2.
> -  // As a result, the decoder fails to deocode SSAT properly.
> -  if (slice(insn, 27, 21) == 0x35 && slice(insn, 5, 4) == 1)
> -    return ARM::SSAT;
> -
> -  // Ditto for RSCrs, which is a super-instruction for A8.6.146 & A8.6.147.
> -  // As a result, the decoder fails to decode STRHT/LDRHT/LDRSHT/LDRSBT.
> -  if (slice(insn, 27, 24) == 0) {
> -    switch (slice(insn, 21, 20)) {
> -    case 2:
> -      switch (slice(insn, 7, 4)) {
> -      case 11:
> -        return slice(insn, 22, 22) ? ARM::STRHTi : ARM::STRHTr;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    case 3:
> -      switch (slice(insn, 7, 4)) {
> -      case 11:
> -        return slice(insn, 22, 22) ? ARM::LDRHTi : ARM::LDRHTr;
> -      case 13:
> -        return slice(insn, 22, 22) ? ARM::LDRSBTi : ARM::LDRSBTr;
> -      case 15:
> -        return slice(insn, 22, 22) ? ARM::LDRSHTi : ARM::LDRSHTr;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    default:
> -      break;   // fallthrough
> -    }
> +  // VFP and NEON instructions, similarly, are shared between ARM
> +  // and Thumb modes.
> +  MI.clear();
> +  result = decodeVFPInstruction32(MI, insn, Address, this);
> +  if (result) {
> +    Size = 4;
> +    return true;
>   }
> 
> -  // Ditto for SBCrs, which is a super-instruction for A8.6.152 & A8.6.153.
> -  // As a result, the decoder fails to decode STRH_Post/LDRD_POST/STRD_POST
> -  // properly.
> -  if (slice(insn, 27, 25) == 0 && slice(insn, 20, 20) == 0) {
> -    unsigned PW = slice(insn, 24, 24) << 1 | slice(insn, 21, 21);
> -    switch (slice(insn, 7, 4)) {
> -    case 11:
> -      switch (PW) {
> -      case 2: // Offset
> -        return ARM::STRH;
> -      case 3: // Pre-indexed
> -        return ARM::STRH_PRE;
> -      case 0: // Post-indexed
> -        return ARM::STRH_POST;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    case 13:
> -      switch (PW) {
> -      case 2: // Offset
> -        return ARM::LDRD;
> -      case 3: // Pre-indexed
> -        return ARM::LDRD_PRE;
> -      case 0: // Post-indexed
> -        return ARM::LDRD_POST;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    case 15:
> -      switch (PW) {
> -      case 2: // Offset
> -        return ARM::STRD;
> -      case 3: // Pre-indexed
> -        return ARM::STRD_PRE;
> -      case 0: // Post-indexed
> -        return ARM::STRD_POST;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    default:
> -      break; // fallthrough
> -    }
> +  MI.clear();
> +  result = decodeNEONInstruction32(MI, insn, Address, this);
> +  if (result) {
> +    // Add a fake predicate operand, because we share these instruction
> +    // definitions with Thumb2 where these instructions are predicable.
> +    if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false;
> +    Size = 4;
> +    return true;
>   }
> 
> -  // Ditto for SBCSSrs, which is a super-instruction for A8.6.152 & A8.6.153.
> -  // As a result, the decoder fails to decode LDRH_POST/LDRSB_POST/LDRSH_POST
> -  // properly.
> -  if (slice(insn, 27, 25) == 0 && slice(insn, 20, 20) == 1) {
> -    unsigned PW = slice(insn, 24, 24) << 1 | slice(insn, 21, 21);
> -    switch (slice(insn, 7, 4)) {
> -    case 11:
> -      switch (PW) {
> -      case 2: // Offset
> -        return ARM::LDRH;
> -      case 3: // Pre-indexed
> -        return ARM::LDRH_PRE;
> -      case 0: // Post-indexed
> -        return ARM::LDRH_POST;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    case 13:
> -      switch (PW) {
> -      case 2: // Offset
> -        return ARM::LDRSB;
> -      case 3: // Pre-indexed
> -        return ARM::LDRSB_PRE;
> -      case 0: // Post-indexed
> -        return ARM::LDRSB_POST;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    case 15:
> -      switch (PW) {
> -      case 2: // Offset
> -        return ARM::LDRSH;
> -      case 3: // Pre-indexed
> -        return ARM::LDRSH_PRE;
> -      case 0: // Post-indexed
> -        return ARM::LDRSH_POST;
> -      default:
> -        break; // fallthrough
> -      }
> -      break;
> -    default:
> -      break; // fallthrough
> +  MI.clear();
> +
> +  return false;
> +}
> +
> +namespace llvm {
> +extern MCInstrDesc ARMInsts[];
> +}
> +
> +// 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) {
> +  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
> +  MCInst::iterator I = MI.begin();
> +  for (unsigned i = 0; i < MI.size(); ++i, ++I) {
> +    if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
> +      MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
> +      return;
>     }
>   }
> 
> -AutoGenedDecoder:
> -  // Calling the auto-generated decoder function.
> -  return decodeInstruction(insn);
> +  if (OpInfo[MI.size()].isOptionalDef() &&
> +      OpInfo[MI.size()].RegClass == ARM::CCRRegClassID)
> +    MI.insert(MI.end(), MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
> }
> 
> -// Helper function for special case handling of LDR (literal) and friends.
> -// See, for example, A6.3.7 Load word: Table A6-18 Load word.
> -// See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode
> -// before returning it.
> -static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return Opcode; // Return unmorphed opcode.
> -
> -  case ARM::t2LDR_POST:   case ARM::t2LDR_PRE:
> -  case ARM::t2LDRi12:     case ARM::t2LDRi8:
> -  case ARM::t2LDRs:       case ARM::t2LDRT:
> -    return ARM::t2LDRpci;
> -
> -  case ARM::t2LDRB_POST:  case ARM::t2LDRB_PRE:
> -  case ARM::t2LDRBi12:    case ARM::t2LDRBi8:
> -  case ARM::t2LDRBs:      case ARM::t2LDRBT:
> -    return ARM::t2LDRBpci;
> -
> -  case ARM::t2LDRH_POST:  case ARM::t2LDRH_PRE:
> -  case ARM::t2LDRHi12:    case ARM::t2LDRHi8:
> -  case ARM::t2LDRHs:      case ARM::t2LDRHT:
> -    return ARM::t2LDRHpci;
> -
> -  case ARM::t2LDRSB_POST:  case ARM::t2LDRSB_PRE:
> -  case ARM::t2LDRSBi12:    case ARM::t2LDRSBi8:
> -  case ARM::t2LDRSBs:      case ARM::t2LDRSBT:
> -    return ARM::t2LDRSBpci;
> -
> -  case ARM::t2LDRSH_POST:  case ARM::t2LDRSH_PRE:
> -  case ARM::t2LDRSHi12:    case ARM::t2LDRSHi8:
> -  case ARM::t2LDRSHs:      case ARM::t2LDRSHT:
> -    return ARM::t2LDRSHpci;
> -  }
> -}
> -
> -// Helper function for special case handling of PLD (literal) and friends.
> -// See A8.6.117 T1 & T2 and friends for why we morphed the opcode
> -// before returning it.
> -static unsigned T2Morph2PLDLiteral(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return Opcode; // Return unmorphed opcode.
> -
> -  case ARM::t2PLDi8:   case ARM::t2PLDs:
> -  case ARM::t2PLDWi12: case ARM::t2PLDWi8:
> -  case ARM::t2PLDWs:
> -    return ARM::t2PLDi12;
> -
> -  case ARM::t2PLIi8:   case ARM::t2PLIs:
> -    return ARM::t2PLIi12;
> -  }
> -}
> -
> -/// decodeThumbSideEffect is a decorator function which can potentially twiddle
> -/// the instruction or morph the returned opcode under Thumb2.
> -///
> -/// First it checks whether the insn is a NEON or VFP instr; if true, bit
> -/// twiddling could be performed on insn to turn it into an ARM NEON/VFP
> -/// equivalent instruction and decodeInstruction is called with the transformed
> -/// insn.
> -///
> -/// Next, there is special handling for Load byte/halfword/word instruction by
> -/// checking whether Rn=0b1111 and call T2Morph2LoadLiteral() on the decoded
> -/// Thumb2 instruction.  See comments below for further details.
> -///
> -/// Finally, one last check is made to see whether the insn is a NEON/VFP and
> -/// decodeInstruction(insn) is invoked on the original insn.
> -///
> -/// Otherwise, decodeThumbInstruction is called with the original insn.
> -static unsigned decodeThumbSideEffect(bool IsThumb2, unsigned &insn) {
> -  if (IsThumb2) {
> -    uint16_t op1 = slice(insn, 28, 27);
> -    uint16_t op2 = slice(insn, 26, 20);
> -
> -    // A6.3 32-bit Thumb instruction encoding
> -    // Table A6-9 32-bit Thumb instruction encoding
> -
> -    // The coprocessor instructions of interest are transformed to their ARM
> -    // equivalents.
> -
> -    // --------- Transform Begin Marker ---------
> -    if ((op1 == 1 || op1 == 3) && slice(op2, 6, 4) == 7) {
> -      // A7.4 Advanced SIMD data-processing instructions
> -      // U bit of Thumb corresponds to Inst{24} of ARM.
> -      uint16_t U = slice(op1, 1, 1);
> -
> -      // Inst{28-24} of ARM = {1,0,0,1,U};
> -      uint16_t bits28_24 = 9 << 1 | U;
> -      DEBUG(showBitVector(errs(), insn));
> -      setSlice(insn, 28, 24, bits28_24);
> -      return decodeInstruction(insn);
> -    }
> -
> -    if (op1 == 3 && slice(op2, 6, 4) == 1 && slice(op2, 0, 0) == 0) {
> -      // A7.7 Advanced SIMD element or structure load/store instructions
> -      // Inst{27-24} of Thumb = 0b1001
> -      // Inst{27-24} of ARM   = 0b0100
> -      DEBUG(showBitVector(errs(), insn));
> -      setSlice(insn, 27, 24, 4);
> -      return decodeInstruction(insn);
> -    }
> -    // --------- Transform End Marker ---------
> -
> -    unsigned unmorphed = decodeThumbInstruction(insn);
> -
> -    // See, for example, A6.3.7 Load word: Table A6-18 Load word.
> -    // See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode
> -    // before returning it to our caller.
> -    if (op1 == 3 && slice(op2, 6, 5) == 0 && slice(op2, 0, 0) == 1
> -        && slice(insn, 19, 16) == 15) {
> -      unsigned morphed = T2Morph2LoadLiteral(unmorphed);
> -      if (morphed != unmorphed)
> -        return morphed;
> -    }
> -
> -    // See, for example, A8.6.117 PLD,PLDW (immediate) T1 & T2, and friends for
> -    // why we morphed the opcode before returning it to our caller.
> -    if (slice(insn, 31, 25) == 0x7C && slice(insn, 15, 12) == 0xF
> -        && slice(insn, 22, 22) == 0 && slice(insn, 20, 20) == 1
> -        && slice(insn, 19, 16) == 15) {
> -      unsigned morphed = T2Morph2PLDLiteral(unmorphed);
> -      if (morphed != unmorphed)
> -        return morphed;
> -    }
> -
> -    // One last check for NEON/VFP instructions.
> -    if ((op1 == 1 || op1 == 3) && slice(op2, 6, 6) == 1)
> -      return decodeInstruction(insn);
> +// 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.
> +void ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
> +  // A few instructions actually have predicates encoded in them.  Don't
> +  // try to overwrite it if we're seeing one of those.
> +  switch (MI.getOpcode()) {
> +    case ARM::tBcc:
> +    case ARM::t2Bcc:
> +      return;
> +    default:
> +      break;
> +  }
> 
> -    // Fall through.
> +  // If we're in an IT block, base the predicate on that.  Otherwise,
> +  // assume a predicate of AL.
> +  unsigned CC;
> +  if (ITBlock.size()) {
> +    CC = ITBlock.back();
> +    ITBlock.pop_back();
> +  } else
> +    CC = ARMCC::AL;
> +
> +  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
> +  MCInst::iterator I = MI.begin();
> +  for (unsigned i = 0; i < MI.size(); ++i, ++I) {
> +    if (OpInfo[i].isPredicate()) {
> +      I = MI.insert(I, MCOperand::CreateImm(CC));
> +      ++I;
> +      if (CC == ARMCC::AL)
> +        MI.insert(I, MCOperand::CreateReg(0));
> +      else
> +        MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
> +      return;
> +    }
>   }
> 
> -  return decodeThumbInstruction(insn);
> +  MI.insert(MI.end(), MCOperand::CreateImm(CC));
> +  if (CC == ARMCC::AL)
> +    MI.insert(MI.end(), MCOperand::CreateReg(0));
> +  else
> +    MI.insert(MI.end(), MCOperand::CreateReg(ARM::CPSR));
> }
> 
> -//
> -// Public interface for the disassembler
> -//
> +// 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.
> +void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
> +  unsigned CC;
> +  if (ITBlock.size()) {
> +    CC = ITBlock.back();
> +    ITBlock.pop_back();
> +  } else
> +    CC = ARMCC::AL;
> +
> +  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
> +  MCInst::iterator I = MI.begin();
> +  for (unsigned i = 0; i < MI.size(); ++i, ++I) {
> +    if (OpInfo[i].isPredicate() ) {
> +      I->setImm(CC);
> +      ++I;
> +      if (CC == ARMCC::AL)
> +        I->setReg(0);
> +      else
> +        I->setReg(ARM::CPSR);
> +      return;
> +    }
> +  }
> +}
> 
> -bool ARMDisassembler::getInstruction(MCInst &MI,
> -                                     uint64_t &Size,
> -                                     const MemoryObject &Region,
> -                                     uint64_t Address,
> -                                     raw_ostream &os) const {
> -  // The machine instruction.
> -  uint32_t insn;
> +
> +bool ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
> +                                       const MemoryObject &Region,
> +                                       uint64_t Address,raw_ostream &os) const {
>   uint8_t bytes[4];
> 
> +  // We want to read exactly 2 bytes of data.
> +  if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1)
> +    return false;
> +
> +  uint16_t insn16 = (bytes[1] << 8) | bytes[0];
> +  bool result = decodeThumbInstruction16(MI, insn16, Address, this);
> +  if (result) {
> +    Size = 2;
> +    bool InITBlock = ITBlock.size();
> +    AddThumbPredicate(MI);
> +    AddThumb1SBit(MI, InITBlock);
> +    return true;
> +  }
> +
> +  MI.clear();
> +  result = decodeThumb2Instruction16(MI, insn16, Address, this);
> +  if (result) {
> +    Size = 2;
> +    AddThumbPredicate(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 (MI.getOpcode() == ARM::t2IT) {
> +      unsigned firstcond = MI.getOperand(0).getImm();
> +      uint32_t mask = MI.getOperand(1).getImm();
> +      unsigned zeros = CountTrailingZeros_32(mask);
> +      mask >>= zeros+1;
> +
> +      for (unsigned i = 0; i < 4 - (zeros+1); ++i) {
> +        if (firstcond ^ (mask & 1))
> +          ITBlock.push_back(firstcond ^ 1);
> +        else
> +          ITBlock.push_back(firstcond);
> +        mask >>= 1;
> +      }
> +      ITBlock.push_back(firstcond);
> +    }
> +
> +    return true;
> +  }
> +
>   // We want to read exactly 4 bytes of data.
>   if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1)
>     return false;
> 
> -  // Encoded as a small-endian 32-bit word in the stream.
> -  insn = (bytes[3] << 24) |
> -         (bytes[2] << 16) |
> -         (bytes[1] <<  8) |
> -         (bytes[0] <<  0);
> +  uint32_t insn32 = (bytes[3] <<  8) |
> +                    (bytes[2] <<  0) |
> +                    (bytes[1] << 24) |
> +                    (bytes[0] << 16);
> +  MI.clear();
> +  result = decodeThumbInstruction32(MI, insn32, Address, this);
> +  if (result) {
> +    Size = 4;
> +    bool InITBlock = ITBlock.size();
> +    AddThumbPredicate(MI);
> +    AddThumb1SBit(MI, InITBlock);
> +    return true;
> +  }
> +
> +  MI.clear();
> +  result = decodeThumb2Instruction32(MI, insn32, Address, this);
> +  if (result) {
> +    Size = 4;
> +    AddThumbPredicate(MI);
> +    return true;
> +  }
> +
> +  MI.clear();
> +  result = decodeVFPInstruction32(MI, insn32, Address, this);
> +  if (result) {
> +    Size = 4;
> +    UpdateThumbVFPPredicate(MI);
> +    return true;
> +  }
> +
> +  MI.clear();
> +  result = decodeCommonInstruction32(MI, insn32, Address, this);
> +  if (result) {
> +    Size = 4;
> +    AddThumbPredicate(MI);
> +    return true;
> +  }
> +
> +  return false;
> +}
> 
> -  unsigned Opcode = decodeARMInstruction(insn);
> -  ARMFormat Format = ARMFormats[Opcode];
> -  Size = 4;
> 
> -  DEBUG({
> -      errs() << "\nOpcode=" << Opcode << " Name=" <<ARMUtils::OpcodeName(Opcode)
> -             << " Format=" << stringForARMFormat(Format) << '(' << (int)Format
> -             << ")\n";
> -      showBitVector(errs(), insn);
> -    });
> +extern "C" void LLVMInitializeARMDisassembler() {
> +  TargetRegistry::RegisterMCDisassembler(TheARMTarget,
> +                                         createARMDisassembler);
> +  TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
> +                                         createThumbDisassembler);
> +}
> 
> -  OwningPtr<ARMBasicMCBuilder> Builder(CreateMCBuilder(Opcode, Format));
> -  if (!Builder)
> +static const unsigned 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 bool DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 15)
>     return false;
> 
> -  Builder->setupBuilderForSymbolicDisassembly(getLLVMOpInfoCallback(),
> -                                              getDisInfoBlock(), getMCContext(),
> -                                              Address);
> +  unsigned Register = GPRDecoderTable[RegNo];
> +  Inst.addOperand(MCOperand::CreateReg(Register));
> +  return true;
> +}
> 
> -  if (!Builder->Build(MI, insn))
> +static bool DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 7)
>     return false;
> +  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
> +}
> +
> +static bool DecodetcGPRRegisterClass(llvm::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 false;
> +    }
> 
> +  Inst.addOperand(MCOperand::CreateReg(Register));
>   return true;
> }
> 
> -bool ThumbDisassembler::getInstruction(MCInst &MI,
> -                                       uint64_t &Size,
> -                                       const MemoryObject &Region,
> -                                       uint64_t Address,
> -                                       raw_ostream &os) const {
> -  // The Thumb instruction stream is a sequence of halfwords.
> -
> -  // This represents the first halfword as well as the machine instruction
> -  // passed to decodeThumbInstruction().  For 16-bit Thumb instruction, the top
> -  // halfword of insn is 0x00 0x00; otherwise, the first halfword is moved to
> -  // the top half followed by the second halfword.
> -  unsigned insn = 0;
> -  // Possible second halfword.
> -  uint16_t insn1 = 0;
> -
> -  // A6.1 Thumb instruction set encoding
> -  //
> -  // If bits [15:11] of the halfword being decoded take any of the following
> -  // values, the halfword is the first halfword of a 32-bit instruction:
> -  // o 0b11101
> -  // o 0b11110
> -  // o 0b11111.
> -  //
> -  // Otherwise, the halfword is a 16-bit instruction.
> +static bool DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo == 13 || RegNo == 15) return false;
> +  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
> +}
> 
> -  // Read 2 bytes of data first.
> -  uint8_t bytes[2];
> -  if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1)
> +static const unsigned 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 bool DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 31)
>     return false;
> 
> -  // Encoded as a small-endian 16-bit halfword in the stream.
> -  insn = (bytes[1] << 8) | bytes[0];
> -  unsigned bits15_11 = slice(insn, 15, 11);
> -  bool IsThumb2 = false;
> -
> -  // 32-bit instructions if the bits [15:11] of the halfword matches
> -  // { 0b11101 /* 0x1D */, 0b11110 /* 0x1E */, ob11111 /* 0x1F */ }.
> -  if (bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F) {
> -    IsThumb2 = true;
> -    if (Region.readBytes(Address + 2, 2, (uint8_t*)bytes, NULL) == -1)
> -      return false;
> -    // Encoded as a small-endian 16-bit halfword in the stream.
> -    insn1 = (bytes[1] << 8) | bytes[0];
> -    insn = (insn << 16 | insn1);
> -  }
> +  unsigned Register = SPRDecoderTable[RegNo];
> +  Inst.addOperand(MCOperand::CreateReg(Register));
> +  return true;
> +}
> 
> -  // The insn could potentially be bit-twiddled in order to be decoded as an ARM
> -  // NEON/VFP opcode.  In such case, the modified insn is later disassembled as
> -  // an ARM NEON/VFP instruction.
> -  //
> -  // This is a short term solution for lack of encoding bits specified for the
> -  // Thumb2 NEON/VFP instructions.  The long term solution could be adding some
> -  // infrastructure to have each instruction support more than one encodings.
> -  // Which encoding is used would be based on which subtarget the compiler/
> -  // disassembler is working with at the time.  This would allow the sharing of
> -  // the NEON patterns between ARM and Thumb2, as well as potential greater
> -  // sharing between the regular ARM instructions and the 32-bit wide Thumb2
> -  // instructions as well.
> -  unsigned Opcode = decodeThumbSideEffect(IsThumb2, insn);
> +static const unsigned 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 bool DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 31)
> +    return false;
> 
> -  ARMFormat Format = ARMFormats[Opcode];
> -  Size = IsThumb2 ? 4 : 2;
> +  unsigned Register = DPRDecoderTable[RegNo];
> +  Inst.addOperand(MCOperand::CreateReg(Register));
> +  return true;
> +}
> 
> -  DEBUG({
> -      errs() << "Opcode=" << Opcode << " Name=" << ARMUtils::OpcodeName(Opcode)
> -             << " Format=" << stringForARMFormat(Format) << '(' << (int)Format
> -             << ")\n";
> -      showBitVector(errs(), insn);
> -    });
> +static bool DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 7)
> +    return false;
> +  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
> +}
> 
> -  OwningPtr<ARMBasicMCBuilder> Builder(CreateMCBuilder(Opcode, Format));
> -  if (!Builder)
> +static bool DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 15)
>     return false;
> +  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
> +}
> 
> -  Builder->SetSession(const_cast<Session *>(&SO));
> +static const unsigned 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
> +};
> 
> -  Builder->setupBuilderForSymbolicDisassembly(getLLVMOpInfoCallback(),
> -                                              getDisInfoBlock(), getMCContext(),
> -                                              Address);
> 
> -  if (!Builder->Build(MI, insn))
> +static bool DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (RegNo > 31)
>     return false;
> +  RegNo >>= 1;
> 
> +  unsigned Register = QPRDecoderTable[RegNo];
> +  Inst.addOperand(MCOperand::CreateReg(Register));
>   return true;
> }
> 
> -// A8.6.50
> -// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
> -static unsigned short CountITSize(unsigned ITMask) {
> -  // First count the trailing zeros of the IT mask.
> -  unsigned TZ = CountTrailingZeros_32(ITMask);
> -  if (TZ > 3) {
> -    DEBUG(errs() << "Encoding error: IT Mask '0000'");
> -    return 0;
> -  }
> -  return (4 - TZ);
> +static bool DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  if (Val == 0xF) return false;
> +  Inst.addOperand(MCOperand::CreateImm(Val));
> +  if (Val == ARMCC::AL) {
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  } else
> +    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
> +  return true;
> }
> 
> -/// Init ITState.  Note that at least one bit is always 1 in mask.
> -bool Session::InitIT(unsigned short bits7_0) {
> -  ITCounter = CountITSize(slice(bits7_0, 3, 0));
> -  if (ITCounter == 0)
> -    return false;
> +static bool DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  if (Val)
> +    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
> +  else
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  return true;
> +}
> 
> -  // A8.6.50 IT
> -  unsigned short FirstCond = slice(bits7_0, 7, 4);
> -  if (FirstCond == 0xF) {
> -    DEBUG(errs() << "Encoding error: IT FirstCond '1111'");
> -    return false;
> +static bool DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  uint32_t imm = Val & 0xFF;
> +  uint32_t rot = (Val & 0xF00) >> 7;
> +  uint32_t rot_imm = (imm >> rot) | (imm << (32-rot));
> +  Inst.addOperand(MCOperand::CreateImm(rot_imm));
> +  return true;
> +}
> +
> +static bool DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  Val <<= 2;
> +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(Val)));
> +  return true;
> +}
> +
> +static bool DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +
> +  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
> +  unsigned type = fieldFromInstruction32(Val, 5, 2);
> +  unsigned imm = fieldFromInstruction32(Val, 7, 5);
> +
> +  // Register-immediate
> +  DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  ARM_AM::ShiftOpc 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 (FirstCond == 0xE && ITCounter != 1) {
> -    DEBUG(errs() << "Encoding error: IT FirstCond '1110' && Mask != '1000'");
> -    return false;
> +
> +  if (Shift == ARM_AM::ror && imm == 0)
> +    Shift = ARM_AM::rrx;
> +
> +  unsigned Op = Shift | (imm << 3);
> +  Inst.addOperand(MCOperand::CreateImm(Op));
> +
> +  return true;
> +}
> +
> +static bool DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +
> +  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
> +  unsigned type = fieldFromInstruction32(Val, 5, 2);
> +  unsigned Rs = fieldFromInstruction32(Val, 8, 4);
> +
> +  // Register-register
> +  DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  DecodeGPRRegisterClass(Inst, Rs, Address, Decoder);
> +
> +  ARM_AM::ShiftOpc 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;
>   }
> 
> -  ITState = bits7_0;
> +  Inst.addOperand(MCOperand::CreateImm(Shift));
> 
>   return true;
> }
> 
> -/// Update ITState if necessary.
> -void Session::UpdateIT() {
> -  assert(ITCounter);
> -  --ITCounter;
> -  if (ITCounter == 0)
> -    ITState = 0;
> -  else {
> -    unsigned short NewITState4_0 = slice(ITState, 4, 0) << 1;
> -    setSlice(ITState, 4, 0, NewITState4_0);
> +static bool DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  for (unsigned i = 0; i < 16; ++i) {
> +    if (Val & (1 << i))
> +      DecodeGPRRegisterClass(Inst, i, Address, Decoder);
>   }
> +
> +  return true;
> }
> 
> -static MCDisassembler *createARMDisassembler(const Target &T) {
> -  return new ARMDisassembler;
> +static bool DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned Vd = fieldFromInstruction32(Val, 8, 4);
> +  unsigned regs = Val & 0xFF;
> +
> +  DecodeSPRRegisterClass(Inst, Vd, Address, Decoder);
> +  for (unsigned i = 0; i < (regs - 1); ++i)
> +    DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder);
> +
> +  return true;
> }
> 
> -static MCDisassembler *createThumbDisassembler(const Target &T) {
> -  return new ThumbDisassembler;
> +static bool DecodeDPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned Vd = fieldFromInstruction32(Val, 8, 4);
> +  unsigned regs = (Val & 0xFF) / 2;
> +
> +  DecodeDPRRegisterClass(Inst, Vd, Address, Decoder);
> +  for (unsigned i = 0; i < (regs - 1); ++i)
> +    DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder);
> +
> +  return true;
> }
> 
> -extern "C" void LLVMInitializeARMDisassembler() {
> -  // Register the disassembler.
> -  TargetRegistry::RegisterMCDisassembler(TheARMTarget,
> -                                         createARMDisassembler);
> -  TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
> -                                         createThumbDisassembler);
> +static bool DecodeBitfieldMaskOperand(llvm::MCInst &Inst, unsigned Val,
> +                                      uint64_t Address, const void *Decoder) {
> +  unsigned msb = fieldFromInstruction32(Val, 5, 5);
> +  unsigned lsb = fieldFromInstruction32(Val, 0, 5);
> +  uint32_t msb_mask = (1 << (msb+1)) - 1;
> +  uint32_t lsb_mask = (1 << lsb) - 1;
> +  Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
> +  return true;
> }
> 
> -EDInstInfo *ARMDisassembler::getEDInfo() const {
> -  return instInfoARM;
> +static bool DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
> +  unsigned CRd = fieldFromInstruction32(Insn, 12, 4);
> +  unsigned coproc = fieldFromInstruction32(Insn, 8, 4);
> +  unsigned imm = fieldFromInstruction32(Insn, 0, 8);
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned U = fieldFromInstruction32(Insn, 23, 1);
> +
> +  switch (Inst.getOpcode()) {
> +    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 (coproc == 0xA || coproc == 0xB)
> +        return false;
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  Inst.addOperand(MCOperand::CreateImm(coproc));
> +  Inst.addOperand(MCOperand::CreateImm(CRd));
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  switch (Inst.getOpcode()) {
> +    case ARM::LDC_OPTION:
> +    case ARM::LDCL_OPTION:
> +    case ARM::LDC2_OPTION:
> +    case ARM::LDC2L_OPTION:
> +    case ARM::STC_OPTION:
> +    case ARM::STCL_OPTION:
> +    case ARM::STC2_OPTION:
> +    case ARM::STC2L_OPTION:
> +    case ARM::LDCL_POST:
> +    case ARM::STCL_POST:
> +      break;
> +    default:
> +      Inst.addOperand(MCOperand::CreateReg(0));
> +      break;
> +  }
> +
> +  unsigned P = fieldFromInstruction32(Insn, 24, 1);
> +  unsigned W = fieldFromInstruction32(Insn, 21, 1);
> +
> +  bool writeback = (P == 0) || (W == 1);
> +  unsigned idx_mode = 0;
> +  if (P && writeback)
> +    idx_mode = ARMII::IndexModePre;
> +  else if (!P && writeback)
> +    idx_mode = ARMII::IndexModePost;
> +
> +  switch (Inst.getOpcode()) {
> +    case ARM::LDCL_POST:
> +    case ARM::STCL_POST:
> +      imm |= U << 8;
> +    case ARM::LDC_OPTION:
> +    case ARM::LDCL_OPTION:
> +    case ARM::LDC2_OPTION:
> +    case ARM::LDC2L_OPTION:
> +    case ARM::STC_OPTION:
> +    case ARM::STCL_OPTION:
> +    case ARM::STC2_OPTION:
> +    case ARM::STC2L_OPTION:
> +      Inst.addOperand(MCOperand::CreateImm(imm));
> +      break;
> +    default:
> +      if (U)
> +        Inst.addOperand(MCOperand::CreateImm(
> +            ARM_AM::getAM2Opc(ARM_AM::add, imm, ARM_AM::lsl, idx_mode)));
> +      else
> +        Inst.addOperand(MCOperand::CreateImm(
> +            ARM_AM::getAM2Opc(ARM_AM::sub, imm, ARM_AM::lsl, idx_mode)));
> +      break;
> +  }
> +
> +  switch (Inst.getOpcode()) {
> +    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 (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  return true;
> }
> 
> -EDInstInfo *ThumbDisassembler::getEDInfo() const {
> -  return instInfoARM;
> +static bool DecodeAddrMode2IdxInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned imm = fieldFromInstruction32(Insn, 0, 12);
> +  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
> +  unsigned reg = fieldFromInstruction32(Insn, 25, 1);
> +  unsigned P = fieldFromInstruction32(Insn, 24, 1);
> +  unsigned W = fieldFromInstruction32(Insn, 21, 1);
> +
> +  // On stores, the writeback operand precedes Rt.
> +  switch (Inst.getOpcode()) {
> +    case ARM::STR_POST_IMM:
> +    case ARM::STR_POST_REG:
> +    case ARM::STRTr:
> +    case ARM::STRTi:
> +    case ARM::STRBTr:
> +    case ARM::STRBTi:
> +      DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rt, Address, Decoder);
> +
> +  // On loads, the writeback operand comes after Rt.
> +  switch (Inst.getOpcode()) {
> +    case ARM::LDR_POST_IMM:
> +    case ARM::LDR_POST_REG:
> +    case ARM::LDR_PRE:
> +    case ARM::LDRBT_POST_REG:
> +    case ARM::LDRBT_POST_IMM:
> +    case ARM::LDRTr:
> +    case ARM::LDRTi:
> +      DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  ARM_AM::AddrOpc Op = ARM_AM::add;
> +  if (!fieldFromInstruction32(Insn, 23, 1))
> +    Op = ARM_AM::sub;
> +
> +  bool writeback = (P == 0) || (W == 1);
> +  unsigned idx_mode = 0;
> +  if (P && writeback)
> +    idx_mode = ARMII::IndexModePre;
> +  else if (!P && writeback)
> +    idx_mode = ARMII::IndexModePost;
> +
> +  if (reg) {
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +    ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
> +    switch( fieldFromInstruction32(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 false;
> +    }
> +    unsigned amt = fieldFromInstruction32(Insn, 7, 5);
> +    unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
> +
> +    Inst.addOperand(MCOperand::CreateImm(imm));
> +  } else {
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +    unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
> +    Inst.addOperand(MCOperand::CreateImm(tmp));
> +  }
> +
> +  if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
> +
> +  return true;
> +}
> +
> +static bool DecodeSORegMemOperand(llvm::MCInst &Inst, unsigned Val,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 13, 4);
> +  unsigned Rm = fieldFromInstruction32(Val,  0, 4);
> +  unsigned type = fieldFromInstruction32(Val, 5, 2);
> +  unsigned imm = fieldFromInstruction32(Val, 7, 5);
> +  unsigned U = fieldFromInstruction32(Val, 12, 1);
> +
> +  ARM_AM::ShiftOpc ShOp;
> +  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;
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  unsigned shift;
> +  if (U)
> +    shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
> +  else
> +    shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
> +  Inst.addOperand(MCOperand::CreateImm(shift));
> +
> +  return true;
> +}
> +
> +static bool DecodeAddrMode3Instruction(llvm::MCInst &Inst, unsigned Insn,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned type = fieldFromInstruction32(Insn, 22, 1);
> +  unsigned imm = fieldFromInstruction32(Insn, 8, 4);
> +  unsigned U = ((~fieldFromInstruction32(Insn, 23, 1)) & 1) << 8;
> +  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
> +  unsigned W = fieldFromInstruction32(Insn, 21, 1);
> +  unsigned P = fieldFromInstruction32(Insn, 24, 1);
> +
> +  bool writeback = (W == 1) | (P == 0);
> +  if (writeback) { // Writeback
> +    if (P)
> +      U |= ARMII::IndexModePre << 9;
> +    else
> +      U |= ARMII::IndexModePost << 9;
> +
> +    // On stores, the writeback operand precedes Rt.
> +    switch (Inst.getOpcode()) {
> +    case ARM::STRD:
> +    case ARM::STRD_PRE:
> +    case ARM::STRD_POST:
> +      DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +    }
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rt, Address, Decoder);
> +  switch (Inst.getOpcode()) {
> +    case ARM::STRD:
> +    case ARM::STRD_PRE:
> +    case ARM::STRD_POST:
> +    case ARM::LDRD:
> +    case ARM::LDRD_PRE:
> +    case ARM::LDRD_POST:
> +      DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  if (writeback) {
> +    // On loads, the writeback operand comes after Rt.
> +    switch (Inst.getOpcode()) {
> +    case ARM::LDRD:
> +    case ARM::LDRD_PRE:
> +    case ARM::LDRD_POST:
> +    case ARM::LDRHTr:
> +    case ARM::LDRSBTr:
> +      DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +    }
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  if (type) {
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +    Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
> +  } else {
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +    Inst.addOperand(MCOperand::CreateImm(U));
> +  }
> +
> +  if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
> +
> +  return true;
> +}
> +
> +static bool DecodeRFEInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned mode = fieldFromInstruction32(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;
> +  }
> +
> +  Inst.addOperand(MCOperand::CreateImm(mode));
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeMemMultipleWritebackInstruction(llvm::MCInst &Inst,
> +                                  unsigned Insn,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
> +  unsigned reglist = fieldFromInstruction32(Insn, 0, 16);
> +
> +  if (pred == 0xF) {
> +    switch (Inst.getOpcode()) {
> +      case ARM::STMDA:
> +        Inst.setOpcode(ARM::RFEDA);
> +        break;
> +      case ARM::STMDA_UPD:
> +        Inst.setOpcode(ARM::RFEDA_UPD);
> +        break;
> +      case ARM::STMDB:
> +        Inst.setOpcode(ARM::RFEDB);
> +        break;
> +      case ARM::STMDB_UPD:
> +        Inst.setOpcode(ARM::RFEDB_UPD);
> +        break;
> +      case ARM::STMIA:
> +        Inst.setOpcode(ARM::RFEIA);
> +        break;
> +      case ARM::STMIA_UPD:
> +        Inst.setOpcode(ARM::RFEIA_UPD);
> +        break;
> +      case ARM::STMIB:
> +        Inst.setOpcode(ARM::RFEIB);
> +        break;
> +      case ARM::STMIB_UPD:
> +        Inst.setOpcode(ARM::RFEIB_UPD);
> +        break;
> +
> +    }
> +    return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder); // Tied
> +  if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
> +  DecodeRegListOperand(Inst, reglist, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned imod = fieldFromInstruction32(Insn, 18, 2);
> +  unsigned M = fieldFromInstruction32(Insn, 17, 1);
> +  unsigned iflags = fieldFromInstruction32(Insn, 6, 3);
> +  unsigned mode = fieldFromInstruction32(Insn, 0, 5);
> +
> +  if (M && mode && imod && iflags) {
> +    Inst.setOpcode(ARM::CPS3p);
> +    Inst.addOperand(MCOperand::CreateImm(imod));
> +    Inst.addOperand(MCOperand::CreateImm(iflags));
> +    Inst.addOperand(MCOperand::CreateImm(mode));
> +    return true;
> +  } else if (!mode && !M) {
> +    Inst.setOpcode(ARM::CPS2p);
> +    Inst.addOperand(MCOperand::CreateImm(imod));
> +    Inst.addOperand(MCOperand::CreateImm(iflags));
> +    return true;
> +  } else if (!imod && !iflags && M) {
> +    Inst.setOpcode(ARM::CPS1p);
> +    Inst.addOperand(MCOperand::CreateImm(mode));
> +    return true;
> +  }
> +
> +  return false;
> +}
> +
> +static bool DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rn = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 8, 4);
> +  unsigned Ra = fieldFromInstruction32(Insn, 12, 4);
> +  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
> +
> +  if (pred == 0xF)
> +    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
> +
> +  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  DecodeGPRRegisterClass(Inst, Ra, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val,
> +                           uint64_t Address, const void *Decoder) {
> +  unsigned add = fieldFromInstruction32(Val, 12, 1);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 12);
> +  unsigned Rn = fieldFromInstruction32(Val, 13, 4);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  if (!add) imm *= -1;
> +  if (imm == 0 && !add) imm = INT32_MIN;
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  return true;
> +}
> +
> +static bool DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 9, 4);
> +  unsigned U = fieldFromInstruction32(Val, 8, 1);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 8);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  if (U)
> +    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
> +  else
> +    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
> +
> +  return true;
> +}
> +
> +static bool DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
> +}
> +
> +static bool DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
> +  unsigned imm = fieldFromInstruction32(Insn, 0, 24) << 2;
> +
> +  if (pred == 0xF) {
> +    Inst.setOpcode(ARM::BLXi);
> +    imm |= fieldFromInstruction32(Insn, 24, 1) << 1;
> +    Inst.addOperand(MCOperand::CreateImm(imm));
> +    return true;
> +  }
> +
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +  if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
> +
> +  return true;
> +}
> +
> +
> +static bool DecodeVCVTImmOperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(64 - Val));
> +  return true;
> +}
> +
> +static bool DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
> +  unsigned align = fieldFromInstruction32(Val, 4, 2);
> +
> +  DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  if (!align)
> +    Inst.addOperand(MCOperand::CreateImm(0));
> +  else
> +    Inst.addOperand(MCOperand::CreateImm(4 << align));
> +
> +  return true;
> +}
> +
> +static bool DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned wb = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  Rn |= fieldFromInstruction32(Insn, 4, 2) << 4;
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +
> +  // First output register
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +
> +  // Second output register
> +  switch (Inst.getOpcode()) {
> +    case ARM::VLD1q8:
> +    case ARM::VLD1q16:
> +    case ARM::VLD1q32:
> +    case ARM::VLD1q64:
> +    case ARM::VLD1q8_UPD:
> +    case ARM::VLD1q16_UPD:
> +    case ARM::VLD1q32_UPD:
> +    case ARM::VLD1q64_UPD:
> +    case ARM::VLD1d8T:
> +    case ARM::VLD1d16T:
> +    case ARM::VLD1d32T:
> +    case ARM::VLD1d64T:
> +    case ARM::VLD1d8T_UPD:
> +    case ARM::VLD1d16T_UPD:
> +    case ARM::VLD1d32T_UPD:
> +    case ARM::VLD1d64T_UPD:
> +    case ARM::VLD1d8Q:
> +    case ARM::VLD1d16Q:
> +    case ARM::VLD1d32Q:
> +    case ARM::VLD1d64Q:
> +    case ARM::VLD1d8Q_UPD:
> +    case ARM::VLD1d16Q_UPD:
> +    case ARM::VLD1d32Q_UPD:
> +    case ARM::VLD1d64Q_UPD:
> +    case ARM::VLD2d8:
> +    case ARM::VLD2d16:
> +    case ARM::VLD2d32:
> +    case ARM::VLD2d8_UPD:
> +    case ARM::VLD2d16_UPD:
> +    case ARM::VLD2d32_UPD:
> +    case ARM::VLD2q8:
> +    case ARM::VLD2q16:
> +    case ARM::VLD2q32:
> +    case ARM::VLD2q8_UPD:
> +    case ARM::VLD2q16_UPD:
> +    case ARM::VLD2q32_UPD:
> +    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:
> +      DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder);
> +      break;
> +    case ARM::VLD2b8:
> +    case ARM::VLD2b16:
> +    case ARM::VLD2b32:
> +    case ARM::VLD2b8_UPD:
> +    case ARM::VLD2b16_UPD:
> +    case ARM::VLD2b32_UPD:
> +    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:
> +      DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
> +    default:
> +      break;
> +  }
> +
> +  // Third output register
> +  switch(Inst.getOpcode()) {
> +    case ARM::VLD1d8T:
> +    case ARM::VLD1d16T:
> +    case ARM::VLD1d32T:
> +    case ARM::VLD1d64T:
> +    case ARM::VLD1d8T_UPD:
> +    case ARM::VLD1d16T_UPD:
> +    case ARM::VLD1d32T_UPD:
> +    case ARM::VLD1d64T_UPD:
> +    case ARM::VLD1d8Q:
> +    case ARM::VLD1d16Q:
> +    case ARM::VLD1d32Q:
> +    case ARM::VLD1d64Q:
> +    case ARM::VLD1d8Q_UPD:
> +    case ARM::VLD1d16Q_UPD:
> +    case ARM::VLD1d32Q_UPD:
> +    case ARM::VLD1d64Q_UPD:
> +    case ARM::VLD2q8:
> +    case ARM::VLD2q16:
> +    case ARM::VLD2q32:
> +    case ARM::VLD2q8_UPD:
> +    case ARM::VLD2q16_UPD:
> +    case ARM::VLD2q32_UPD:
> +    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:
> +      DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
> +      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:
> +      DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  // Fourth output register
> +  switch (Inst.getOpcode()) {
> +    case ARM::VLD1d8Q:
> +    case ARM::VLD1d16Q:
> +    case ARM::VLD1d32Q:
> +    case ARM::VLD1d64Q:
> +    case ARM::VLD1d8Q_UPD:
> +    case ARM::VLD1d16Q_UPD:
> +    case ARM::VLD1d32Q_UPD:
> +    case ARM::VLD1d64Q_UPD:
> +    case ARM::VLD2q8:
> +    case ARM::VLD2q16:
> +    case ARM::VLD2q32:
> +    case ARM::VLD2q8_UPD:
> +    case ARM::VLD2q16_UPD:
> +    case ARM::VLD2q32_UPD:
> +    case ARM::VLD4d8:
> +    case ARM::VLD4d16:
> +    case ARM::VLD4d32:
> +    case ARM::VLD4d8_UPD:
> +    case ARM::VLD4d16_UPD:
> +    case ARM::VLD4d32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder);
> +      break;
> +    case ARM::VLD4q8:
> +    case ARM::VLD4q16:
> +    case ARM::VLD4q32:
> +    case ARM::VLD4q8_UPD:
> +    case ARM::VLD4q16_UPD:
> +    case ARM::VLD4q32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  // Writeback operand
> +  switch (Inst.getOpcode()) {
> +    case ARM::VLD1d8_UPD:
> +    case ARM::VLD1d16_UPD:
> +    case ARM::VLD1d32_UPD:
> +    case ARM::VLD1d64_UPD:
> +    case ARM::VLD1q8_UPD:
> +    case ARM::VLD1q16_UPD:
> +    case ARM::VLD1q32_UPD:
> +    case ARM::VLD1q64_UPD:
> +    case ARM::VLD1d8T_UPD:
> +    case ARM::VLD1d16T_UPD:
> +    case ARM::VLD1d32T_UPD:
> +    case ARM::VLD1d64T_UPD:
> +    case ARM::VLD1d8Q_UPD:
> +    case ARM::VLD1d16Q_UPD:
> +    case ARM::VLD1d32Q_UPD:
> +    case ARM::VLD1d64Q_UPD:
> +    case ARM::VLD2d8_UPD:
> +    case ARM::VLD2d16_UPD:
> +    case ARM::VLD2d32_UPD:
> +    case ARM::VLD2q8_UPD:
> +    case ARM::VLD2q16_UPD:
> +    case ARM::VLD2q32_UPD:
> +    case ARM::VLD2b8_UPD:
> +    case ARM::VLD2b16_UPD:
> +    case ARM::VLD2b32_UPD:
> +    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:
> +      DecodeGPRRegisterClass(Inst, wb, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  // AddrMode6 Base (register+alignment)
> +  DecodeAddrMode6Operand(Inst, Rn, Address, Decoder);
> +
> +  // AddrMode6 Offset (register)
> +  if (Rm == 0xD)
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  else if (Rm != 0xF)
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned wb = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  Rn |= fieldFromInstruction32(Insn, 4, 2) << 4;
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +
> +  // Writeback Operand
> +  switch (Inst.getOpcode()) {
> +    case ARM::VST1d8_UPD:
> +    case ARM::VST1d16_UPD:
> +    case ARM::VST1d32_UPD:
> +    case ARM::VST1d64_UPD:
> +    case ARM::VST1q8_UPD:
> +    case ARM::VST1q16_UPD:
> +    case ARM::VST1q32_UPD:
> +    case ARM::VST1q64_UPD:
> +    case ARM::VST1d8T_UPD:
> +    case ARM::VST1d16T_UPD:
> +    case ARM::VST1d32T_UPD:
> +    case ARM::VST1d64T_UPD:
> +    case ARM::VST1d8Q_UPD:
> +    case ARM::VST1d16Q_UPD:
> +    case ARM::VST1d32Q_UPD:
> +    case ARM::VST1d64Q_UPD:
> +    case ARM::VST2d8_UPD:
> +    case ARM::VST2d16_UPD:
> +    case ARM::VST2d32_UPD:
> +    case ARM::VST2q8_UPD:
> +    case ARM::VST2q16_UPD:
> +    case ARM::VST2q32_UPD:
> +    case ARM::VST2b8_UPD:
> +    case ARM::VST2b16_UPD:
> +    case ARM::VST2b32_UPD:
> +    case ARM::VST3d8_UPD:
> +    case ARM::VST3d16_UPD:
> +    case ARM::VST3d32_UPD:
> +    case ARM::VST3q8_UPD:
> +    case ARM::VST3q16_UPD:
> +    case ARM::VST3q32_UPD:
> +    case ARM::VST4d8_UPD:
> +    case ARM::VST4d16_UPD:
> +    case ARM::VST4d32_UPD:
> +    case ARM::VST4q8_UPD:
> +    case ARM::VST4q16_UPD:
> +    case ARM::VST4q32_UPD:
> +      DecodeGPRRegisterClass(Inst, wb, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  // AddrMode6 Base (register+alignment)
> +  DecodeAddrMode6Operand(Inst, Rn, Address, Decoder);
> +
> +  // AddrMode6 Offset (register)
> +  if (Rm == 0xD)
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  else if (Rm != 0xF)
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  // First input register
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +
> +  // Second input register
> +  switch (Inst.getOpcode()) {
> +    case ARM::VST1q8:
> +    case ARM::VST1q16:
> +    case ARM::VST1q32:
> +    case ARM::VST1q64:
> +    case ARM::VST1q8_UPD:
> +    case ARM::VST1q16_UPD:
> +    case ARM::VST1q32_UPD:
> +    case ARM::VST1q64_UPD:
> +    case ARM::VST1d8T:
> +    case ARM::VST1d16T:
> +    case ARM::VST1d32T:
> +    case ARM::VST1d64T:
> +    case ARM::VST1d8T_UPD:
> +    case ARM::VST1d16T_UPD:
> +    case ARM::VST1d32T_UPD:
> +    case ARM::VST1d64T_UPD:
> +    case ARM::VST1d8Q:
> +    case ARM::VST1d16Q:
> +    case ARM::VST1d32Q:
> +    case ARM::VST1d64Q:
> +    case ARM::VST1d8Q_UPD:
> +    case ARM::VST1d16Q_UPD:
> +    case ARM::VST1d32Q_UPD:
> +    case ARM::VST1d64Q_UPD:
> +    case ARM::VST2d8:
> +    case ARM::VST2d16:
> +    case ARM::VST2d32:
> +    case ARM::VST2d8_UPD:
> +    case ARM::VST2d16_UPD:
> +    case ARM::VST2d32_UPD:
> +    case ARM::VST2q8:
> +    case ARM::VST2q16:
> +    case ARM::VST2q32:
> +    case ARM::VST2q8_UPD:
> +    case ARM::VST2q16_UPD:
> +    case ARM::VST2q32_UPD:
> +    case ARM::VST3d8:
> +    case ARM::VST3d16:
> +    case ARM::VST3d32:
> +    case ARM::VST3d8_UPD:
> +    case ARM::VST3d16_UPD:
> +    case ARM::VST3d32_UPD:
> +    case ARM::VST4d8:
> +    case ARM::VST4d16:
> +    case ARM::VST4d32:
> +    case ARM::VST4d8_UPD:
> +    case ARM::VST4d16_UPD:
> +    case ARM::VST4d32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder);
> +      break;
> +    case ARM::VST2b8:
> +    case ARM::VST2b16:
> +    case ARM::VST2b32:
> +    case ARM::VST2b8_UPD:
> +    case ARM::VST2b16_UPD:
> +    case ARM::VST2b32_UPD:
> +    case ARM::VST3q8:
> +    case ARM::VST3q16:
> +    case ARM::VST3q32:
> +    case ARM::VST3q8_UPD:
> +    case ARM::VST3q16_UPD:
> +    case ARM::VST3q32_UPD:
> +    case ARM::VST4q8:
> +    case ARM::VST4q16:
> +    case ARM::VST4q32:
> +    case ARM::VST4q8_UPD:
> +    case ARM::VST4q16_UPD:
> +    case ARM::VST4q32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  // Third input register
> +  switch (Inst.getOpcode()) {
> +    case ARM::VST1d8T:
> +    case ARM::VST1d16T:
> +    case ARM::VST1d32T:
> +    case ARM::VST1d64T:
> +    case ARM::VST1d8T_UPD:
> +    case ARM::VST1d16T_UPD:
> +    case ARM::VST1d32T_UPD:
> +    case ARM::VST1d64T_UPD:
> +    case ARM::VST1d8Q:
> +    case ARM::VST1d16Q:
> +    case ARM::VST1d32Q:
> +    case ARM::VST1d64Q:
> +    case ARM::VST1d8Q_UPD:
> +    case ARM::VST1d16Q_UPD:
> +    case ARM::VST1d32Q_UPD:
> +    case ARM::VST1d64Q_UPD:
> +    case ARM::VST2q8:
> +    case ARM::VST2q16:
> +    case ARM::VST2q32:
> +    case ARM::VST2q8_UPD:
> +    case ARM::VST2q16_UPD:
> +    case ARM::VST2q32_UPD:
> +    case ARM::VST3d8:
> +    case ARM::VST3d16:
> +    case ARM::VST3d32:
> +    case ARM::VST3d8_UPD:
> +    case ARM::VST3d16_UPD:
> +    case ARM::VST3d32_UPD:
> +    case ARM::VST4d8:
> +    case ARM::VST4d16:
> +    case ARM::VST4d32:
> +    case ARM::VST4d8_UPD:
> +    case ARM::VST4d16_UPD:
> +    case ARM::VST4d32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
> +      break;
> +    case ARM::VST3q8:
> +    case ARM::VST3q16:
> +    case ARM::VST3q32:
> +    case ARM::VST3q8_UPD:
> +    case ARM::VST3q16_UPD:
> +    case ARM::VST3q32_UPD:
> +    case ARM::VST4q8:
> +    case ARM::VST4q16:
> +    case ARM::VST4q32:
> +    case ARM::VST4q8_UPD:
> +    case ARM::VST4q16_UPD:
> +    case ARM::VST4q32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  // Fourth input register
> +  switch (Inst.getOpcode()) {
> +    case ARM::VST1d8Q:
> +    case ARM::VST1d16Q:
> +    case ARM::VST1d32Q:
> +    case ARM::VST1d64Q:
> +    case ARM::VST1d8Q_UPD:
> +    case ARM::VST1d16Q_UPD:
> +    case ARM::VST1d32Q_UPD:
> +    case ARM::VST1d64Q_UPD:
> +    case ARM::VST2q8:
> +    case ARM::VST2q16:
> +    case ARM::VST2q32:
> +    case ARM::VST2q8_UPD:
> +    case ARM::VST2q16_UPD:
> +    case ARM::VST2q32_UPD:
> +    case ARM::VST4d8:
> +    case ARM::VST4d16:
> +    case ARM::VST4d32:
> +    case ARM::VST4d8_UPD:
> +    case ARM::VST4d16_UPD:
> +    case ARM::VST4d32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder);
> +      break;
> +    case ARM::VST4q8:
> +    case ARM::VST4q16:
> +    case ARM::VST4q32:
> +    case ARM::VST4q8_UPD:
> +    case ARM::VST4q16_UPD:
> +    case ARM::VST4q32_UPD:
> +      DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  return true;
> +}
> +
> +static bool DecodeVLD1DupInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                    uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned align = fieldFromInstruction32(Insn, 4, 1);
> +  unsigned size = fieldFromInstruction32(Insn, 6, 2);
> +  unsigned regs = fieldFromInstruction32(Insn, 5, 1) + 1;
> +
> +  align *= (1 << size);
> +
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +  if (regs == 2) DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder);
> +  if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(align));
> +
> +  if (Rm == 0xD)
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  else if (Rm != 0xF)
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                    uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned align = fieldFromInstruction32(Insn, 4, 1);
> +  unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2);
> +  unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
> +  align *= 2*size;
> +
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder);
> +  if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(align));
> +
> +  if (Rm == 0xD)
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  else if (Rm != 0xF)
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeVLD3DupInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                    uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
> +
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder);
> +  if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(0));
> +
> +  if (Rm == 0xD)
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  else if (Rm != 0xF)
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeVLD4DupInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                    uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned size = fieldFromInstruction32(Insn, 6, 2);
> +  unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
> +  unsigned align = fieldFromInstruction32(Insn, 4, 1);
> +
> +  if (size == 0x3) {
> +    size = 4;
> +    align = 16;
> +  } else {
> +    if (size == 2) {
> +      size = 1 << size;
> +      align *= 8;
> +    } else {
> +      size = 1 << size;
> +      align *= 4*size;
> +    }
> +  }
> +
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder);
> +  if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(align));
> +
> +  if (Rm == 0xD)
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +  else if (Rm != 0xF)
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeNEONModImmInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                        uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned imm = fieldFromInstruction32(Insn, 0, 4);
> +  imm |= fieldFromInstruction32(Insn, 16, 3) << 4;
> +  imm |= fieldFromInstruction32(Insn, 24, 1) << 7;
> +  imm |= fieldFromInstruction32(Insn, 8, 4) << 8;
> +  imm |= fieldFromInstruction32(Insn, 5, 1) << 12;
> +  unsigned Q = fieldFromInstruction32(Insn, 6, 1);
> +
> +  if (Q)
> +    DecodeQPRRegisterClass(Inst, Rd, Address, Decoder);
> +  else
> +    DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  switch (Inst.getOpcode()) {
> +    case ARM::VORRiv4i16:
> +    case ARM::VORRiv2i32:
> +    case ARM::VBICiv4i16:
> +    case ARM::VBICiv2i32:
> +      DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +      break;
> +    case ARM::VORRiv8i16:
> +    case ARM::VORRiv4i32:
> +    case ARM::VBICiv8i16:
> +    case ARM::VBICiv4i32:
> +      DecodeQPRRegisterClass(Inst, Rd, Address, Decoder);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +
> +  return true;
> +}
> +
> +static bool DecodeVSHLMaxInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                        uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
> +  unsigned size = fieldFromInstruction32(Insn, 18, 2);
> +
> +  DecodeQPRRegisterClass(Inst, Rd, Address, Decoder);
> +  DecodeDPRRegisterClass(Inst, Rm, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(8 << size));
> +
> +  return true;
> +}
> +
> +static bool DecodeShiftRight8Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(8 - Val));
> +  return true;
> +}
> +
> +static bool DecodeShiftRight16Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(16 - Val));
> +  return true;
> +}
> +
> +static bool DecodeShiftRight32Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(32 - Val));
> +  return true;
> +}
> +
> +static bool DecodeShiftRight64Imm(llvm::MCInst &Inst, unsigned Val,
> +                               uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(64 - Val));
> +  return true;
> +}
> +
> +static bool DecodeTBLInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                               uint64_t Address, const void *Decoder) {
> +  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
> +  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  Rn |= fieldFromInstruction32(Insn, 7, 1) << 4;
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
> +  unsigned op = fieldFromInstruction32(Insn, 6, 1);
> +  unsigned length = fieldFromInstruction32(Insn, 8, 2) + 1;
> +
> +  DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
> +  if (op) DecodeDPRRegisterClass(Inst, Rd, Address, Decoder); // Writeback
> +
> +  for (unsigned i = 0; i < length; ++i)
> +    DecodeDPRRegisterClass(Inst, (Rn+i)%32, Address, Decoder);
> +
> +  DecodeDPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeVFPfpImm(llvm::MCInst &Inst, unsigned Val,
> +                            uint64_t Address, const void *Decoder) {
> +  // The immediate needs to be a fully instantiated float.  However, the
> +  // auto-generated decoder is only able to fill in some of the bits
> +  // necessary.  For instance, the 'b' bit is replicated multiple times,
> +  // and is even present in inverted form in one bit.  We do a little
> +  // binary parsing here to fill in those missing bits, and then
> +  // reinterpret it all as a float.
> +  union {
> +    uint32_t integer;
> +    float fp;
> +  } fp_conv;
> +
> +  fp_conv.integer = Val;
> +  uint32_t b = fieldFromInstruction32(Val, 25, 1);
> +  fp_conv.integer |= b << 26;
> +  fp_conv.integer |= b << 27;
> +  fp_conv.integer |= b << 28;
> +  fp_conv.integer |= b << 29;
> +  fp_conv.integer |= (~b & 0x1) << 30;
> +
> +  Inst.addOperand(MCOperand::CreateFPImm(fp_conv.fp));
> +  return true;
> +}
> +
> +static bool DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn,
> +                                     uint64_t Address, const void *Decoder) {
> +  unsigned dst = fieldFromInstruction16(Insn, 8, 3);
> +  unsigned imm = fieldFromInstruction16(Insn, 0, 8);
> +
> +  DecodetGPRRegisterClass(Inst, dst, Address, Decoder);
> +
> +  if (Inst.getOpcode() == ARM::tADR)
> +    Inst.addOperand(MCOperand::CreateReg(ARM::PC));
> +  else if (Inst.getOpcode() == ARM::tADDrSPi)
> +    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +  else
> +    return false;
> +
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +  return true;
> +}
> +
> +static bool DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
> +  return true;
> +}
> +
> +static bool DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
> +  return true;
> +}
> +
> +static bool DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
> +  return true;
> +}
> +
> +static bool DecodeThumbAddrModeRR(llvm::MCInst &Inst, unsigned Val,
> +                                 uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 0, 3);
> +  unsigned Rm = fieldFromInstruction32(Val, 3, 3);
> +
> +  DecodetGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecodetGPRRegisterClass(Inst, Rm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbAddrModeIS(llvm::MCInst &Inst, unsigned Val,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 0, 3);
> +  unsigned imm = fieldFromInstruction32(Val, 3, 5);
> +
> +  DecodetGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbAddrModePC(llvm::MCInst &Inst, unsigned Val,
> +                                  uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(Val << 2));
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbAddrModeSP(llvm::MCInst &Inst, unsigned Val,
> +                                  uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +  Inst.addOperand(MCOperand::CreateImm(Val << 2));
> +
> +  return true;
> +}
> +
> +static bool DecodeT2AddrModeSOReg(llvm::MCInst &Inst, unsigned Val,
> +                                  uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 6, 4);
> +  unsigned Rm = fieldFromInstruction32(Val, 2, 4);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 2);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecoderGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  return true;
> +}
> +
> +static bool DecodeT2LoadShift(llvm::MCInst &Inst, unsigned Insn,
> +                              uint64_t Address, const void *Decoder) {
> +  if (Inst.getOpcode() != ARM::t2PLDs) {
> +    unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
> +    DecodeGPRRegisterClass(Inst, Rt, Address, Decoder);
> +  }
> +
> +  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
> +  if (Rn == 0xF) {
> +    switch (Inst.getOpcode()) {
> +      case ARM::t2LDRBs:
> +        Inst.setOpcode(ARM::t2LDRBpci);
> +        break;
> +      case ARM::t2LDRHs:
> +        Inst.setOpcode(ARM::t2LDRHpci);
> +        break;
> +      case ARM::t2LDRSHs:
> +        Inst.setOpcode(ARM::t2LDRSHpci);
> +        break;
> +      case ARM::t2LDRSBs:
> +        Inst.setOpcode(ARM::t2LDRSBpci);
> +        break;
> +      case ARM::t2PLDs:
> +        Inst.setOpcode(ARM::t2PLDi12);
> +        Inst.addOperand(MCOperand::CreateReg(ARM::PC));
> +        break;
> +      default:
> +        return false;
> +    }
> +
> +    int imm = fieldFromInstruction32(Insn, 0, 12);
> +    if (!fieldFromInstruction32(Insn, 23, 1)) imm *= -1;
> +    Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +    return true;
> +  }
> +
> +  unsigned addrmode = fieldFromInstruction32(Insn, 4, 2);
> +  addrmode |= fieldFromInstruction32(Insn, 0, 4) << 2;
> +  addrmode |= fieldFromInstruction32(Insn, 16, 4) << 6;
> +  DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeT2Imm8S4(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  int imm = Val & 0xFF;
> +  if (!(Val & 0x100)) imm *= -1;
> +  Inst.addOperand(MCOperand::CreateImm(imm << 2));
> +
> +  return true;
> +}
> +
> +static bool DecodeT2AddrModeImm8s4(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 9, 4);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 9);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecodeT2Imm8S4(Inst, imm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +static bool DecodeT2Imm8(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  int imm = Val & 0xFF;
> +  if (!(Val & 0x100)) imm *= -1;
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  return true;
> +}
> +
> +
> +static bool DecodeT2AddrModeImm8(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 9, 4);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 9);
> +
> +  // Some instructions always use an additive offset.
> +  switch (Inst.getOpcode()) {
> +    case ARM::t2LDRT:
> +    case ARM::t2LDRBT:
> +    case ARM::t2LDRHT:
> +    case ARM::t2LDRSBT:
> +    case ARM::t2LDRSHT:
> +      imm |= 0x100;
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  DecodeT2Imm8(Inst, imm, Address, Decoder);
> +
> +  return true;
> +}
> +
> +
> +static bool DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rn = fieldFromInstruction32(Val, 13, 4);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 12);
> +
> +  DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  return true;
> +}
> +
> +
> +static bool DecodeThumbAddSPImm(llvm::MCInst &Inst, uint16_t Insn,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned imm = fieldFromInstruction16(Insn, 0, 7);
> +
> +  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +  Inst.addOperand(MCOperand::CreateImm(imm));
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbAddSPReg(llvm::MCInst &Inst, uint16_t Insn,
> +                                   uint64_t Address, const void *Decoder) {
> +  if (Inst.getOpcode() == ARM::tADDrSP) {
> +    unsigned Rdm = fieldFromInstruction16(Insn, 0, 3);
> +    Rdm |= fieldFromInstruction16(Insn, 7, 1) << 3;
> +
> +    DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder);
> +    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +    DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder);
> +  } else if (Inst.getOpcode() == ARM::tADDspr) {
> +    unsigned Rm = fieldFromInstruction16(Insn, 3, 4);
> +
> +    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
> +    DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  }
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbCPS(llvm::MCInst &Inst, uint16_t Insn,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned imod = fieldFromInstruction16(Insn, 4, 1) | 0x2;
> +  unsigned flags = fieldFromInstruction16(Insn, 0, 3);
> +
> +  Inst.addOperand(MCOperand::CreateImm(imod));
> +  Inst.addOperand(MCOperand::CreateImm(flags));
> +
> +  return true;
> +}
> +
> +static bool DecodePostIdxReg(llvm::MCInst &Inst, unsigned Insn,
> +                                   uint64_t Address, const void *Decoder) {
> +  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
> +  unsigned add = fieldFromInstruction32(Insn, 4, 1);
> +
> +  DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
> +  Inst.addOperand(MCOperand::CreateImm(add));
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Val,
> +                                   uint64_t Address, const void *Decoder) {
> +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
> +  return true;
> +}
> +
> +static bool DecodeCoprocessor(llvm::MCInst &Inst, unsigned Val,
> +                              uint64_t Address, const void *Decoder) {
> +  if (Val == 0xA || Val == 0xB)
> +    return false;
> +
> +  Inst.addOperand(MCOperand::CreateImm(Val));
> +  return true;
> +}
> +
> +static bool DecodeThumbSRImm(llvm::MCInst &Inst, unsigned Val,
> +                              uint64_t Address, const void *Decoder) {
> +  if (Val == 0)
> +    Inst.addOperand(MCOperand::CreateImm(32));
> +  else
> +    Inst.addOperand(MCOperand::CreateImm(Val));
> +  return true;
> +}
> +
> +static bool DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Insn,
> +                                       uint64_t Address, const void *Decoder) {
> +  unsigned pred = fieldFromInstruction32(Insn, 22, 4);
> +  if (pred == 0xE || pred == 0xF) {
> +    unsigned opc = fieldFromInstruction32(Insn, 4, 2);
> +    switch (opc) {
> +      default:
> +        return false;
> +      case 0:
> +        Inst.setOpcode(ARM::t2DSB);
> +        break;
> +      case 1:
> +        Inst.setOpcode(ARM::t2DMB);
> +        break;
> +      case 2:
> +        Inst.setOpcode(ARM::t2ISB);
> +        return true;
> +    }
> +
> +    unsigned imm = fieldFromInstruction32(Insn, 0, 4);
> +    Inst.addOperand(MCOperand::CreateImm(imm));
> +    return true;
> +  }
> +
> +  unsigned brtarget = fieldFromInstruction32(Insn, 0, 11) << 1;
> +  brtarget |= fieldFromInstruction32(Insn, 11, 1) << 19;
> +  brtarget |= fieldFromInstruction32(Insn, 13, 1) << 18;
> +  brtarget |= fieldFromInstruction32(Insn, 16, 6) << 12;
> +  brtarget |= fieldFromInstruction32(Insn, 26, 1) << 20;
> +
> +  DecodeT2BROperand(Inst, brtarget, Address, Decoder);
> +  if (!DecodePredicateOperand(Inst, pred, Address, Decoder))
> +    return false;
> +
> +  return true;
> +}
> +
> +// Decode a shifted immediate operand.  These basically consist
> +// of an 8-bit value, and a 4-bit directive that specifies either
> +// a splat operation or a rotation.
> +static bool DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val,
> +                          uint64_t Address, const void *Decoder) {
> +  unsigned ctrl = fieldFromInstruction32(Val, 10, 2);
> +  if (ctrl == 0) {
> +    unsigned byte = fieldFromInstruction32(Val, 8, 2);
> +    unsigned imm = fieldFromInstruction32(Val, 0, 8);
> +    switch (byte) {
> +      case 0:
> +        Inst.addOperand(MCOperand::CreateImm(imm));
> +        break;
> +      case 1:
> +        Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
> +        break;
> +      case 2:
> +        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
> +        break;
> +      case 3:
> +        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
> +                                             (imm << 8)  |  imm));
> +        break;
> +    }
> +  } else {
> +    unsigned unrot = fieldFromInstruction32(Val, 0, 7) | 0x80;
> +    unsigned rot = fieldFromInstruction32(Val, 7, 5);
> +    unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
> +    Inst.addOperand(MCOperand::CreateImm(imm));
> +  }
> +
> +  return true;
> +}
> +
> +static bool DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val,
> +                                        uint64_t Address, const void *Decoder){
> +  Inst.addOperand(MCOperand::CreateImm(Val << 1));
> +  return true;
> +}
> +
> +static bool DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
> +                                        uint64_t Address, const void *Decoder){
> +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
> +  return true;
> +}
> +
> +static bool DecodeAddrMode3Offset(llvm::MCInst &Inst, unsigned Val,
> +                                  uint64_t Address, const void *Decoder) {
> +  bool isImm = fieldFromInstruction32(Val, 9, 1);
> +  bool isAdd = fieldFromInstruction32(Val, 8, 1);
> +  unsigned imm = fieldFromInstruction32(Val, 0, 8);
> +
> +  if (!isImm) {
> +    DecodeGPRRegisterClass(Inst, imm, Address, Decoder);
> +    Inst.addOperand(MCOperand::CreateImm(!isAdd << 8));
> +  } else {
> +    Inst.addOperand(MCOperand::CreateReg(0));
> +    Inst.addOperand(MCOperand::CreateImm(imm | (!isAdd << 8)));
> +  }
> +
> +  return true;
> }
> 
> Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.h?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.h (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.h Tue Aug  9 15:55:18 2011
> @@ -17,15 +17,16 @@
> #define ARMDISASSEMBLER_H
> 
> #include "llvm/MC/MCDisassembler.h"
> +#include <vector>
> 
> namespace llvm {
> 
> class MCInst;
> class MemoryObject;
> class raw_ostream;
> -  
> +
> struct EDInstInfo;
> -  
> +
> /// ARMDisassembler - ARM disassembler for all ARM platforms.
> class ARMDisassembler : public MCDisassembler {
> public:
> @@ -44,38 +45,19 @@
>                       const MemoryObject &region,
>                       uint64_t address,
>                       raw_ostream &vStream) const;
> -  
> +
>   /// getEDInfo - See MCDisassembler.
>   EDInstInfo *getEDInfo() const;
> private:
> };
> 
> -// Forward declaration.
> -class ARMBasicMCBuilder;
> -
> -/// Session - Keep track of the IT Block progression.
> -class Session {
> -  friend class ARMBasicMCBuilder;
> -public:
> -  Session() : ITCounter(0), ITState(0) {}
> -  ~Session() {}
> -  /// InitIT - Initializes ITCounter/ITState.
> -  bool InitIT(unsigned short bits7_0);
> -  /// UpdateIT - Updates ITCounter/ITState as IT Block progresses.
> -  void UpdateIT();
> -
> -private:
> -  unsigned ITCounter; // Possible values: 0, 1, 2, 3, 4.
> -  unsigned ITState;   // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
> -};
> -
> -/// ThumbDisassembler - Thumb disassembler for all ARM platforms.
> +/// ARMDisassembler - ARM disassembler for all ARM platforms.
> class ThumbDisassembler : public MCDisassembler {
> public:
>   /// Constructor     - Initializes the disassembler.
>   ///
>   ThumbDisassembler() :
> -    MCDisassembler(), SO() {
> +    MCDisassembler() {
>   }
> 
>   ~ThumbDisassembler() {
> @@ -87,13 +69,16 @@
>                       const MemoryObject &region,
>                       uint64_t address,
>                       raw_ostream &vStream) const;
> -  
> +
>   /// getEDInfo - See MCDisassembler.
>   EDInstInfo *getEDInfo() const;
> private:
> -  Session SO;
> +  mutable std::vector<unsigned> ITBlock;
> +  void AddThumbPredicate(MCInst&) const;
> +  void UpdateThumbVFPPredicate(MCInst&) const;
> };
> 
> +
> } // namespace llvm
> -  
> +
> #endif
> 
> Removed: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=137143&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (removed)
> @@ -1,3894 +0,0 @@
> -//===- ARMDisassemblerCore.cpp - ARM disassembler helpers -------*- C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -//
> -// This file is part of the ARM Disassembler.
> -// It contains code to represent the core concepts of Builder and DisassembleFP
> -// to solve the problem of disassembling an ARM instr.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -#define DEBUG_TYPE "arm-disassembler"
> -
> -#include "ARMDisassemblerCore.h"
> -#include "MCTargetDesc/ARMAddressingModes.h"
> -#include "MCTargetDesc/ARMMCExpr.h"
> -#include "llvm/ADT/APInt.h"
> -#include "llvm/ADT/APFloat.h"
> -#include "llvm/Support/Debug.h"
> -#include "llvm/Support/raw_ostream.h"
> -
> -//#define DEBUG(X) do { X; } while (0)
> -
> -/// ARMGenInstrInfo.inc - ARMGenInstrInfo.inc contains the static const
> -/// MCInstrDesc ARMInsts[] definition and the MCOperandInfo[]'s describing the
> -/// operand info for each ARMInsts[i].
> -///
> -/// Together with an instruction's encoding format, we can take advantage of the
> -/// NumOperands and the OpInfo fields of the target instruction description in
> -/// the quest to build out the MCOperand list for an MCInst.
> -///
> -/// The general guideline is that with a known format, the number of dst and src
> -/// operands are well-known.  The dst is built first, followed by the src
> -/// operand(s).  The operands not yet used at this point are for the Implicit
> -/// Uses and Defs by this instr.  For the Uses part, the pred:$p operand is
> -/// defined with two components:
> -///
> -/// def pred { // Operand PredicateOperand
> -///   ValueType Type = OtherVT;
> -///   string PrintMethod = "printPredicateOperand";
> -///   string AsmOperandLowerMethod = ?;
> -///   dag MIOperandInfo = (ops i32imm, CCR);
> -///   AsmOperandClass ParserMatchClass = ImmAsmOperand;
> -///   dag DefaultOps = (ops (i32 14), (i32 zero_reg));
> -/// }
> -///
> -/// which is manifested by the MCOperandInfo[] of:
> -///
> -/// { 0, 0|(1<<MCOI::Predicate), 0 },
> -/// { ARM::CCRRegClassID, 0|(1<<MCOI::Predicate), 0 }
> -///
> -/// So the first predicate MCOperand corresponds to the immediate part of the
> -/// ARM condition field (Inst{31-28}), and the second predicate MCOperand
> -/// corresponds to a register kind of ARM::CPSR.
> -///
> -/// For the Defs part, in the simple case of only cc_out:$s, we have:
> -///
> -/// def cc_out { // Operand OptionalDefOperand
> -///   ValueType Type = OtherVT;
> -///   string PrintMethod = "printSBitModifierOperand";
> -///   string AsmOperandLowerMethod = ?;
> -///   dag MIOperandInfo = (ops CCR);
> -///   AsmOperandClass ParserMatchClass = ImmAsmOperand;
> -///   dag DefaultOps = (ops (i32 zero_reg));
> -/// }
> -///
> -/// which is manifested by the one MCOperandInfo of:
> -///
> -/// { ARM::CCRRegClassID, 0|(1<<MCOI::OptionalDef), 0 }
> -///
> -
> -namespace llvm {
> -extern MCInstrDesc ARMInsts[];
> -}
> -
> -using namespace llvm;
> -
> -const char *ARMUtils::OpcodeName(unsigned Opcode) {
> -  return ARMInsts[Opcode].Name;
> -}
> -
> -// Return the register enum Based on RegClass and the raw register number.
> -// FIXME: Auto-gened?
> -static unsigned
> -getRegisterEnum(BO B, unsigned RegClassID, unsigned RawRegister) {
> -  if (RegClassID == ARM::rGPRRegClassID) {
> -    // Check for The register numbers 13 and 15 that are not permitted for many
> -    // Thumb register specifiers.
> -    if (RawRegister == 13 || RawRegister == 15) {
> -      B->SetErr(-1);
> -      return 0;
> -    }
> -    // For this purpose, we can treat rGPR as if it were GPR.
> -    RegClassID = ARM::GPRRegClassID;
> -  }
> -
> -  // See also decodeNEONRd(), decodeNEONRn(), decodeNEONRm().
> -  // A7.3 register encoding
> -  //     Qd -> bit[12] == 0
> -  //     Qn -> bit[16] == 0
> -  //     Qm -> bit[0]  == 0
> -  //
> -  // If one of these bits is 1, the instruction is UNDEFINED.
> -  if (RegClassID == ARM::QPRRegClassID && slice(RawRegister, 0, 0) == 1) {
> -    B->SetErr(-1);
> -    return 0;
> -  }
> -  unsigned RegNum =
> -    RegClassID == ARM::QPRRegClassID ? RawRegister >> 1 : RawRegister;
> -
> -  switch (RegNum) {
> -  default:
> -    break;
> -  case 0:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R0;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D0;
> -    case ARM::QPRRegClassID: case ARM::QPR_8RegClassID:
> -    case ARM::QPR_VFP2RegClassID:
> -      return ARM::Q0;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S0;
> -    }
> -    break;
> -  case 1:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R1;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D1;
> -    case ARM::QPRRegClassID: case ARM::QPR_8RegClassID:
> -    case ARM::QPR_VFP2RegClassID:
> -      return ARM::Q1;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S1;
> -    }
> -    break;
> -  case 2:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R2;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D2;
> -    case ARM::QPRRegClassID: case ARM::QPR_8RegClassID:
> -    case ARM::QPR_VFP2RegClassID:
> -      return ARM::Q2;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S2;
> -    }
> -    break;
> -  case 3:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R3;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D3;
> -    case ARM::QPRRegClassID: case ARM::QPR_8RegClassID:
> -    case ARM::QPR_VFP2RegClassID:
> -      return ARM::Q3;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S3;
> -    }
> -    break;
> -  case 4:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R4;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D4;
> -    case ARM::QPRRegClassID: case ARM::QPR_VFP2RegClassID: return ARM::Q4;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S4;
> -    }
> -    break;
> -  case 5:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R5;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D5;
> -    case ARM::QPRRegClassID: case ARM::QPR_VFP2RegClassID: return ARM::Q5;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S5;
> -    }
> -    break;
> -  case 6:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R6;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D6;
> -    case ARM::QPRRegClassID: case ARM::QPR_VFP2RegClassID: return ARM::Q6;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S6;
> -    }
> -    break;
> -  case 7:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: case ARM::tGPRRegClassID: return ARM::R7;
> -    case ARM::DPRRegClassID: case ARM::DPR_8RegClassID:
> -    case ARM::DPR_VFP2RegClassID:
> -      return ARM::D7;
> -    case ARM::QPRRegClassID: case ARM::QPR_VFP2RegClassID: return ARM::Q7;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S7;
> -    }
> -    break;
> -  case 8:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::R8;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D8;
> -    case ARM::QPRRegClassID: return ARM::Q8;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S8;
> -    }
> -    break;
> -  case 9:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::R9;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D9;
> -    case ARM::QPRRegClassID: return ARM::Q9;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S9;
> -    }
> -    break;
> -  case 10:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::R10;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D10;
> -    case ARM::QPRRegClassID: return ARM::Q10;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S10;
> -    }
> -    break;
> -  case 11:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::R11;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D11;
> -    case ARM::QPRRegClassID: return ARM::Q11;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S11;
> -    }
> -    break;
> -  case 12:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::R12;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D12;
> -    case ARM::QPRRegClassID: return ARM::Q12;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S12;
> -    }
> -    break;
> -  case 13:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::SP;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D13;
> -    case ARM::QPRRegClassID: return ARM::Q13;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S13;
> -    }
> -    break;
> -  case 14:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::LR;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D14;
> -    case ARM::QPRRegClassID: return ARM::Q14;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S14;
> -    }
> -    break;
> -  case 15:
> -    switch (RegClassID) {
> -    case ARM::GPRRegClassID: return ARM::PC;
> -    case ARM::DPRRegClassID: case ARM::DPR_VFP2RegClassID: return ARM::D15;
> -    case ARM::QPRRegClassID: return ARM::Q15;
> -    case ARM::SPRRegClassID: case ARM::SPR_8RegClassID: return ARM::S15;
> -    }
> -    break;
> -  case 16:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D16;
> -    case ARM::SPRRegClassID: return ARM::S16;
> -    }
> -    break;
> -  case 17:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D17;
> -    case ARM::SPRRegClassID: return ARM::S17;
> -    }
> -    break;
> -  case 18:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D18;
> -    case ARM::SPRRegClassID: return ARM::S18;
> -    }
> -    break;
> -  case 19:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D19;
> -    case ARM::SPRRegClassID: return ARM::S19;
> -    }
> -    break;
> -  case 20:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D20;
> -    case ARM::SPRRegClassID: return ARM::S20;
> -    }
> -    break;
> -  case 21:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D21;
> -    case ARM::SPRRegClassID: return ARM::S21;
> -    }
> -    break;
> -  case 22:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D22;
> -    case ARM::SPRRegClassID: return ARM::S22;
> -    }
> -    break;
> -  case 23:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D23;
> -    case ARM::SPRRegClassID: return ARM::S23;
> -    }
> -    break;
> -  case 24:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D24;
> -    case ARM::SPRRegClassID: return ARM::S24;
> -    }
> -    break;
> -  case 25:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D25;
> -    case ARM::SPRRegClassID: return ARM::S25;
> -    }
> -    break;
> -  case 26:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D26;
> -    case ARM::SPRRegClassID: return ARM::S26;
> -    }
> -    break;
> -  case 27:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D27;
> -    case ARM::SPRRegClassID: return ARM::S27;
> -    }
> -    break;
> -  case 28:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D28;
> -    case ARM::SPRRegClassID: return ARM::S28;
> -    }
> -    break;
> -  case 29:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D29;
> -    case ARM::SPRRegClassID: return ARM::S29;
> -    }
> -    break;
> -  case 30:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D30;
> -    case ARM::SPRRegClassID: return ARM::S30;
> -    }
> -    break;
> -  case 31:
> -    switch (RegClassID) {
> -    case ARM::DPRRegClassID: return ARM::D31;
> -    case ARM::SPRRegClassID: return ARM::S31;
> -    }
> -    break;
> -  }
> -  DEBUG(errs() << "Invalid (RegClassID, RawRegister) combination\n");
> -  // Encoding error.  Mark the builder with error code != 0.
> -  B->SetErr(-1);
> -  return 0;
> -}
> -
> -///////////////////////////////
> -//                           //
> -//     Utility Functions     //
> -//                           //
> -///////////////////////////////
> -
> -// Extract/Decode Rd: Inst{15-12}.
> -static inline unsigned decodeRd(uint32_t insn) {
> -  return (insn >> ARMII::RegRdShift) & ARMII::GPRRegMask;
> -}
> -
> -// Extract/Decode Rn: Inst{19-16}.
> -static inline unsigned decodeRn(uint32_t insn) {
> -  return (insn >> ARMII::RegRnShift) & ARMII::GPRRegMask;
> -}
> -
> -// Extract/Decode Rm: Inst{3-0}.
> -static inline unsigned decodeRm(uint32_t insn) {
> -  return (insn & ARMII::GPRRegMask);
> -}
> -
> -// Extract/Decode Rs: Inst{11-8}.
> -static inline unsigned decodeRs(uint32_t insn) {
> -  return (insn >> ARMII::RegRsShift) & ARMII::GPRRegMask;
> -}
> -
> -static inline unsigned getCondField(uint32_t insn) {
> -  return (insn >> ARMII::CondShift);
> -}
> -
> -static inline unsigned getIBit(uint32_t insn) {
> -  return (insn >> ARMII::I_BitShift) & 1;
> -}
> -
> -static inline unsigned getAM3IBit(uint32_t insn) {
> -  return (insn >> ARMII::AM3_I_BitShift) & 1;
> -}
> -
> -static inline unsigned getPBit(uint32_t insn) {
> -  return (insn >> ARMII::P_BitShift) & 1;
> -}
> -
> -static inline unsigned getUBit(uint32_t insn) {
> -  return (insn >> ARMII::U_BitShift) & 1;
> -}
> -
> -static inline unsigned getPUBits(uint32_t insn) {
> -  return (insn >> ARMII::U_BitShift) & 3;
> -}
> -
> -static inline unsigned getSBit(uint32_t insn) {
> -  return (insn >> ARMII::S_BitShift) & 1;
> -}
> -
> -static inline unsigned getWBit(uint32_t insn) {
> -  return (insn >> ARMII::W_BitShift) & 1;
> -}
> -
> -static inline unsigned getDBit(uint32_t insn) {
> -  return (insn >> ARMII::D_BitShift) & 1;
> -}
> -
> -static inline unsigned getNBit(uint32_t insn) {
> -  return (insn >> ARMII::N_BitShift) & 1;
> -}
> -
> -static inline unsigned getMBit(uint32_t insn) {
> -  return (insn >> ARMII::M_BitShift) & 1;
> -}
> -
> -// See A8.4 Shifts applied to a register.
> -//     A8.4.2 Register controlled shifts.
> -//
> -// getShiftOpcForBits - getShiftOpcForBits translates from the ARM encoding bits
> -// into llvm enums for shift opcode.  The API clients should pass in the value
> -// encoded with two bits, so the assert stays to signal a wrong API usage.
> -//
> -// A8-12: DecodeRegShift()
> -static inline ARM_AM::ShiftOpc getShiftOpcForBits(unsigned bits) {
> -  switch (bits) {
> -  default: assert(0 && "No such value"); return ARM_AM::no_shift;
> -  case 0:  return ARM_AM::lsl;
> -  case 1:  return ARM_AM::lsr;
> -  case 2:  return ARM_AM::asr;
> -  case 3:  return ARM_AM::ror;
> -  }
> -}
> -
> -// See A8.4 Shifts applied to a register.
> -//     A8.4.1 Constant shifts.
> -//
> -// getImmShiftSE - getImmShiftSE translates from the raw ShiftOpc and raw Imm5
> -// encodings into the intended ShiftOpc and shift amount.
> -//
> -// A8-11: DecodeImmShift()
> -static inline void getImmShiftSE(ARM_AM::ShiftOpc &ShOp, unsigned &ShImm) {
> -  if (ShImm != 0)
> -    return;
> -  switch (ShOp) {
> -  case ARM_AM::no_shift:
> -  case ARM_AM::rrx:
> -    break;
> -  case ARM_AM::lsl:
> -    ShOp = ARM_AM::no_shift;
> -    break;
> -  case ARM_AM::lsr:
> -  case ARM_AM::asr:
> -    ShImm = 32;
> -    break;
> -  case ARM_AM::ror:
> -    ShOp = ARM_AM::rrx;
> -    break;
> -  }
> -}
> -
> -// getAMSubModeForBits - getAMSubModeForBits translates from the ARM encoding
> -// bits Inst{24-23} (P(24) and U(23)) into llvm enums for AMSubMode.  The API
> -// clients should pass in the value encoded with two bits, so the assert stays
> -// to signal a wrong API usage.
> -static inline ARM_AM::AMSubMode getAMSubModeForBits(unsigned bits) {
> -  switch (bits) {
> -  default: assert(0 && "No such value"); return ARM_AM::bad_am_submode;
> -  case 1:  return ARM_AM::ia;   // P=0 U=1
> -  case 3:  return ARM_AM::ib;   // P=1 U=1
> -  case 0:  return ARM_AM::da;   // P=0 U=0
> -  case 2:  return ARM_AM::db;   // P=1 U=0
> -  }
> -}
> -
> -////////////////////////////////////////////
> -//                                        //
> -//    Disassemble function definitions    //
> -//                                        //
> -////////////////////////////////////////////
> -
> -/// There is a separate Disassemble*Frm function entry for disassembly of an ARM
> -/// instr into a list of MCOperands in the appropriate order, with possible dst,
> -/// followed by possible src(s).
> -///
> -/// The processing of the predicate, and the 'S' modifier bit, if MI modifies
> -/// the CPSR, is factored into ARMBasicMCBuilder's method named
> -/// TryPredicateAndSBitModifier.
> -
> -static bool DisassemblePseudo(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO) {
> -
> -  assert(0 && "Unexpected pseudo instruction!");
> -  return false;
> -}
> -
> -// A8.6.94 MLA
> -// if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE;
> -//
> -// A8.6.105 MUL
> -// if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
> -//
> -// A8.6.246 UMULL
> -// if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
> -// if dHi == dLo then UNPREDICTABLE;
> -static bool BadRegsMulFrm(unsigned Opcode, uint32_t insn) {
> -  unsigned R19_16 = slice(insn, 19, 16);
> -  unsigned R15_12 = slice(insn, 15, 12);
> -  unsigned R11_8  = slice(insn, 11, 8);
> -  unsigned R3_0   = slice(insn, 3, 0);
> -  switch (Opcode) {
> -  default:
> -    // Did we miss an opcode?
> -    DEBUG(errs() << "BadRegsMulFrm: unexpected opcode!");
> -    return false;
> -  case ARM::MLA:     case ARM::MLS:     case ARM::SMLABB:  case ARM::SMLABT:
> -  case ARM::SMLATB:  case ARM::SMLATT:  case ARM::SMLAWB:  case ARM::SMLAWT:
> -  case ARM::SMMLA:   case ARM::SMMLAR:  case ARM::SMMLS:   case ARM::SMMLSR:
> -  case ARM::USADA8:
> -    if (R19_16 == 15 || R15_12 == 15 || R11_8 == 15 || R3_0 == 15)
> -      return true;
> -    return false;
> -  case ARM::MUL:     case ARM::SMMUL:   case ARM::SMMULR:
> -  case ARM::SMULBB:  case ARM::SMULBT:  case ARM::SMULTB:  case ARM::SMULTT:
> -  case ARM::SMULWB:  case ARM::SMULWT:  case ARM::SMUAD:   case ARM::SMUADX:
> -  // A8.6.167 SMLAD & A8.6.172 SMLSD
> -  case ARM::SMLAD:   case ARM::SMLADX:  case ARM::SMLSD:   case ARM::SMLSDX:
> -  case ARM::USAD8:
> -    if (R19_16 == 15 || R11_8 == 15 || R3_0 == 15)
> -      return true;
> -    return false;
> -  case ARM::SMLAL:   case ARM::SMULL:   case ARM::UMAAL:   case ARM::UMLAL:
> -  case ARM::UMULL:
> -  case ARM::SMLALBB: case ARM::SMLALBT: case ARM::SMLALTB: case ARM::SMLALTT:
> -  case ARM::SMLALD:  case ARM::SMLALDX: case ARM::SMLSLD:  case ARM::SMLSLDX:
> -    if (R19_16 == 15 || R15_12 == 15 || R11_8 == 15 || R3_0 == 15)
> -      return true;
> -    if (R19_16 == R15_12)
> -      return true;
> -    return false;;
> -  }
> -}
> -
> -// Multiply Instructions.
> -// MLA, MLS, SMLABB, SMLABT, SMLATB, SMLATT, SMLAWB, SMLAWT, SMMLA, SMMLAR,
> -// SMMLS, SMMLAR, SMLAD, SMLADX, SMLSD, SMLSDX, and USADA8 (for convenience):
> -//     Rd{19-16} Rn{3-0} Rm{11-8} Ra{15-12}
> -// But note that register checking for {SMLAD, SMLADX, SMLSD, SMLSDX} is
> -// only for {d, n, m}.
> -//
> -// MUL, SMMUL, SMMULR, SMULBB, SMULBT, SMULTB, SMULTT, SMULWB, SMULWT, SMUAD,
> -// SMUADX, and USAD8 (for convenience):
> -//     Rd{19-16} Rn{3-0} Rm{11-8}
> -//
> -// SMLAL, SMULL, UMAAL, UMLAL, UMULL, SMLALBB, SMLALBT, SMLALTB, SMLALTT,
> -// SMLALD, SMLADLX, SMLSLD, SMLSLDX:
> -//     RdLo{15-12} RdHi{19-16} Rn{3-0} Rm{11-8}
> -//
> -// The mapping of the multiply registers to the "regular" ARM registers, where
> -// there are convenience decoder functions, is:
> -//
> -// Inst{15-12} => Rd
> -// Inst{19-16} => Rn
> -// Inst{3-0} => Rm
> -// Inst{11-8} => Rs
> -static bool DisassembleMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  unsigned short NumDefs = MCID.getNumDefs();
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumDefs > 0 && "NumDefs should be greater than 0 for MulFrm");
> -  assert(NumOps >= 3
> -         && OpInfo[0].RegClass == ARM::GPRRegClassID
> -         && OpInfo[1].RegClass == ARM::GPRRegClassID
> -         && OpInfo[2].RegClass == ARM::GPRRegClassID
> -         && "Expect three register operands");
> -
> -  // Sanity check for the register encodings.
> -  if (BadRegsMulFrm(Opcode, insn))
> -    return false;
> -
> -  // Instructions with two destination registers have RdLo{15-12} first.
> -  if (NumDefs == 2) {
> -    assert(NumOps >= 4 && OpInfo[3].RegClass == ARM::GPRRegClassID &&
> -           "Expect 4th register operand");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // The destination register: RdHi{19-16} or Rd{19-16}.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -
> -  // The two src regsiters: Rn{3-0}, then Rm{11-8}.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRs(insn))));
> -  OpIdx += 3;
> -
> -  // Many multiply instructions (e.g., MLA) have three src registers.
> -  // The third register operand is Ra{15-12}.
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// Helper routines for disassembly of coprocessor instructions.
> -
> -static bool LdStCopOpcode(unsigned Opcode) {
> -  if ((Opcode >= ARM::LDC2L_OFFSET && Opcode <= ARM::LDC_PRE) ||
> -      (Opcode >= ARM::STC2L_OFFSET && Opcode <= ARM::STC_PRE))
> -    return true;
> -  return false;
> -}
> -static bool CoprocessorOpcode(unsigned Opcode) {
> -  if (LdStCopOpcode(Opcode))
> -    return true;
> -
> -  switch (Opcode) {
> -  default:
> -    return false;
> -  case ARM::CDP:  case ARM::CDP2:
> -  case ARM::MCR:  case ARM::MCR2:  case ARM::MRC:  case ARM::MRC2:
> -  case ARM::MCRR: case ARM::MCRR2: case ARM::MRRC: case ARM::MRRC2:
> -    return true;
> -  }
> -}
> -static inline unsigned GetCoprocessor(uint32_t insn) {
> -  return slice(insn, 11, 8);
> -}
> -static inline unsigned GetCopOpc1(uint32_t insn, bool CDP) {
> -  return CDP ? slice(insn, 23, 20) : slice(insn, 23, 21);
> -}
> -static inline unsigned GetCopOpc2(uint32_t insn) {
> -  return slice(insn, 7, 5);
> -}
> -static inline unsigned GetCopOpc(uint32_t insn) {
> -  return slice(insn, 7, 4);
> -}
> -// Most of the operands are in immediate forms, except Rd and Rn, which are ARM
> -// core registers.
> -//
> -// CDP, CDP2:                cop opc1 CRd CRn CRm opc2
> -//
> -// MCR, MCR2, MRC, MRC2:     cop opc1 Rd CRn CRm opc2
> -//
> -// MCRR, MCRR2, MRRC, MRRc2: cop opc Rd Rn CRm
> -//
> -// LDC_OFFSET, LDC_PRE, LDC_POST: cop CRd Rn R0 [+/-]imm8:00
> -// and friends
> -// STC_OFFSET, STC_PRE, STC_POST: cop CRd Rn R0 [+/-]imm8:00
> -// and friends
> -//                                        <-- addrmode2 -->
> -//
> -// LDC_OPTION:                    cop CRd Rn imm8
> -// and friends
> -// STC_OPTION:                    cop CRd Rn imm8
> -// and friends
> -//
> -static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 4 && "Num of operands >= 4 for coprocessor instr");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -  // A8.6.92
> -  // if coproc == '101x' then SEE "Advanced SIMD and VFP"
> -  // But since the special instructions have more explicit encoding bits
> -  // specified, if coproc == 10 or 11, we should reject it as invalid.
> -  unsigned coproc = GetCoprocessor(insn);
> -  if ((Opcode == ARM::MCR || Opcode == ARM::MCRR ||
> -       Opcode == ARM::MRC || Opcode == ARM::MRRC) &&
> -      (coproc == 10 || coproc == 11)) {
> -    DEBUG(errs() << "Encoding error: coproc == 10 or 11 for MCR[R]/MR[R]C\n");
> -    return false;
> -  }
> -
> -  bool OneCopOpc = (Opcode == ARM::MCRR || Opcode == ARM::MCRR2 ||
> -                    Opcode == ARM::MRRC || Opcode == ARM::MRRC2);
> -
> -  // CDP/CDP2 has no GPR operand; the opc1 operand is also wider (Inst{23-20}).
> -  bool NoGPR = (Opcode == ARM::CDP || Opcode == ARM::CDP2);
> -  bool LdStCop = LdStCopOpcode(Opcode);
> -  bool RtOut = (Opcode == ARM::MRC || Opcode == ARM::MRC2);
> -
> -  OpIdx = 0;
> -
> -  if (RtOut) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    ++OpIdx;
> -  }
> -  MI.addOperand(MCOperand::CreateImm(coproc));
> -  ++OpIdx;
> -
> -  if (LdStCop) {
> -    // Unindex if P:W = 0b00 --> _OPTION variant
> -    unsigned PW = getPBit(insn) << 1 | getWBit(insn);
> -
> -    MI.addOperand(MCOperand::CreateImm(decodeRd(insn)));
> -
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    OpIdx += 2;
> -
> -    if (PW) {
> -      MI.addOperand(MCOperand::CreateReg(0));
> -      ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> -      const MCInstrDesc &MCID = ARMInsts[Opcode];
> -      unsigned IndexMode =
> -                 (MCID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
> -      unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2,
> -                                          ARM_AM::no_shift, IndexMode);
> -      MI.addOperand(MCOperand::CreateImm(Offset));
> -      OpIdx += 2;
> -    } else {
> -      MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 0)));
> -      ++OpIdx;
> -    }
> -  } else {
> -    MI.addOperand(MCOperand::CreateImm(OneCopOpc ? GetCopOpc(insn)
> -                                                 : GetCopOpc1(insn, NoGPR)));
> -    ++OpIdx;
> -
> -    if (!RtOut) {
> -      MI.addOperand(NoGPR ? MCOperand::CreateImm(decodeRd(insn))
> -                          : MCOperand::CreateReg(
> -                                getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                decodeRd(insn))));
> -      ++OpIdx;
> -    }
> -
> -    MI.addOperand(OneCopOpc ? MCOperand::CreateReg(
> -                                getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                decodeRn(insn)))
> -                            : MCOperand::CreateImm(decodeRn(insn)));
> -
> -    MI.addOperand(MCOperand::CreateImm(decodeRm(insn)));
> -
> -    OpIdx += 2;
> -
> -    if (!OneCopOpc) {
> -      MI.addOperand(MCOperand::CreateImm(GetCopOpc2(insn)));
> -      ++OpIdx;
> -    }
> -  }
> -
> -  return true;
> -}
> -
> -// Branch Instructions.
> -// BL: SignExtend(Imm24:'00', 32)
> -// Bcc, BL_pred: SignExtend(Imm24:'00', 32) Pred0 Pred1
> -// SMC: ZeroExtend(imm4, 32)
> -// SVC: ZeroExtend(Imm24, 32)
> -//
> -// Various coprocessor instructions are assigned BrFrm arbitrarily.
> -// Delegates to DisassembleCoprocessor() helper function.
> -//
> -// MRS/MRSsys: Rd
> -// MSR/MSRsys: Rm mask=Inst{19-16}
> -// BXJ:        Rm
> -// MSRi/MSRsysi: so_imm
> -// SRS: mode_imm
> -// RFE: Rn
> -static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  if (CoprocessorOpcode(Opcode))
> -    return DisassembleCoprocessor(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  // MRS and MRSsys take one GPR reg Rd.
> -  if (Opcode == ARM::MRS || Opcode == ARM::MRSsys) {
> -    assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -  // BXJ takes one GPR reg Rm.
> -  if (Opcode == ARM::BXJ) {
> -    assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -  // MSR take a mask, followed by one GPR reg Rm. The mask contains the R Bit in
> -  // bit 4, and the special register fields in bits 3-0.
> -  if (Opcode == ARM::MSR) {
> -    assert(NumOps >= 1 && OpInfo[1].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 22, 22) << 4 /* R Bit */ |
> -                                       slice(insn, 19, 16) /* Special Reg */ ));
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -  // MSRi take a mask, followed by one so_imm operand. The mask contains the
> -  // R Bit in bit 4, and the special register fields in bits 3-0.
> -  if (Opcode == ARM::MSRi) {
> -    // A5.2.11 MSR (immediate), and hints & B6.1.6 MSR (immediate)
> -    // The hints instructions have more specific encodings, so if mask == 0,
> -    // we should reject this as an invalid instruction.
> -    if (slice(insn, 19, 16) == 0)
> -      return false;
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 22, 22) << 4 /* R Bit */ |
> -                                       slice(insn, 19, 16) /* Special Reg */ ));
> -    // SOImm is 4-bit rotate amount in bits 11-8 with 8-bit imm in bits 7-0.
> -    // A5.2.4 Rotate amount is twice the numeric value of Inst{11-8}.
> -    // See also ARMAddressingModes.h: getSOImmValImm() and getSOImmValRot().
> -    unsigned Rot = (insn >> ARMII::SoRotImmShift) & 0xF;
> -    unsigned Imm = insn & 0xFF;
> -    MI.addOperand(MCOperand::CreateImm(ARM_AM::rotr32(Imm, 2*Rot)));
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -  if (Opcode == ARM::SRSDA || Opcode == ARM::SRSDB ||
> -      Opcode == ARM::SRSIA || Opcode == ARM::SRSIB ||
> -      Opcode == ARM::SRSDA_UPD || Opcode == ARM::SRSDB_UPD ||
> -      Opcode == ARM::SRSIA_UPD || Opcode == ARM::SRSIB_UPD) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -  if (Opcode == ARM::RFEDA || Opcode == ARM::RFEDB ||
> -      Opcode == ARM::RFEIA || Opcode == ARM::RFEIB ||
> -      Opcode == ARM::RFEDA_UPD || Opcode == ARM::RFEDB_UPD ||
> -      Opcode == ARM::RFEIA_UPD || Opcode == ARM::RFEIB_UPD) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  assert((Opcode == ARM::Bcc || Opcode == ARM::BL || Opcode == ARM::BL_pred
> -          || Opcode == ARM::SMC || Opcode == ARM::SVC) &&
> -         "Unexpected Opcode");
> -
> -  assert(NumOps >= 1 && OpInfo[0].RegClass < 0 && "Imm operand expected");
> -
> -  int Imm32 = 0;
> -  if (Opcode == ARM::SMC) {
> -    // ZeroExtend(imm4, 32) where imm24 = Inst{3-0}.
> -    Imm32 = slice(insn, 3, 0);
> -  } else if (Opcode == ARM::SVC) {
> -    // ZeroExtend(imm24, 32) where imm24 = Inst{23-0}.
> -    Imm32 = slice(insn, 23, 0);
> -  } else {
> -    // SignExtend(imm24:'00', 32) where imm24 = Inst{23-0}.
> -    unsigned Imm26 = slice(insn, 23, 0) << 2;
> -    //Imm32 = signextend<signed int, 26>(Imm26);
> -    Imm32 = SignExtend32<26>(Imm26);
> -  }
> -
> -  MI.addOperand(MCOperand::CreateImm(Imm32));
> -  NumOpsAdded = 1;
> -
> -  return true;
> -}
> -
> -// Misc. Branch Instructions.
> -// BX_RET, MOVPCLR
> -// BLX, BLX_pred, BX, BX_pred
> -// BLXi
> -static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // BX_RET and MOVPCLR have only two predicate operands; do an early return.
> -  if (Opcode == ARM::BX_RET || Opcode == ARM::MOVPCLR)
> -    return true;
> -
> -  // BLX and BX take one GPR reg.
> -  if (Opcode == ARM::BLX || Opcode == ARM::BLX_pred ||
> -      Opcode == ARM::BX || Opcode == ARM::BX_pred) {
> -    assert(NumOps >= 1 && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    OpIdx = 1;
> -    return true;
> -  }
> -
> -  // BLXi takes imm32 (the PC offset).
> -  if (Opcode == ARM::BLXi) {
> -    assert(NumOps >= 1 && OpInfo[0].RegClass < 0 && "Imm operand expected");
> -    // SignExtend(imm24:H:'0', 32) where imm24 = Inst{23-0} and H = Inst{24}.
> -    unsigned Imm26 = slice(insn, 23, 0) << 2 | slice(insn, 24, 24) << 1;
> -    int Imm32 = SignExtend32<26>(Imm26);
> -    MI.addOperand(MCOperand::CreateImm(Imm32));
> -    OpIdx = 1;
> -    return true;
> -  }
> -
> -  return false;
> -}
> -
> -static inline bool getBFCInvMask(uint32_t insn, uint32_t &mask) {
> -  uint32_t lsb = slice(insn, 11, 7);
> -  uint32_t msb = slice(insn, 20, 16);
> -  uint32_t Val = 0;
> -  if (msb < lsb) {
> -    DEBUG(errs() << "Encoding error: msb < lsb\n");
> -    return false;
> -  }
> -
> -  for (uint32_t i = lsb; i <= msb; ++i)
> -    Val |= (1 << i);
> -  mask = ~Val;
> -  return true;
> -}
> -
> -// Standard data-processing instructions allow PC as a register specifier,
> -// but we should reject other DPFrm instructions with PC as registers.
> -static bool BadRegsDPFrm(unsigned Opcode, uint32_t insn) {
> -  switch (Opcode) {
> -  default:
> -    // Did we miss an opcode?
> -    if (decodeRd(insn) == 15 || decodeRn(insn) == 15 || decodeRm(insn) == 15) {
> -      DEBUG(errs() << "DPFrm with bad reg specifier(s)\n");
> -      return true;
> -    }
> -  case ARM::ADCrr:  case ARM::ADDSrr: case ARM::ADDrr:  case ARM::ANDrr:
> -  case ARM::BICrr:  case ARM::CMNzrr: case ARM::CMPrr:  case ARM::EORrr:
> -  case ARM::ORRrr:  case ARM::RSBrr:  case ARM::RSCrr:  case ARM::SBCrr:
> -  case ARM::SUBSrr: case ARM::SUBrr:  case ARM::TEQrr:  case ARM::TSTrr:
> -    return false;
> -  }
> -}
> -
> -// A major complication is the fact that some of the saturating add/subtract
> -// operations have Rd Rm Rn, instead of the "normal" Rd Rn Rm.
> -// They are QADD, QDADD, QDSUB, and QSUB.
> -static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  unsigned short NumDefs = MCID.getNumDefs();
> -  bool isUnary = isUnaryDP(MCID.TSFlags);
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // Disassemble register def if there is one.
> -  if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Now disassemble the src operands.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  // Special-case handling of BFC/BFI/SBFX/UBFX.
> -  if (Opcode == ARM::BFC || Opcode == ARM::BFI) {
> -    // A8.6.17 BFC & A8.6.18 BFI
> -    // Sanity check Rd.
> -    if (decodeRd(insn) == 15)
> -      return false;
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    if (Opcode == ARM::BFI) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         decodeRm(insn))));
> -      ++OpIdx;
> -    }
> -    uint32_t mask = 0;
> -    if (!getBFCInvMask(insn, mask))
> -      return false;
> -
> -    MI.addOperand(MCOperand::CreateImm(mask));
> -    OpIdx += 2;
> -    return true;
> -  }
> -  if (Opcode == ARM::SBFX || Opcode == ARM::UBFX) {
> -    // Sanity check Rd and Rm.
> -    if (decodeRd(insn) == 15 || decodeRm(insn) == 15)
> -      return false;
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 7)));
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 16)));
> -    OpIdx += 3;
> -    return true;
> -  }
> -
> -  bool RmRn = (Opcode == ARM::QADD || Opcode == ARM::QDADD ||
> -               Opcode == ARM::QDSUB || Opcode == ARM::QSUB);
> -
> -  // BinaryDP has an Rn operand.
> -  if (!isUnary) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, ARM::GPRRegClassID,
> -                                    RmRn ? decodeRm(insn) : decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // If this is a two-address operand, skip it, e.g., MOVCCr operand 1.
> -  if (isUnary && (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)) {
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  // Now disassemble operand 2.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  if (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
> -    // We have a reg/reg form.
> -    // Assert disabled because saturating operations, e.g., A8.6.127 QASX, are
> -    // routed here as well.
> -    // assert(getIBit(insn) == 0 && "I_Bit != '0' reg/reg form");
> -    if (BadRegsDPFrm(Opcode, insn))
> -      return false;
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, ARM::GPRRegClassID,
> -                                    RmRn? decodeRn(insn) : decodeRm(insn))));
> -    ++OpIdx;
> -  } else if (Opcode == ARM::MOVi16 || Opcode == ARM::MOVTi16) {
> -    // These two instructions don't allow d as 15.
> -    if (decodeRd(insn) == 15)
> -      return false;
> -    // We have an imm16 = imm4:imm12 (imm4=Inst{19:16}, imm12 = Inst{11:0}).
> -    assert(getIBit(insn) == 1 && "I_Bit != '1' reg/imm form");
> -    unsigned Imm16 = slice(insn, 19, 16) << 12 | slice(insn, 11, 0);
> -    if (!B->tryAddingSymbolicOperand(Imm16, 4, MI))
> -      MI.addOperand(MCOperand::CreateImm(Imm16));
> -    ++OpIdx;
> -  } else {
> -    // We have a reg/imm form.
> -    // SOImm is 4-bit rotate amount in bits 11-8 with 8-bit imm in bits 7-0.
> -    // A5.2.4 Rotate amount is twice the numeric value of Inst{11-8}.
> -    // See also ARMAddressingModes.h: getSOImmValImm() and getSOImmValRot().
> -    assert(getIBit(insn) == 1 && "I_Bit != '1' reg/imm form");
> -    unsigned Rot = (insn >> ARMII::SoRotImmShift) & 0xF;
> -    unsigned Imm = insn & 0xFF;
> -    MI.addOperand(MCOperand::CreateImm(ARM_AM::rotr32(Imm, 2*Rot)));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -static bool DisassembleDPSoRegRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  unsigned short NumDefs = MCID.getNumDefs();
> -  bool isUnary = isUnaryDP(MCID.TSFlags);
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // Disassemble register def if there is one.
> -  if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble the src operands.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  // BinaryDP has an Rn operand.
> -  if (!isUnary) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // If this is a two-address operand, skip it, e.g., MOVCCs operand 1.
> -  if (isUnary && (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)) {
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble operand 2, which consists of three components.
> -  if (OpIdx + 2 >= NumOps)
> -    return false;
> -
> -  assert((OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) &&
> -         (OpInfo[OpIdx+1].RegClass == ARM::GPRRegClassID) &&
> -         (OpInfo[OpIdx+2].RegClass < 0) &&
> -         "Expect 3 reg operands");
> -
> -  // Register-controlled shifts have Inst{7} = 0 and Inst{4} = 1.
> -  unsigned Rs = slice(insn, 4, 4);
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -  if (Rs) {
> -    // If Inst{7} != 0, we should reject this insn as an invalid encoding.
> -    if (slice(insn, 7, 7))
> -      return false;
> -
> -    // A8.6.3 ADC (register-shifted register)
> -    // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
> -    // 
> -    // This also accounts for shift instructions (register) where, fortunately,
> -    // Inst{19-16} = 0b0000.
> -    // A8.6.89 LSL (register)
> -    // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
> -    if (decodeRd(insn) == 15 || decodeRn(insn) == 15 ||
> -        decodeRm(insn) == 15 || decodeRs(insn) == 15)
> -      return false;
> -    
> -    // Register-controlled shifts: [Rm, Rs, shift].
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRs(insn))));
> -    // Inst{6-5} encodes the shift opcode.
> -    ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
> -    MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, 0)));
> -  } else {
> -    // Constant shifts: [Rm, reg0, shift_imm].
> -    MI.addOperand(MCOperand::CreateReg(0)); // NoRegister
> -    // Inst{6-5} encodes the shift opcode.
> -    ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
> -    // Inst{11-7} encodes the imm5 shift amount.
> -    unsigned ShImm = slice(insn, 11, 7);
> -
> -    // A8.4.1.  Possible rrx or shift amount of 32...
> -    getImmShiftSE(ShOp, ShImm);
> -    MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShImm)));
> -  }
> -  OpIdx += 3;
> -
> -  return true;
> -}
> -
> -static bool DisassembleDPSoRegImmFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  unsigned short NumDefs = MCID.getNumDefs();
> -  bool isUnary = isUnaryDP(MCID.TSFlags);
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // Disassemble register def if there is one.
> -  if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble the src operands.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  // BinaryDP has an Rn operand.
> -  if (!isUnary) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // If this is a two-address operand, skip it, e.g., MOVCCs operand 1.
> -  if (isUnary && (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)) {
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble operand 2, which consists of two components.
> -  if (OpIdx + 1 >= NumOps)
> -    return false;
> -
> -  assert((OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) &&
> -         (OpInfo[OpIdx+1].RegClass < 0) &&
> -         "Expect 2 reg operands");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -
> -  // Inst{6-5} encodes the shift opcode.
> -  ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
> -  // Inst{11-7} encodes the imm5 shift amount.
> -  unsigned ShImm = slice(insn, 11, 7);
> -
> -  // A8.4.1.  Possible rrx or shift amount of 32...
> -  getImmShiftSE(ShOp, ShImm);
> -  MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShImm)));
> -
> -  OpIdx += 2;
> -
> -  return true;
> -}
> -
> -
> -static bool BadRegsLdStFrm(unsigned Opcode, uint32_t insn, bool Store, bool WBack,
> -                           bool Imm) {
> -  const StringRef Name = ARMInsts[Opcode].Name;
> -  unsigned Rt = decodeRd(insn);
> -  unsigned Rn = decodeRn(insn);
> -  unsigned Rm = decodeRm(insn);
> -  unsigned P  = getPBit(insn);
> -  unsigned W  = getWBit(insn);
> -
> -  if (Store) {
> -    // Only STR (immediate, register) allows PC as the source.
> -    if (Name.startswith("STRB") && Rt == 15) {
> -      DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
> -      return true;
> -    }
> -    if (WBack && (Rn == 15 || Rn == Rt)) {
> -      DEBUG(errs() << "if wback && (n == 15 || n == t) then UNPREDICTABLE\n");
> -      return true;
> -    }
> -    if (!Imm && Rm == 15) {
> -      DEBUG(errs() << "if m == 15 then UNPREDICTABLE\n");
> -      return true;
> -    }
> -  } else {
> -    // Only LDR (immediate, register) allows PC as the destination.
> -    if (Name.startswith("LDRB") && Rt == 15) {
> -      DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
> -      return true;
> -    }
> -    if (Imm) {
> -      // Immediate
> -      if (Rn == 15) {
> -        // The literal form must be in offset mode; it's an encoding error
> -        // otherwise.
> -        if (!(P == 1 && W == 0)) {
> -          DEBUG(errs() << "Ld literal form with !(P == 1 && W == 0)\n");
> -          return true;
> -        }
> -        // LDRB (literal) does not allow PC as the destination.
> -        if (Opcode != ARM::LDRi12 && Rt == 15) {
> -          DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
> -          return true;
> -        }
> -      } else {
> -        // Write back while Rn == Rt does not make sense.
> -        if (WBack && (Rn == Rt)) {
> -          DEBUG(errs() << "if wback && n == t then UNPREDICTABLE\n");
> -          return true;
> -        }
> -      }
> -    } else {
> -      // Register
> -      if (Rm == 15) {
> -        DEBUG(errs() << "if m == 15 then UNPREDICTABLE\n");
> -        return true;
> -      }
> -      if (WBack && (Rn == 15 || Rn == Rt)) {
> -        DEBUG(errs() << "if wback && (n == 15 || n == t) then UNPREDICTABLE\n");
> -        return true;
> -      }
> -    }
> -  }
> -  return false;
> -}
> -
> -static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, bool isStore, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  bool isPrePost = isPrePostLdSt(MCID.TSFlags);
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  if (!OpInfo) return false;
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(((!isStore && MCID.getNumDefs() > 0) ||
> -          (isStore && (MCID.getNumDefs() == 0 || isPrePost)))
> -         && "Invalid arguments");
> -
> -  // Operand 0 of a pre- and post-indexed store is the address base writeback.
> -  if (isPrePost && isStore) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble the dst/src operand.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -         "Reg operand expected");
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  ++OpIdx;
> -
> -  // After dst of a pre- and post-indexed load is the address base writeback.
> -  if (isPrePost && !isStore) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble the base operand.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -         "Reg operand expected");
> -  assert((!isPrePost || (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1))
> -         && "Index mode or tied_to operand expected");
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  ++OpIdx;
> -
> -  // For reg/reg form, base reg is followed by +/- reg shop imm.
> -  // For immediate form, it is followed by +/- imm12.
> -  // See also ARMAddressingModes.h (Addressing Mode #2).
> -  if (OpIdx + 1 >= NumOps)
> -    return false;
> -
> -  if (BadRegsLdStFrm(Opcode, insn, isStore, isPrePost, getIBit(insn)==0))
> -    return false;
> -
> -  ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> -  unsigned IndexMode =
> -               (MCID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
> -  if (getIBit(insn) == 0) {
> -    // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
> -    // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
> -    // been populated.
> -    if (isPrePost) {
> -      MI.addOperand(MCOperand::CreateReg(0));
> -      OpIdx += 1;
> -    }
> -
> -    unsigned Imm12 = slice(insn, 11, 0);
> -    if (Opcode == ARM::LDRBi12 || Opcode == ARM::LDRi12 ||
> -        Opcode == ARM::STRBi12 || Opcode == ARM::STRi12) {
> -      // Disassemble the 12-bit immediate offset, which is the second operand in
> -      // $addrmode_imm12 => (ops GPR:$base, i32imm:$offsimm).
> -      int Offset = AddrOpcode == ARM_AM::add ? 1 * Imm12 : -1 * Imm12;
> -      MI.addOperand(MCOperand::CreateImm(Offset));
> -    } else {
> -      // Disassemble the 12-bit immediate offset, which is the second operand in
> -      // $am2offset => (ops GPR, i32imm).
> -      unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift,
> -                                          IndexMode);
> -      MI.addOperand(MCOperand::CreateImm(Offset));
> -    }
> -    OpIdx += 1;
> -  } else {
> -    // If Inst{25} = 1 and Inst{4} != 0, we should reject this as invalid.
> -    if (slice(insn,4,4) == 1)
> -      return false;
> -
> -    // Disassemble the offset reg (Rm), shift type, and immediate shift length.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    // Inst{6-5} encodes the shift opcode.
> -    ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
> -    // Inst{11-7} encodes the imm5 shift amount.
> -    unsigned ShImm = slice(insn, 11, 7);
> -
> -    // A8.4.1.  Possible rrx or shift amount of 32...
> -    getImmShiftSE(ShOp, ShImm);
> -    MI.addOperand(MCOperand::CreateImm(
> -                    ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode)));
> -    OpIdx += 2;
> -  }
> -
> -  return true;
> -}
> -
> -static bool DisassembleLdFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  return DisassembleLdStFrm(MI, Opcode, insn, NumOps, NumOpsAdded, false, B);
> -}
> -
> -static bool DisassembleStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  return DisassembleLdStFrm(MI, Opcode, insn, NumOps, NumOpsAdded, true, B);
> -}
> -
> -static bool HasDualReg(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return false;
> -  case ARM::LDRD: case ARM::LDRD_PRE: case ARM::LDRD_POST:
> -  case ARM::STRD: case ARM::STRD_PRE: case ARM::STRD_POST:
> -    return true;
> -  }
> -}
> -
> -static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, bool isStore, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  bool isPrePost = isPrePostLdSt(MCID.TSFlags);
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  if (!OpInfo) return false;
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(((!isStore && MCID.getNumDefs() > 0) ||
> -          (isStore && (MCID.getNumDefs() == 0 || isPrePost)))
> -         && "Invalid arguments");
> -
> -  // Operand 0 of a pre- and post-indexed store is the address base writeback.
> -  if (isPrePost && isStore) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble the dst/src operand.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -         "Reg operand expected");
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  ++OpIdx;
> -
> -  // Fill in LDRD and STRD's second operand Rt operand.
> -  if (HasDualReg(Opcode)) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn) + 1)));
> -    ++OpIdx;
> -  }
> -
> -  // After dst of a pre- and post-indexed load is the address base writeback.
> -  if (isPrePost && !isStore) {
> -    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Disassemble the base operand.
> -  if (OpIdx >= NumOps)
> -    return false;
> -
> -  assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -         "Reg operand expected");
> -  assert((!isPrePost || (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1))
> -         && "Offset mode or tied_to operand expected");
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  ++OpIdx;
> -
> -  // For reg/reg form, base reg is followed by +/- reg.
> -  // For immediate form, it is followed by +/- imm8.
> -  if (OpIdx + 1 >= NumOps)
> -    return false;
> -
> -  unsigned IndexMode =
> -    (MCID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
> -  ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> -  if (getAM3IBit(insn) == 1) {
> -    // FIXME: Conditional while in the midst of refactoring addrmode3. Will
> -    // go away entirely when the rest are converted.
> -    if (Opcode != ARM::STRHTi && Opcode != ARM::LDRSBTi &&
> -        Opcode != ARM::LDRHTi && Opcode != ARM::LDRSHTi) {
> -      MI.addOperand(MCOperand::CreateReg(0));
> -      ++OpIdx;
> -    }
> -
> -    // Disassemble the 8-bit immediate offset (postidx_imm8).
> -    unsigned Imm4H = (insn >> ARMII::ImmHiShift) & 0xF;
> -    unsigned Imm4L = insn & 0xF;
> -    unsigned Offset;
> -    // FIXME: Remove the 'else' once done w/ addrmode3 refactor.
> -    if (Opcode == ARM::STRHTi || Opcode == ARM::LDRSBTi ||
> -        Opcode == ARM::LDRHTi || Opcode == ARM::LDRSHTi)
> -      Offset = (Imm4H << 4) | Imm4L | (getUBit(insn) << 8);
> -    else
> -      Offset = ARM_AM::getAM3Opc(AddrOpcode, (Imm4H << 4) | Imm4L,
> -                                 IndexMode);
> -
> -    MI.addOperand(MCOperand::CreateImm(Offset));
> -    ++OpIdx;
> -  } else {
> -    // Disassemble the offset reg (Rm).
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    // FIXME: Remove the 'else' once done w/ addrmode3 refactor.
> -    if (Opcode == ARM::STRHTr || Opcode == ARM::LDRSBTr ||
> -        Opcode == ARM::LDRHTr || Opcode == ARM::LDRSHTr)
> -      MI.addOperand(MCOperand::CreateImm(getUBit(insn)));
> -    else {
> -      unsigned Offset = ARM_AM::getAM3Opc(AddrOpcode, 0);
> -      MI.addOperand(MCOperand::CreateImm(Offset));
> -    }
> -    OpIdx += 2;
> -  }
> -
> -  return true;
> -}
> -
> -static bool DisassembleLdMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  return DisassembleLdStMiscFrm(MI, Opcode, insn, NumOps, NumOpsAdded, false,
> -                                B);
> -}
> -
> -static bool DisassembleStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  return DisassembleLdStMiscFrm(MI, Opcode, insn, NumOps, NumOpsAdded, true, B);
> -}
> -
> -// The algorithm for disassembly of LdStMulFrm is different from others because
> -// it explicitly populates the two predicate operands after the base register.
> -// After that, we need to populate the reglist with each affected register
> -// encoded as an MCOperand.
> -static bool DisassembleLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 4 && "LdStMulFrm expects NumOps >= 4");
> -  NumOpsAdded = 0;
> -
> -  unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
> -
> -  // Writeback to base, if necessary.
> -  if (Opcode == ARM::LDMIA_UPD || Opcode == ARM::STMIA_UPD ||
> -      Opcode == ARM::LDMDA_UPD || Opcode == ARM::STMDA_UPD ||
> -      Opcode == ARM::LDMDB_UPD || Opcode == ARM::STMDB_UPD ||
> -      Opcode == ARM::LDMIB_UPD || Opcode == ARM::STMIB_UPD) {
> -    MI.addOperand(MCOperand::CreateReg(Base));
> -    ++NumOpsAdded;
> -  }
> -
> -  // Add the base register operand.
> -  MI.addOperand(MCOperand::CreateReg(Base));
> -
> -  // Handling the two predicate operands before the reglist.
> -  int64_t CondVal = getCondField(insn);
> -  if (CondVal == 0xF)
> -    return false;
> -  MI.addOperand(MCOperand::CreateImm(CondVal));
> -  MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
> -
> -  NumOpsAdded += 3;
> -
> -  // Fill the variadic part of reglist.
> -  unsigned RegListBits = insn & ((1 << 16) - 1);
> -  for (unsigned i = 0; i < 16; ++i) {
> -    if ((RegListBits >> i) & 1) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         i)));
> -      ++NumOpsAdded;
> -    }
> -  }
> -
> -  return true;
> -}
> -
> -// LDREX, LDREXB, LDREXH: Rd Rn
> -// LDREXD:                Rd Rd+1 Rn
> -// STREX, STREXB, STREXH: Rd Rm Rn
> -// STREXD:                Rd Rm Rm+1 Rn
> -//
> -// SWP, SWPB:             Rd Rm Rn
> -static bool DisassembleLdStExFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2
> -         && OpInfo[0].RegClass == ARM::GPRRegClassID
> -         && OpInfo[1].RegClass == ARM::GPRRegClassID
> -         && "Expect 2 reg operands");
> -
> -  bool isStore = slice(insn, 20, 20) == 0;
> -  bool isDW = (Opcode == ARM::LDREXD || Opcode == ARM::STREXD);
> -
> -  // Add the destination operand.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  ++OpIdx;
> -
> -  // Store register Exclusive needs a source operand.
> -  if (isStore) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    ++OpIdx;
> -
> -    if (isDW) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         decodeRm(insn)+1)));
> -      ++OpIdx;
> -    }
> -  } else if (isDW) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRd(insn)+1)));
> -    ++OpIdx;
> -  }
> -
> -  // Finally add the pointer operand.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// Misc. Arithmetic Instructions.
> -// CLZ: Rd Rm
> -// PKHBT, PKHTB: Rd Rn Rm , LSL/ASR #imm5
> -// RBIT, REV, REV16, REVSH: Rd Rm
> -static bool DisassembleArithMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2
> -         && OpInfo[0].RegClass == ARM::GPRRegClassID
> -         && OpInfo[1].RegClass == ARM::GPRRegClassID
> -         && "Expect 2 reg operands");
> -
> -  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID;
> -
> -  // Sanity check the registers, which should not be 15.
> -  if (decodeRd(insn) == 15 || decodeRm(insn) == 15)
> -    return false;
> -  if (ThreeReg && decodeRn(insn) == 15)
> -    return false;
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  ++OpIdx;
> -
> -  if (ThreeReg) {
> -    assert(NumOps >= 4 && "Expect >= 4 operands");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -  ++OpIdx;
> -
> -  // If there is still an operand info left which is an immediate operand, add
> -  // an additional imm5 LSL/ASR operand.
> -  if (ThreeReg && OpInfo[OpIdx].RegClass < 0
> -      && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -    // Extract the 5-bit immediate field Inst{11-7}.
> -    unsigned ShiftAmt = (insn >> ARMII::ShiftShift) & 0x1F;
> -    if (Opcode == ARM::PKHBT || Opcode == ARM::PKHTB)
> -      MI.addOperand(MCOperand::CreateImm(ShiftAmt));
> -     else
> -      MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ARM_AM::no_shift,
> -                                                             ShiftAmt)));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -/// DisassembleSatFrm - Disassemble saturate instructions:
> -/// SSAT, SSAT16, USAT, and USAT16.
> -static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  // A8.6.183 SSAT
> -  // if d == 15 || n == 15 then UNPREDICTABLE;
> -  if (decodeRd(insn) == 15 || decodeRm(insn) == 15)
> -    return false;
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  NumOpsAdded = MCID.getNumOperands() - 2; // ignore predicate operands
> -
> -  // Disassemble register def.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -
> -  unsigned Pos = slice(insn, 20, 16);
> -  MI.addOperand(MCOperand::CreateImm(Pos));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -
> -  if (NumOpsAdded == 4) {
> -    // Inst{6} encodes the shift type.
> -    bool isASR = slice(insn, 6, 6);
> -    // Inst{11-7} encodes the imm5 shift amount.
> -    unsigned ShAmt = slice(insn, 11, 7);
> -    MI.addOperand(MCOperand::CreateImm(isASR << 5 | ShAmt));
> -  }
> -  return true;
> -}
> -
> -// Extend instructions.
> -// SXT* and UXT*: Rd [Rn] Rm [rot_imm].
> -// The 2nd operand register is Rn and the 3rd operand regsiter is Rm for the
> -// three register operand form.  Otherwise, Rn=0b1111 and only Rm is used.
> -static bool DisassembleExtFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  // A8.6.220 SXTAB
> -  // if d == 15 || m == 15 then UNPREDICTABLE;
> -  if (decodeRd(insn) == 15 || decodeRm(insn) == 15)
> -    return false;
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2
> -         && OpInfo[0].RegClass == ARM::GPRRegClassID
> -         && OpInfo[1].RegClass == ARM::GPRRegClassID
> -         && "Expect 2 reg operands");
> -
> -  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID;
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  ++OpIdx;
> -
> -  if (ThreeReg) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -  ++OpIdx;
> -
> -  // If there is still an operand info left which is an immediate operand, add
> -  // an additional rotate immediate operand.
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -      && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -    // Extract the 2-bit rotate field Inst{11-10}.
> -    unsigned rot = (insn >> ARMII::ExtRotImmShift) & 3;
> -    MI.addOperand(MCOperand::CreateImm(rot));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -/////////////////////////////////////
> -//                                 //
> -//    Utility Functions For VFP    //
> -//                                 //
> -/////////////////////////////////////
> -
> -// Extract/Decode Dd/Sd:
> -//
> -// SP => d = UInt(Vd:D)
> -// DP => d = UInt(D:Vd)
> -static unsigned decodeVFPRd(uint32_t insn, bool isSPVFP) {
> -  return isSPVFP ? (decodeRd(insn) << 1 | getDBit(insn))
> -                 : (decodeRd(insn) | getDBit(insn) << 4);
> -}
> -
> -// Extract/Decode Dn/Sn:
> -//
> -// SP => n = UInt(Vn:N)
> -// DP => n = UInt(N:Vn)
> -static unsigned decodeVFPRn(uint32_t insn, bool isSPVFP) {
> -  return isSPVFP ? (decodeRn(insn) << 1 | getNBit(insn))
> -                 : (decodeRn(insn) | getNBit(insn) << 4);
> -}
> -
> -// Extract/Decode Dm/Sm:
> -//
> -// SP => m = UInt(Vm:M)
> -// DP => m = UInt(M:Vm)
> -static unsigned decodeVFPRm(uint32_t insn, bool isSPVFP) {
> -  return isSPVFP ? (decodeRm(insn) << 1 | getMBit(insn))
> -                 : (decodeRm(insn) | getMBit(insn) << 4);
> -}
> -
> -// A7.5.1
> -static APInt VFPExpandImm(unsigned char byte, unsigned N) {
> -  assert(N == 32 || N == 64);
> -
> -  uint64_t Result;
> -  unsigned bit6 = slice(byte, 6, 6);
> -  if (N == 32) {
> -    Result = slice(byte, 7, 7) << 31 | slice(byte, 5, 0) << 19;
> -    if (bit6)
> -      Result |= 0x1f << 25;
> -    else
> -      Result |= 0x1 << 30;
> -  } else {
> -    Result = (uint64_t)slice(byte, 7, 7) << 63 |
> -             (uint64_t)slice(byte, 5, 0) << 48;
> -    if (bit6)
> -      Result |= 0xffULL << 54;
> -    else
> -      Result |= 0x1ULL << 62;
> -  }
> -  return APInt(N, Result);
> -}
> -
> -// VFP Unary Format Instructions:
> -//
> -// VCMP[E]ZD, VCMP[E]ZS: compares one floating-point register with zero
> -// VCVTDS, VCVTSD: converts between double-precision and single-precision
> -// The rest of the instructions have homogeneous [VFP]Rd and [VFP]Rm registers.
> -static bool DisassembleVFPUnaryFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 1 && "VFPUnaryFrm expects NumOps >= 1");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  unsigned RegClass = OpInfo[OpIdx].RegClass;
> -  assert((RegClass == ARM::SPRRegClassID || RegClass == ARM::DPRRegClassID) &&
> -         "Reg operand expected");
> -  bool isSP = (RegClass == ARM::SPRRegClassID);
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass, decodeVFPRd(insn, isSP))));
> -  ++OpIdx;
> -
> -  // Early return for compare with zero instructions.
> -  if (Opcode == ARM::VCMPEZD || Opcode == ARM::VCMPEZS
> -      || Opcode == ARM::VCMPZD || Opcode == ARM::VCMPZS)
> -    return true;
> -
> -  RegClass = OpInfo[OpIdx].RegClass;
> -  assert((RegClass == ARM::SPRRegClassID || RegClass == ARM::DPRRegClassID) &&
> -         "Reg operand expected");
> -  isSP = (RegClass == ARM::SPRRegClassID);
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass, decodeVFPRm(insn, isSP))));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// All the instructions have homogeneous [VFP]Rd, [VFP]Rn, and [VFP]Rm regs.
> -// Some of them have operand constraints which tie the first operand in the
> -// InOperandList to that of the dst.  As far as asm printing is concerned, this
> -// tied_to operand is simply skipped.
> -static bool DisassembleVFPBinaryFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 3 && "VFPBinaryFrm expects NumOps >= 3");
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  unsigned RegClass = OpInfo[OpIdx].RegClass;
> -  assert((RegClass == ARM::SPRRegClassID || RegClass == ARM::DPRRegClassID) &&
> -         "Reg operand expected");
> -  bool isSP = (RegClass == ARM::SPRRegClassID);
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass, decodeVFPRd(insn, isSP))));
> -  ++OpIdx;
> -
> -  // Skip tied_to operand constraint.
> -  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1) {
> -    assert(NumOps >= 4 && "Expect >=4 operands");
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass, decodeVFPRn(insn, isSP))));
> -  ++OpIdx;
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass, decodeVFPRm(insn, isSP))));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// A8.6.295 vcvt (floating-point <-> integer)
> -// Int to FP: VSITOD, VSITOS, VUITOD, VUITOS
> -// FP to Int: VTOSI[Z|R]D, VTOSI[Z|R]S, VTOUI[Z|R]D, VTOUI[Z|R]S
> -//
> -// A8.6.297 vcvt (floating-point and fixed-point)
> -// Dd|Sd Dd|Sd(TIED_TO) #fbits(= 16|32 - UInt(imm4:i))
> -static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 2 && "VFPConv1Frm expects NumOps >= 2");
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  if (!OpInfo) return false;
> -
> -  bool SP = slice(insn, 8, 8) == 0; // A8.6.295 & A8.6.297
> -  bool fixed_point = slice(insn, 17, 17) == 1; // A8.6.297
> -  unsigned RegClassID = SP ? ARM::SPRRegClassID : ARM::DPRRegClassID;
> -
> -  if (fixed_point) {
> -    // A8.6.297
> -    assert(NumOps >= 3 && "Expect >= 3 operands");
> -    int size = slice(insn, 7, 7) == 0 ? 16 : 32;
> -    int fbits = size - (slice(insn,3,0) << 1 | slice(insn,5,5));
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, RegClassID,
> -                                    decodeVFPRd(insn, SP))));
> -
> -    assert(MCID.getOperandConstraint(1, MCOI::TIED_TO) != -1 &&
> -           "Tied to operand expected");
> -    MI.addOperand(MI.getOperand(0));
> -
> -    assert(OpInfo[2].RegClass < 0 && !OpInfo[2].isPredicate() &&
> -           !OpInfo[2].isOptionalDef() && "Imm operand expected");
> -    MI.addOperand(MCOperand::CreateImm(fbits));
> -
> -    NumOpsAdded = 3;
> -  } else {
> -    // A8.6.295
> -    // The Rd (destination) and Rm (source) bits have different interpretations
> -    // depending on their single-precisonness.
> -    unsigned d, m;
> -    if (slice(insn, 18, 18) == 1) { // to_integer operation
> -      d = decodeVFPRd(insn, true /* Is Single Precision */);
> -      MI.addOperand(MCOperand::CreateReg(
> -                      getRegisterEnum(B, ARM::SPRRegClassID, d)));
> -      m = decodeVFPRm(insn, SP);
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, m)));
> -    } else {
> -      d = decodeVFPRd(insn, SP);
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, d)));
> -      m = decodeVFPRm(insn, true /* Is Single Precision */);
> -      MI.addOperand(MCOperand::CreateReg(
> -                      getRegisterEnum(B, ARM::SPRRegClassID, m)));
> -    }
> -    NumOpsAdded = 2;
> -  }
> -
> -  return true;
> -}
> -
> -// VMOVRS - A8.6.330
> -// Rt => Rd; Sn => UInt(Vn:N)
> -static bool DisassembleVFPConv2Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 2 && "VFPConv2Frm expects NumOps >= 2");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
> -                                                     decodeVFPRn(insn, true))));
> -  NumOpsAdded = 2;
> -  return true;
> -}
> -
> -// VMOVRRD - A8.6.332
> -// Rt => Rd; Rt2 => Rn; Dm => UInt(M:Vm)
> -//
> -// VMOVRRS - A8.6.331
> -// Rt => Rd; Rt2 => Rn; Sm => UInt(Vm:M); Sm1 = Sm+1
> -static bool DisassembleVFPConv3Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 3 && "VFPConv3Frm expects NumOps >= 3");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  OpIdx = 2;
> -
> -  if (OpInfo[OpIdx].RegClass == ARM::SPRRegClassID) {
> -    unsigned Sm = decodeVFPRm(insn, true);
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
> -                                                       Sm)));
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
> -                                                       Sm+1)));
> -    OpIdx += 2;
> -  } else {
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, ARM::DPRRegClassID,
> -                                    decodeVFPRm(insn, false))));
> -    ++OpIdx;
> -  }
> -  return true;
> -}
> -
> -// VMOVSR - A8.6.330
> -// Rt => Rd; Sn => UInt(Vn:N)
> -static bool DisassembleVFPConv4Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 2 && "VFPConv4Frm expects NumOps >= 2");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
> -                                                     decodeVFPRn(insn, true))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  NumOpsAdded = 2;
> -  return true;
> -}
> -
> -// VMOVDRR - A8.6.332
> -// Rt => Rd; Rt2 => Rn; Dm => UInt(M:Vm)
> -//
> -// VMOVRRS - A8.6.331
> -// Rt => Rd; Rt2 => Rn; Sm => UInt(Vm:M); Sm1 = Sm+1
> -static bool DisassembleVFPConv5Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 3 && "VFPConv5Frm expects NumOps >= 3");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  if (OpInfo[OpIdx].RegClass == ARM::SPRRegClassID) {
> -    unsigned Sm = decodeVFPRm(insn, true);
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
> -                                                       Sm)));
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
> -                                                       Sm+1)));
> -    OpIdx += 2;
> -  } else {
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, ARM::DPRRegClassID,
> -                                    decodeVFPRm(insn, false))));
> -    ++OpIdx;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  OpIdx += 2;
> -  return true;
> -}
> -
> -// VFP Load/Store Instructions.
> -// VLDRD, VLDRS, VSTRD, VSTRS
> -static bool DisassembleVFPLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 3 && "VFPLdStFrm expects NumOps >= 3");
> -
> -  bool isSPVFP = (Opcode == ARM::VLDRS || Opcode == ARM::VSTRS);
> -  unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID;
> -
> -  // Extract Dd/Sd for operand 0.
> -  unsigned RegD = decodeVFPRd(insn, isSPVFP);
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, RegD)));
> -
> -  unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
> -  MI.addOperand(MCOperand::CreateReg(Base));
> -
> -  // Next comes the AM5 Opcode.
> -  ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> -  unsigned char Imm8 = insn & 0xFF;
> -  MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(AddrOpcode, Imm8)));
> -
> -  NumOpsAdded = 3;
> -
> -  return true;
> -}
> -
> -// VFP Load/Store Multiple Instructions.
> -// We have an optional write back reg, the base, and two predicate operands.
> -// It is then followed by a reglist of either DPR(s) or SPR(s).
> -//
> -// VLDMD[_UPD], VLDMS[_UPD], VSTMD[_UPD], VSTMS[_UPD]
> -static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 4 && "VFPLdStMulFrm expects NumOps >= 4");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
> -
> -  // Writeback to base, if necessary.
> -  if (Opcode == ARM::VLDMDIA_UPD || Opcode == ARM::VLDMSIA_UPD ||
> -      Opcode == ARM::VLDMDDB_UPD || Opcode == ARM::VLDMSDB_UPD ||
> -      Opcode == ARM::VSTMDIA_UPD || Opcode == ARM::VSTMSIA_UPD ||
> -      Opcode == ARM::VSTMDDB_UPD || Opcode == ARM::VSTMSDB_UPD) {
> -    MI.addOperand(MCOperand::CreateReg(Base));
> -    ++OpIdx;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(Base));
> -
> -  // Handling the two predicate operands before the reglist.
> -  int64_t CondVal = getCondField(insn);
> -  if (CondVal == 0xF)
> -    return false;
> -  MI.addOperand(MCOperand::CreateImm(CondVal));
> -  MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
> -
> -  OpIdx += 3;
> -
> -  bool isSPVFP = (Opcode == ARM::VLDMSIA     ||
> -                  Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMSDB_UPD ||
> -                  Opcode == ARM::VSTMSIA     ||
> -                  Opcode == ARM::VSTMSIA_UPD || Opcode == ARM::VSTMSDB_UPD);
> -  unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID;
> -
> -  // Extract Dd/Sd.
> -  unsigned RegD = decodeVFPRd(insn, isSPVFP);
> -
> -  // Fill the variadic part of reglist.
> -  unsigned char Imm8 = insn & 0xFF;
> -  unsigned Regs = isSPVFP ? Imm8 : Imm8/2;
> -
> -  // Apply some sanity checks before proceeding.
> -  if (Regs == 0 || (RegD + Regs) > 32 || (!isSPVFP && Regs > 16))
> -    return false;
> -
> -  for (unsigned i = 0; i < Regs; ++i) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID,
> -                                                       RegD + i)));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// Misc. VFP Instructions.
> -// FMSTAT (vmrs with Rt=0b1111, i.e., to apsr_nzcv and no register operand)
> -// FCONSTD (DPR and a VFPf64Imm operand)
> -// FCONSTS (SPR and a VFPf32Imm operand)
> -// VMRS/VMSR (GPR operand)
> -static bool DisassembleVFPMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  if (Opcode == ARM::FMSTAT)
> -    return true;
> -
> -  assert(NumOps >= 2 && "VFPMiscFrm expects >=2 operands");
> -
> -  unsigned RegEnum = 0;
> -  switch (OpInfo[0].RegClass) {
> -  case ARM::DPRRegClassID:
> -    RegEnum = getRegisterEnum(B, ARM::DPRRegClassID, decodeVFPRd(insn, false));
> -    break;
> -  case ARM::SPRRegClassID:
> -    RegEnum = getRegisterEnum(B, ARM::SPRRegClassID, decodeVFPRd(insn, true));
> -    break;
> -  case ARM::GPRRegClassID:
> -    RegEnum = getRegisterEnum(B, ARM::GPRRegClassID, decodeRd(insn));
> -    break;
> -  default:
> -    assert(0 && "Invalid reg class id");
> -    return false;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(RegEnum));
> -  ++OpIdx;
> -
> -  // Extract/decode the f64/f32 immediate.
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -        && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -    // The asm syntax specifies the floating point value, not the 8-bit literal.
> -    APInt immRaw = VFPExpandImm(slice(insn,19,16) << 4 | slice(insn, 3, 0),
> -                             Opcode == ARM::FCONSTD ? 64 : 32);
> -    APFloat immFP = APFloat(immRaw, true);
> -    double imm = Opcode == ARM::FCONSTD ? immFP.convertToDouble() :
> -      immFP.convertToFloat();
> -    MI.addOperand(MCOperand::CreateFPImm(imm));
> -
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// DisassembleThumbFrm() is defined in ThumbDisassemblerCore.h file.
> -#include "ThumbDisassemblerCore.h"
> -
> -/////////////////////////////////////////////////////
> -//                                                 //
> -//     Utility Functions For ARM Advanced SIMD     //
> -//                                                 //
> -/////////////////////////////////////////////////////
> -
> -// The following NEON namings are based on A8.6.266 VABA, VABAL.  Notice that
> -// A8.6.303 VDUP (ARM core register)'s D/Vd pair is the N/Vn pair of VABA/VABAL.
> -
> -// A7.3 Register encoding
> -
> -// Extract/Decode NEON D/Vd:
> -//
> -// Note that for quadword, Qd = UInt(D:Vd<3:1>) = Inst{22:15-13}, whereas for
> -// doubleword, Dd = UInt(D:Vd).  We compensate for this difference by
> -// handling it in the getRegisterEnum() utility function.
> -// D = Inst{22}, Vd = Inst{15-12}
> -static unsigned decodeNEONRd(uint32_t insn) {
> -  return ((insn >> ARMII::NEON_D_BitShift) & 1) << 4
> -    | ((insn >> ARMII::NEON_RegRdShift) & ARMII::NEONRegMask);
> -}
> -
> -// Extract/Decode NEON N/Vn:
> -//
> -// Note that for quadword, Qn = UInt(N:Vn<3:1>) = Inst{7:19-17}, whereas for
> -// doubleword, Dn = UInt(N:Vn).  We compensate for this difference by
> -// handling it in the getRegisterEnum() utility function.
> -// N = Inst{7}, Vn = Inst{19-16}
> -static unsigned decodeNEONRn(uint32_t insn) {
> -  return ((insn >> ARMII::NEON_N_BitShift) & 1) << 4
> -    | ((insn >> ARMII::NEON_RegRnShift) & ARMII::NEONRegMask);
> -}
> -
> -// Extract/Decode NEON M/Vm:
> -//
> -// Note that for quadword, Qm = UInt(M:Vm<3:1>) = Inst{5:3-1}, whereas for
> -// doubleword, Dm = UInt(M:Vm).  We compensate for this difference by
> -// handling it in the getRegisterEnum() utility function.
> -// M = Inst{5}, Vm = Inst{3-0}
> -static unsigned decodeNEONRm(uint32_t insn) {
> -  return ((insn >> ARMII::NEON_M_BitShift) & 1) << 4
> -    | ((insn >> ARMII::NEON_RegRmShift) & ARMII::NEONRegMask);
> -}
> -
> -namespace {
> -enum ElemSize {
> -  ESizeNA = 0,
> -  ESize8 = 8,
> -  ESize16 = 16,
> -  ESize32 = 32,
> -  ESize64 = 64
> -};
> -} // End of unnamed namespace
> -
> -// size        field -> Inst{11-10}
> -// index_align field -> Inst{7-4}
> -//
> -// The Lane Index interpretation depends on the Data Size:
> -//   8  (encoded as size = 0b00) -> Index = index_align[3:1]
> -//   16 (encoded as size = 0b01) -> Index = index_align[3:2]
> -//   32 (encoded as size = 0b10) -> Index = index_align[3]
> -//
> -// Ref: A8.6.317 VLD4 (single 4-element structure to one lane).
> -static unsigned decodeLaneIndex(uint32_t insn) {
> -  unsigned size = insn >> 10 & 3;
> -  assert((size == 0 || size == 1 || size == 2) &&
> -         "Encoding error: size should be either 0, 1, or 2");
> -
> -  unsigned index_align = insn >> 4 & 0xF;
> -  return (index_align >> 1) >> size;
> -}
> -
> -// imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4)
> -// op = Inst{5}, cmode = Inst{11-8}
> -// i = Inst{24} (ARM architecture)
> -// imm3 = Inst{18-16}, imm4 = Inst{3-0}
> -// Ref: Table A7-15 Modified immediate values for Advanced SIMD instructions.
> -static uint64_t decodeN1VImm(uint32_t insn, ElemSize esize) {
> -  unsigned char op = (insn >> 5) & 1;
> -  unsigned char cmode = (insn >> 8) & 0xF;
> -  unsigned char Imm8 = ((insn >> 24) & 1) << 7 |
> -                       ((insn >> 16) & 7) << 4 |
> -                       (insn & 0xF);
> -  return (op << 12) | (cmode << 8) | Imm8;
> -}
> -
> -// A8.6.339 VMUL, VMULL (by scalar)
> -// ESize16 => m = Inst{2-0} (Vm<2:0>) D0-D7
> -// ESize32 => m = Inst{3-0} (Vm<3:0>) D0-D15
> -static unsigned decodeRestrictedDm(uint32_t insn, ElemSize esize) {
> -  switch (esize) {
> -  case ESize16:
> -    return insn & 7;
> -  case ESize32:
> -    return insn & 0xF;
> -  default:
> -    assert(0 && "Unreachable code!");
> -    return 0;
> -  }
> -}
> -
> -// A8.6.339 VMUL, VMULL (by scalar)
> -// ESize16 => index = Inst{5:3} (M:Vm<3>) D0-D7
> -// ESize32 => index = Inst{5}   (M)       D0-D15
> -static unsigned decodeRestrictedDmIndex(uint32_t insn, ElemSize esize) {
> -  switch (esize) {
> -  case ESize16:
> -    return (((insn >> 5) & 1) << 1) | ((insn >> 3) & 1);
> -  case ESize32:
> -    return (insn >> 5) & 1;
> -  default:
> -    assert(0 && "Unreachable code!");
> -    return 0;
> -  }
> -}
> -
> -// A8.6.296 VCVT (between floating-point and fixed-point, Advanced SIMD)
> -// (64 - <fbits>) is encoded as imm6, i.e., Inst{21-16}.
> -static unsigned decodeVCVTFractionBits(uint32_t insn) {
> -  return 64 - ((insn >> 16) & 0x3F);
> -}
> -
> -// A8.6.302 VDUP (scalar)
> -// ESize8  => index = Inst{19-17}
> -// ESize16 => index = Inst{19-18}
> -// ESize32 => index = Inst{19}
> -static unsigned decodeNVLaneDupIndex(uint32_t insn, ElemSize esize) {
> -  switch (esize) {
> -  case ESize8:
> -    return (insn >> 17) & 7;
> -  case ESize16:
> -    return (insn >> 18) & 3;
> -  case ESize32:
> -    return (insn >> 19) & 1;
> -  default:
> -    assert(0 && "Unspecified element size!");
> -    return 0;
> -  }
> -}
> -
> -// A8.6.328 VMOV (ARM core register to scalar)
> -// A8.6.329 VMOV (scalar to ARM core register)
> -// ESize8  => index = Inst{21:6-5}
> -// ESize16 => index = Inst{21:6}
> -// ESize32 => index = Inst{21}
> -static unsigned decodeNVLaneOpIndex(uint32_t insn, ElemSize esize) {
> -  switch (esize) {
> -  case ESize8:
> -    return ((insn >> 21) & 1) << 2 | ((insn >> 5) & 3);
> -  case ESize16:
> -    return ((insn >> 21) & 1) << 1 | ((insn >> 6) & 1);
> -  case ESize32:
> -    return ((insn >> 21) & 1);
> -  default:
> -    assert(0 && "Unspecified element size!");
> -    return 0;
> -  }
> -}
> -
> -// Imm6 = Inst{21-16}, L = Inst{7}
> -//
> -// LeftShift == true (A8.6.367 VQSHL, A8.6.387 VSLI):
> -// case L:imm6 of
> -//   '0001xxx' => esize = 8; shift_amount = imm6 - 8
> -//   '001xxxx' => esize = 16; shift_amount = imm6 - 16
> -//   '01xxxxx' => esize = 32; shift_amount = imm6 - 32
> -//   '1xxxxxx' => esize = 64; shift_amount = imm6
> -//
> -// LeftShift == false (A8.6.376 VRSHR, A8.6.368 VQSHRN):
> -// case L:imm6 of
> -//   '0001xxx' => esize = 8; shift_amount = 16 - imm6
> -//   '001xxxx' => esize = 16; shift_amount = 32 - imm6
> -//   '01xxxxx' => esize = 32; shift_amount = 64 - imm6
> -//   '1xxxxxx' => esize = 64; shift_amount = 64 - imm6
> -//
> -static unsigned decodeNVSAmt(uint32_t insn, bool LeftShift) {
> -  ElemSize esize = ESizeNA;
> -  unsigned L = (insn >> 7) & 1;
> -  unsigned imm6 = (insn >> 16) & 0x3F;
> -  if (L == 0) {
> -    if (imm6 >> 3 == 1)
> -      esize = ESize8;
> -    else if (imm6 >> 4 == 1)
> -      esize = ESize16;
> -    else if (imm6 >> 5 == 1)
> -      esize = ESize32;
> -    else
> -      assert(0 && "Wrong encoding of Inst{7:21-16}!");
> -  } else
> -    esize = ESize64;
> -
> -  if (LeftShift)
> -    return esize == ESize64 ? imm6 : (imm6 - esize);
> -  else
> -    return esize == ESize64 ? (esize - imm6) : (2*esize - imm6);
> -}
> -
> -// A8.6.305 VEXT
> -// Imm4 = Inst{11-8}
> -static unsigned decodeN3VImm(uint32_t insn) {
> -  return (insn >> 8) & 0xF;
> -}
> -
> -// VLD*
> -//   D[d] D[d2] ... Rn [TIED_TO Rn] align [Rm]
> -// VLD*LN*
> -//   D[d] D[d2] ... Rn [TIED_TO Rn] align [Rm] TIED_TO ... imm(idx)
> -// VST*
> -//   Rn [TIED_TO Rn] align [Rm] D[d] D[d2] ...
> -// VST*LN*
> -//   Rn [TIED_TO Rn] align [Rm] D[d] D[d2] ... [imm(idx)]
> -//
> -// Correctly set VLD*/VST*'s TIED_TO GPR, as the asm printer needs it.
> -static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, bool Store, bool DblSpaced,
> -    unsigned alignment, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -
> -  // At least one DPR register plus addressing mode #6.
> -  assert(NumOps >= 3 && "Expect >= 3 operands");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // We have homogeneous NEON registers for Load/Store.
> -  unsigned RegClass = 0;
> -
> -  // Double-spaced registers have increments of 2.
> -  unsigned Inc = DblSpaced ? 2 : 1;
> -
> -  unsigned Rn = decodeRn(insn);
> -  unsigned Rm = decodeRm(insn);
> -  unsigned Rd = decodeNEONRd(insn);
> -
> -  // A7.7.1 Advanced SIMD addressing mode.
> -  bool WB = Rm != 15;
> -
> -  // LLVM Addressing Mode #6.
> -  unsigned RmEnum = 0;
> -  if (WB && Rm != 13)
> -    RmEnum = getRegisterEnum(B, ARM::GPRRegClassID, Rm);
> -
> -  if (Store) {
> -    // Consume possible WB, AddrMode6, possible increment reg, the DPR/QPR's,
> -    // then possible lane index.
> -    assert(OpIdx < NumOps && OpInfo[0].RegClass == ARM::GPRRegClassID &&
> -           "Reg operand expected");
> -
> -    if (WB) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         Rn)));
> -      ++OpIdx;
> -    }
> -
> -    assert((OpIdx+1) < NumOps && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           OpInfo[OpIdx + 1].RegClass < 0 && "Addrmode #6 Operands expected");
> -    // addrmode6 := (ops GPR:$addr, i32imm)
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       Rn)));
> -    MI.addOperand(MCOperand::CreateImm(alignment)); // Alignment
> -    OpIdx += 2;
> -
> -    if (WB) {
> -      MI.addOperand(MCOperand::CreateReg(RmEnum));
> -      ++OpIdx;
> -    }
> -
> -    assert(OpIdx < NumOps &&
> -           (OpInfo[OpIdx].RegClass == ARM::DPRRegClassID ||
> -            OpInfo[OpIdx].RegClass == ARM::QPRRegClassID) &&
> -           "Reg operand expected");
> -
> -    RegClass = OpInfo[OpIdx].RegClass;
> -    while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
> -      MI.addOperand(MCOperand::CreateReg(
> -                      getRegisterEnum(B, RegClass, Rd)));
> -      Rd += Inc;
> -      ++OpIdx;
> -    }
> -
> -    // Handle possible lane index.
> -    if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -        && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -      MI.addOperand(MCOperand::CreateImm(decodeLaneIndex(insn)));
> -      ++OpIdx;
> -    }
> -
> -  } else {
> -    // Consume the DPR/QPR's, possible WB, AddrMode6, possible incrment reg,
> -    // possible TIED_TO DPR/QPR's (ignored), then possible lane index.
> -    RegClass = OpInfo[0].RegClass;
> -
> -    while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
> -      MI.addOperand(MCOperand::CreateReg(
> -                      getRegisterEnum(B, RegClass, Rd)));
> -      Rd += Inc;
> -      ++OpIdx;
> -    }
> -
> -    if (WB) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         Rn)));
> -      ++OpIdx;
> -    }
> -
> -    assert((OpIdx+1) < NumOps && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
> -           OpInfo[OpIdx + 1].RegClass < 0 && "Addrmode #6 Operands expected");
> -    // addrmode6 := (ops GPR:$addr, i32imm)
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       Rn)));
> -    MI.addOperand(MCOperand::CreateImm(alignment)); // Alignment
> -    OpIdx += 2;
> -
> -    if (WB) {
> -      MI.addOperand(MCOperand::CreateReg(RmEnum));
> -      ++OpIdx;
> -    }
> -
> -    while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
> -      assert(MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1 &&
> -             "Tied to operand expected");
> -      MI.addOperand(MCOperand::CreateReg(0));
> -      ++OpIdx;
> -    }
> -
> -    // Handle possible lane index.
> -    if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -        && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -      MI.addOperand(MCOperand::CreateImm(decodeLaneIndex(insn)));
> -      ++OpIdx;
> -    }
> -  }
> -
> -  // Accessing registers past the end of the NEON register file is not
> -  // defined.
> -  if (Rd > 32)
> -    return false;
> -
> -  return true;
> -}
> -
> -// A8.6.308, A8.6.311, A8.6.314, A8.6.317.
> -static bool Align4OneLaneInst(unsigned elem, unsigned size,
> -    unsigned index_align, unsigned & alignment) {
> -  unsigned bits = 0;
> -  switch (elem) {
> -  default:
> -    return false;
> -  case 1:
> -    // A8.6.308
> -    if (size == 0)
> -      return slice(index_align, 0, 0) == 0;
> -    else if (size == 1) {
> -      bits = slice(index_align, 1, 0);
> -      if (bits != 0 && bits != 1)
> -        return false;
> -      if (bits == 1)
> -        alignment = 16;
> -      return true;
> -    } else if (size == 2) {
> -      bits = slice(index_align, 2, 0);
> -      if (bits != 0 && bits != 3)
> -        return false;
> -      if (bits == 3)
> -        alignment = 32;
> -      return true;;
> -    }
> -    return true;
> -  case 2:
> -    // A8.6.311
> -    if (size == 0) {
> -      if (slice(index_align, 0, 0) == 1)
> -        alignment = 16;
> -      return true;
> -    } if (size == 1) {
> -      if (slice(index_align, 0, 0) == 1)
> -        alignment = 32;
> -      return true;
> -    } else if (size == 2) {
> -      if (slice(index_align, 1, 1) != 0)
> -        return false;
> -      if (slice(index_align, 0, 0) == 1)
> -        alignment = 64;
> -      return true;;
> -    }
> -    return true;
> -  case 3:
> -    // A8.6.314
> -    if (size == 0) {
> -      if (slice(index_align, 0, 0) != 0)
> -        return false;
> -      return true;
> -    } if (size == 1) {
> -      if (slice(index_align, 0, 0) != 0)
> -        return false;
> -      return true;
> -      return true;
> -    } else if (size == 2) {
> -      if (slice(index_align, 1, 0) != 0)
> -        return false;
> -      return true;;
> -    }
> -    return true;
> -  case 4:
> -    // A8.6.317
> -    if (size == 0) {
> -      if (slice(index_align, 0, 0) == 1)
> -        alignment = 32;
> -      return true;
> -    } if (size == 1) {
> -      if (slice(index_align, 0, 0) == 1)
> -        alignment = 64;
> -      return true;
> -    } else if (size == 2) {
> -      bits = slice(index_align, 1, 0);
> -      if (bits == 3)
> -        return false;
> -      if (bits == 1)
> -        alignment = 64;
> -      else if (bits == 2)
> -        alignment = 128;
> -      return true;;
> -    }
> -    return true;
> -  }
> -}
> -
> -// A7.7
> -// If L (Inst{21}) == 0, store instructions.
> -// Find out about double-spaced-ness of the Opcode and pass it on to
> -// DisassembleNLdSt0().
> -static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const StringRef Name = ARMInsts[Opcode].Name;
> -  bool DblSpaced = false;
> -  // 0 represents standard alignment, i.e., unaligned data access.
> -  unsigned alignment = 0;
> -
> -  unsigned elem = 0; // legal values: {1, 2, 3, 4}
> -  if (Name.startswith("VST1") || Name.startswith("VLD1"))
> -    elem = 1;
> -
> -  if (Name.startswith("VST2") || Name.startswith("VLD2"))
> -    elem = 2;
> -
> -  if (Name.startswith("VST3") || Name.startswith("VLD3"))
> -    elem = 3;
> -
> -  if (Name.startswith("VST4") || Name.startswith("VLD4"))
> -    elem = 4;
> -
> -  if (Name.find("LN") != std::string::npos) {
> -    // To one lane instructions.
> -    // See, for example, 8.6.317 VLD4 (single 4-element structure to one lane).
> -
> -    // Utility function takes number of elements, size, and index_align.
> -    if (!Align4OneLaneInst(elem,
> -                           slice(insn, 11, 10),
> -                           slice(insn, 7, 4),
> -                           alignment))
> -      return false;
> -
> -    // <size> == 16 && Inst{5} == 1 --> DblSpaced = true
> -    if (Name.endswith("16") || Name.endswith("16_UPD"))
> -      DblSpaced = slice(insn, 5, 5) == 1;
> -
> -    // <size> == 32 && Inst{6} == 1 --> DblSpaced = true
> -    if (Name.endswith("32") || Name.endswith("32_UPD"))
> -      DblSpaced = slice(insn, 6, 6) == 1;
> -  } else if (Name.find("DUP") != std::string::npos) {
> -    // Single element (or structure) to all lanes.
> -    // Inst{9-8} encodes the number of element(s) in the structure, with:
> -    // 0b00 (VLD1DUP) (for this, a bit makes sense only for data size 16 and 32.
> -    // 0b01 (VLD2DUP)
> -    // 0b10 (VLD3DUP) (for this, a bit must be encoded as 0)
> -    // 0b11 (VLD4DUP)
> -    //
> -    // Inst{7-6} encodes the data size, with:
> -    // 0b00 => 8, 0b01 => 16, 0b10 => 32
> -    //
> -    // Inst{4} (the a bit) encodes the align action (0: standard alignment)
> -    unsigned elem = slice(insn, 9, 8) + 1;
> -    unsigned a = slice(insn, 4, 4);
> -    if (elem != 3) {
> -      // 0b11 is not a valid encoding for Inst{7-6}.
> -      if (slice(insn, 7, 6) == 3)
> -        return false;
> -      unsigned data_size = 8 << slice(insn, 7, 6);
> -      // For VLD1DUP, a bit makes sense only for data size of 16 and 32.
> -      if (a && data_size == 8)
> -        return false;
> -
> -      // Now we can calculate the alignment!
> -      if (a)
> -        alignment = elem * data_size;
> -    } else {
> -      if (a) {
> -        // A8.6.315 VLD3 (single 3-element structure to all lanes)
> -        // The a bit must be encoded as 0.
> -        return false;
> -      }
> -    }
> -  } else {
> -    // Multiple n-element structures with type encoded as Inst{11-8}.
> -    // See, for example, A8.6.316 VLD4 (multiple 4-element structures).
> -
> -    // Inst{5-4} encodes alignment.
> -    unsigned align = slice(insn, 5, 4);
> -    switch (align) {
> -    default:
> -      break;
> -    case 1:
> -      alignment = 64; break;
> -    case 2:
> -      alignment = 128; break;
> -    case 3:
> -      alignment = 256; break;
> -    }
> -
> -    unsigned type = slice(insn, 11, 8);
> -    // Reject UNDEFINED instructions based on type and align.
> -    // Plus set DblSpaced flag where appropriate.
> -    switch (elem) {
> -    default:
> -      break;
> -    case 1:
> -      // n == 1
> -      // A8.6.307 & A8.6.391
> -      if ((type == 7  && slice(align, 1, 1) == 1) ||
> -          (type == 10 && align == 3) ||
> -          (type == 6  && slice(align, 1, 1) == 1))
> -        return false;
> -      break;
> -    case 2:
> -      // n == 2 && type == 0b1001 -> DblSpaced = true
> -      // A8.6.310 & A8.6.393
> -      if ((type == 8 || type == 9) && align == 3)
> -        return false;
> -      DblSpaced = (type == 9);
> -      break;
> -    case 3:
> -      // n == 3 && type == 0b0101 -> DblSpaced = true
> -      // A8.6.313 & A8.6.395
> -      if (slice(insn, 7, 6) == 3 || slice(align, 1, 1) == 1)
> -        return false;
> -      DblSpaced = (type == 5);
> -      break;
> -    case 4:
> -      // n == 4 && type == 0b0001 -> DblSpaced = true
> -      // A8.6.316 & A8.6.397
> -      if (slice(insn, 7, 6) == 3)
> -        return false;
> -      DblSpaced = (type == 1);
> -      break;
> -    }
> -  }
> -  return DisassembleNLdSt0(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                           slice(insn, 21, 21) == 0, DblSpaced, alignment/8, B);
> -}
> -
> -// VMOV (immediate)
> -//   Qd/Dd imm
> -// VBIC (immediate)
> -// VORR (immediate)
> -//   Qd/Dd imm src(=Qd/Dd)
> -static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -
> -  assert(NumOps >= 2 &&
> -         (OpInfo[0].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[0].RegClass == ARM::QPRRegClassID) &&
> -         (OpInfo[1].RegClass < 0) &&
> -         "Expect 1 reg operand followed by 1 imm operand");
> -
> -  // Qd/Dd = Inst{22:15-12} => NEON Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[0].RegClass,
> -                                                     decodeNEONRd(insn))));
> -
> -  ElemSize esize = ESizeNA;
> -  switch (Opcode) {
> -  case ARM::VMOVv8i8:
> -  case ARM::VMOVv16i8:
> -    esize = ESize8;
> -    break;
> -  case ARM::VMOVv4i16:
> -  case ARM::VMOVv8i16:
> -  case ARM::VMVNv4i16:
> -  case ARM::VMVNv8i16:
> -  case ARM::VBICiv4i16:
> -  case ARM::VBICiv8i16:
> -  case ARM::VORRiv4i16:
> -  case ARM::VORRiv8i16:
> -    esize = ESize16;
> -    break;
> -  case ARM::VMOVv2i32:
> -  case ARM::VMOVv4i32:
> -  case ARM::VMVNv2i32:
> -  case ARM::VMVNv4i32:
> -  case ARM::VBICiv2i32:
> -  case ARM::VBICiv4i32:
> -  case ARM::VORRiv2i32:
> -  case ARM::VORRiv4i32:
> -    esize = ESize32;
> -    break;
> -  case ARM::VMOVv1i64:
> -  case ARM::VMOVv2i64:
> -    esize = ESize64;
> -    break;
> -  default:
> -    assert(0 && "Unexpected opcode!");
> -    return false;
> -  }
> -
> -  // One register and a modified immediate value.
> -  // Add the imm operand.
> -  MI.addOperand(MCOperand::CreateImm(decodeN1VImm(insn, esize)));
> -
> -  NumOpsAdded = 2;
> -
> -  // VBIC/VORRiv*i* variants have an extra $src = $Vd to be filled in.
> -  if (NumOps >= 3 &&
> -      (OpInfo[2].RegClass == ARM::DPRRegClassID ||
> -       OpInfo[2].RegClass == ARM::QPRRegClassID)) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[0].RegClass,
> -                                                     decodeNEONRd(insn))));
> -    NumOpsAdded += 1;
> -  }
> -
> -  return true;
> -}
> -
> -namespace {
> -enum N2VFlag {
> -  N2V_None,
> -  N2V_VectorDupLane,
> -  N2V_VectorConvert_Between_Float_Fixed
> -};
> -} // End of unnamed namespace
> -
> -// Vector Convert [between floating-point and fixed-point]
> -//   Qd/Dd Qm/Dm [fbits]
> -//
> -// Vector Duplicate Lane (from scalar to all elements) Instructions.
> -// VDUPLN16d, VDUPLN16q, VDUPLN32d, VDUPLN32q, VDUPLN8d, VDUPLN8q:
> -//   Qd/Dd Dm index
> -//
> -// Vector Move Long:
> -//   Qd Dm
> -//
> -// Vector Move Narrow:
> -//   Dd Qm
> -//
> -// Others
> -static bool DisassembleNVdVmOptImm(MCInst &MI, unsigned Opc, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, N2VFlag Flag, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opc];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -
> -  assert(NumOps >= 2 &&
> -         (OpInfo[0].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[0].RegClass == ARM::QPRRegClassID) &&
> -         (OpInfo[1].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[1].RegClass == ARM::QPRRegClassID) &&
> -         "Expect >= 2 operands and first 2 as reg operands");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  ElemSize esize = ESizeNA;
> -  if (Flag == N2V_VectorDupLane) {
> -    // VDUPLN has its index embedded.  Its size can be inferred from the Opcode.
> -    assert(Opc >= ARM::VDUPLN16d && Opc <= ARM::VDUPLN8q &&
> -           "Unexpected Opcode");
> -    esize = (Opc == ARM::VDUPLN8d || Opc == ARM::VDUPLN8q) ? ESize8
> -       : ((Opc == ARM::VDUPLN16d || Opc == ARM::VDUPLN16q) ? ESize16
> -                                                           : ESize32);
> -  }
> -
> -  // Qd/Dd = Inst{22:15-12} => NEON Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeNEONRd(insn))));
> -  ++OpIdx;
> -
> -  // VPADAL...
> -  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1) {
> -    // TIED_TO operand.
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  // Dm = Inst{5:3-0} => NEON Rm
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeNEONRm(insn))));
> -  ++OpIdx;
> -
> -  // VZIP and others have two TIED_TO reg operands.
> -  int Idx;
> -  while (OpIdx < NumOps &&
> -         (Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -    // Add TIED_TO operand.
> -    MI.addOperand(MI.getOperand(Idx));
> -    ++OpIdx;
> -  }
> -
> -  // Add the imm operand, if required.
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -      && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -
> -    unsigned imm = 0xFFFFFFFF;
> -
> -    if (Flag == N2V_VectorDupLane)
> -      imm = decodeNVLaneDupIndex(insn, esize);
> -    if (Flag == N2V_VectorConvert_Between_Float_Fixed)
> -      imm = decodeVCVTFractionBits(insn);
> -
> -    assert(imm != 0xFFFFFFFF && "Internal error");
> -    MI.addOperand(MCOperand::CreateImm(imm));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -static bool DisassembleN2RegFrm(MCInst &MI, unsigned Opc, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded,
> -                                N2V_None, B);
> -}
> -static bool DisassembleNVCVTFrm(MCInst &MI, unsigned Opc, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded,
> -                                N2V_VectorConvert_Between_Float_Fixed, B);
> -}
> -static bool DisassembleNVecDupLnFrm(MCInst &MI, unsigned Opc, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded,
> -                                N2V_VectorDupLane, B);
> -}
> -
> -// Vector Shift [Accumulate] Instructions.
> -// Qd/Dd [Qd/Dd (TIED_TO)] Qm/Dm ShiftAmt
> -//
> -// Vector Shift Left Long (with maximum shift count) Instructions.
> -// VSHLLi16, VSHLLi32, VSHLLi8: Qd Dm imm (== size)
> -//
> -static bool DisassembleNVectorShift(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, bool LeftShift, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -
> -  assert(NumOps >= 3 &&
> -         (OpInfo[0].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[0].RegClass == ARM::QPRRegClassID) &&
> -         (OpInfo[1].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[1].RegClass == ARM::QPRRegClassID) &&
> -         "Expect >= 3 operands and first 2 as reg operands");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // Qd/Dd = Inst{22:15-12} => NEON Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeNEONRd(insn))));
> -  ++OpIdx;
> -
> -  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1) {
> -    // TIED_TO operand.
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  assert((OpInfo[OpIdx].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[OpIdx].RegClass == ARM::QPRRegClassID) &&
> -         "Reg operand expected");
> -
> -  // Qm/Dm = Inst{5:3-0} => NEON Rm
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeNEONRm(insn))));
> -  ++OpIdx;
> -
> -  assert(OpInfo[OpIdx].RegClass < 0 && "Imm operand expected");
> -
> -  // Add the imm operand.
> -
> -  // VSHLL has maximum shift count as the imm, inferred from its size.
> -  unsigned Imm;
> -  switch (Opcode) {
> -  default:
> -    Imm = decodeNVSAmt(insn, LeftShift);
> -    break;
> -  case ARM::VSHLLi8:
> -    Imm = 8;
> -    break;
> -  case ARM::VSHLLi16:
> -    Imm = 16;
> -    break;
> -  case ARM::VSHLLi32:
> -    Imm = 32;
> -    break;
> -  }
> -  MI.addOperand(MCOperand::CreateImm(Imm));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// Left shift instructions.
> -static bool DisassembleN2RegVecShLFrm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVectorShift(MI, Opcode, insn, NumOps, NumOpsAdded, true,
> -                                 B);
> -}
> -// Right shift instructions have different shift amount interpretation.
> -static bool DisassembleN2RegVecShRFrm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVectorShift(MI, Opcode, insn, NumOps, NumOpsAdded, false,
> -                                 B);
> -}
> -
> -namespace {
> -enum N3VFlag {
> -  N3V_None,
> -  N3V_VectorExtract,
> -  N3V_VectorShift,
> -  N3V_Multiply_By_Scalar
> -};
> -} // End of unnamed namespace
> -
> -// NEON Three Register Instructions with Optional Immediate Operand
> -//
> -// Vector Extract Instructions.
> -// Qd/Dd Qn/Dn Qm/Dm imm4
> -//
> -// Vector Shift (Register) Instructions.
> -// Qd/Dd Qm/Dm Qn/Dn (notice the order of m, n)
> -//
> -// Vector Multiply [Accumulate/Subtract] [Long] By Scalar Instructions.
> -// Qd/Dd Qn/Dn RestrictedDm index
> -//
> -// Others
> -static bool DisassembleNVdVnVmOptImm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, N3VFlag Flag, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -
> -  // No checking for OpInfo[2] because of MOVDneon/MOVQ with only two regs.
> -  assert(NumOps >= 3 &&
> -         (OpInfo[0].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[0].RegClass == ARM::QPRRegClassID) &&
> -         (OpInfo[1].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[1].RegClass == ARM::QPRRegClassID) &&
> -         "Expect >= 3 operands and first 2 as reg operands");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  bool VdVnVm = Flag == N3V_VectorShift ? false : true;
> -  bool IsImm4 = Flag == N3V_VectorExtract ? true : false;
> -  bool IsDmRestricted = Flag == N3V_Multiply_By_Scalar ? true : false;
> -  ElemSize esize = ESizeNA;
> -  if (Flag == N3V_Multiply_By_Scalar) {
> -    unsigned size = (insn >> 20) & 3;
> -    if (size == 1) esize = ESize16;
> -    if (size == 2) esize = ESize32;
> -    assert (esize == ESize16 || esize == ESize32);
> -  }
> -
> -  // Qd/Dd = Inst{22:15-12} => NEON Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeNEONRd(insn))));
> -  ++OpIdx;
> -
> -  // VABA, VABAL, VBSLd, VBSLq, ...
> -  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1) {
> -    // TIED_TO operand.
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    ++OpIdx;
> -  }
> -
> -  // Dn = Inst{7:19-16} => NEON Rn
> -  // or
> -  // Dm = Inst{5:3-0} => NEON Rm
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                  VdVnVm ? decodeNEONRn(insn)
> -                                         : decodeNEONRm(insn))));
> -  ++OpIdx;
> -
> -  // Dm = Inst{5:3-0} => NEON Rm
> -  // or
> -  // Dm is restricted to D0-D7 if size is 16, D0-D15 otherwise
> -  // or
> -  // Dn = Inst{7:19-16} => NEON Rn
> -  unsigned m = VdVnVm ? (IsDmRestricted ? decodeRestrictedDm(insn, esize)
> -                                        : decodeNEONRm(insn))
> -                      : decodeNEONRn(insn);
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, OpInfo[OpIdx].RegClass, m)));
> -  ++OpIdx;
> -
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -      && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -    // Add the imm operand.
> -    unsigned Imm = 0;
> -    if (IsImm4)
> -      Imm = decodeN3VImm(insn);
> -    else if (IsDmRestricted)
> -      Imm = decodeRestrictedDmIndex(insn, esize);
> -    else {
> -      assert(0 && "Internal error: unreachable code!");
> -      return false;
> -    }
> -
> -    MI.addOperand(MCOperand::CreateImm(Imm));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -static bool DisassembleN3RegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                  N3V_None, B);
> -}
> -static bool DisassembleN3RegVecShFrm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                  N3V_VectorShift, B);
> -}
> -static bool DisassembleNVecExtractFrm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                  N3V_VectorExtract, B);
> -}
> -static bool DisassembleNVecMulScalarFrm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                  N3V_Multiply_By_Scalar, B);
> -}
> -
> -// Vector Table Lookup
> -//
> -// VTBL1, VTBX1: Dd [Dd(TIED_TO)] Dn Dm
> -// VTBL2, VTBX2: Dd [Dd(TIED_TO)] Dn Dn+1 Dm
> -// VTBL3, VTBX3: Dd [Dd(TIED_TO)] Dn Dn+1 Dn+2 Dm
> -// VTBL4, VTBX4: Dd [Dd(TIED_TO)] Dn Dn+1 Dn+2 Dn+3 Dm
> -static bool DisassembleNVTBLFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::DPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::DPRRegClassID &&
> -         OpInfo[2].RegClass == ARM::DPRRegClassID &&
> -         "Expect >= 3 operands and first 3 as reg operands");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  unsigned Rn = decodeNEONRn(insn);
> -
> -  // {Dn} encoded as len = 0b00
> -  // {Dn Dn+1} encoded as len = 0b01
> -  // {Dn Dn+1 Dn+2 } encoded as len = 0b10
> -  // {Dn Dn+1 Dn+2 Dn+3} encoded as len = 0b11
> -  unsigned Len = slice(insn, 9, 8) + 1;
> -
> -  // Dd (the destination vector)
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
> -                                                     decodeNEONRd(insn))));
> -  ++OpIdx;
> -
> -  // Process tied_to operand constraint.
> -  int Idx;
> -  if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -    MI.addOperand(MI.getOperand(Idx));
> -    ++OpIdx;
> -  }
> -
> -  // Do the <list> now.
> -  for (unsigned i = 0; i < Len; ++i) {
> -    assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::DPRRegClassID &&
> -           "Reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
> -                                                       Rn + i)));
> -    ++OpIdx;
> -  }
> -
> -  // Dm (the index vector)
> -  assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::DPRRegClassID &&
> -         "Reg operand (index vector) expected");
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
> -                                                     decodeNEONRm(insn))));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// Vector Get Lane (move scalar to ARM core register) Instructions.
> -// VGETLNi32, VGETLNs16, VGETLNs8, VGETLNu16, VGETLNu8: Rt Dn index
> -static bool DisassembleNGetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(MCID.getNumDefs() == 1 && NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::GPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::DPRRegClassID &&
> -         OpInfo[2].RegClass < 0 &&
> -         "Expect >= 3 operands with one dst operand");
> -
> -  ElemSize esize =
> -    Opcode == ARM::VGETLNi32 ? ESize32
> -      : ((Opcode == ARM::VGETLNs16 || Opcode == ARM::VGETLNu16) ? ESize16
> -                                                                : ESize8);
> -
> -  // Rt = Inst{15-12} => ARM Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -
> -  // Dn = Inst{7:19-16} => NEON Rn
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
> -                                                     decodeNEONRn(insn))));
> -
> -  MI.addOperand(MCOperand::CreateImm(decodeNVLaneOpIndex(insn, esize)));
> -
> -  NumOpsAdded = 3;
> -  return true;
> -}
> -
> -// Vector Set Lane (move ARM core register to scalar) Instructions.
> -// VSETLNi16, VSETLNi32, VSETLNi8: Dd Dd (TIED_TO) Rt index
> -static bool DisassembleNSetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(MCID.getNumDefs() == 1 && NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::DPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::DPRRegClassID &&
> -         MCID.getOperandConstraint(1, MCOI::TIED_TO) != -1 &&
> -         OpInfo[2].RegClass == ARM::GPRRegClassID &&
> -         OpInfo[3].RegClass < 0 &&
> -         "Expect >= 3 operands with one dst operand");
> -
> -  ElemSize esize =
> -    Opcode == ARM::VSETLNi8 ? ESize8
> -                            : (Opcode == ARM::VSETLNi16 ? ESize16
> -                                                        : ESize32);
> -
> -  // Dd = Inst{7:19-16} => NEON Rn
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
> -                                                     decodeNEONRn(insn))));
> -
> -  // TIED_TO operand.
> -  MI.addOperand(MCOperand::CreateReg(0));
> -
> -  // Rt = Inst{15-12} => ARM Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -
> -  MI.addOperand(MCOperand::CreateImm(decodeNVLaneOpIndex(insn, esize)));
> -
> -  NumOpsAdded = 4;
> -  return true;
> -}
> -
> -// Vector Duplicate Instructions (from ARM core register to all elements).
> -// VDUP8d, VDUP16d, VDUP32d, VDUP8q, VDUP16q, VDUP32q: Qd/Dd Rt
> -static bool DisassembleNDupFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -
> -  assert(NumOps >= 2 &&
> -         (OpInfo[0].RegClass == ARM::DPRRegClassID ||
> -          OpInfo[0].RegClass == ARM::QPRRegClassID) &&
> -         OpInfo[1].RegClass == ARM::GPRRegClassID &&
> -         "Expect >= 2 operands and first 2 as reg operand");
> -
> -  unsigned RegClass = OpInfo[0].RegClass;
> -
> -  // Qd/Dd = Inst{7:19-16} => NEON Rn
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass,
> -                                                     decodeNEONRn(insn))));
> -
> -  // Rt = Inst{15-12} => ARM Rd
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -
> -  NumOpsAdded = 2;
> -  return true;
> -}
> -
> -static inline bool PreLoadOpcode(unsigned Opcode) {
> -  switch(Opcode) {
> -  case ARM::PLDi12:  case ARM::PLDrs:
> -  case ARM::PLDWi12: case ARM::PLDWrs:
> -  case ARM::PLIi12:  case ARM::PLIrs:
> -    return true;
> -  default:
> -    return false;
> -  }
> -}
> -
> -static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  // Preload Data/Instruction requires either 2 or 3 operands.
> -  // PLDi12, PLDWi12, PLIi12: addrmode_imm12
> -  // PLDrs, PLDWrs, PLIrs:    ldst_so_reg
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -
> -  if (Opcode == ARM::PLDi12 || Opcode == ARM::PLDWi12
> -      || Opcode == ARM::PLIi12) {
> -    unsigned Imm12 = slice(insn, 11, 0);
> -    bool Negative = getUBit(insn) == 0;
> -
> -    // A8.6.118 PLD (literal) PLDWi12 with Rn=PC is transformed to PLDi12.
> -    if (Opcode == ARM::PLDWi12 && slice(insn, 19, 16) == 0xF) {
> -      DEBUG(errs() << "Rn == '1111': PLDWi12 morphed to PLDi12\n");
> -      MI.setOpcode(ARM::PLDi12);
> -    }
> -    
> -    // -0 is represented specially. All other values are as normal.
> -    int Offset = Negative ? -1 * Imm12 : Imm12;
> -    if (Imm12 == 0 && Negative)
> -      Offset = INT32_MIN;
> -
> -    MI.addOperand(MCOperand::CreateImm(Offset));
> -    NumOpsAdded = 2;
> -  } else {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -
> -    ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> -
> -    // Inst{6-5} encodes the shift opcode.
> -    ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
> -    // Inst{11-7} encodes the imm5 shift amount.
> -    unsigned ShImm = slice(insn, 11, 7);
> -
> -    // A8.4.1.  Possible rrx or shift amount of 32...
> -    getImmShiftSE(ShOp, ShImm);
> -    MI.addOperand(MCOperand::CreateImm(
> -                    ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
> -    NumOpsAdded = 3;
> -  }
> -
> -  return true;
> -}
> -
> -static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  if (Opcode == ARM::DMB || Opcode == ARM::DSB || Opcode == ARM::ISB) {
> -    // Inst{3-0} encodes the memory barrier option for the variants.
> -    unsigned opt = slice(insn, 3, 0);
> -    switch (opt) {
> -    case ARM_MB::SY:  case ARM_MB::ST:
> -    case ARM_MB::ISH: case ARM_MB::ISHST:
> -    case ARM_MB::NSH: case ARM_MB::NSHST:
> -    case ARM_MB::OSH: case ARM_MB::OSHST:
> -      MI.addOperand(MCOperand::CreateImm(opt));
> -      NumOpsAdded = 1;
> -      return true;
> -    default:
> -      return false;
> -    }
> -  }
> -
> -  switch (Opcode) {
> -  case ARM::CLREX:
> -  case ARM::NOP:
> -  case ARM::TRAP:
> -  case ARM::YIELD:
> -  case ARM::WFE:
> -  case ARM::WFI:
> -  case ARM::SEV:
> -    return true;
> -  case ARM::SWP:
> -  case ARM::SWPB:
> -    // SWP, SWPB: Rd Rm Rn
> -    // Delegate to DisassembleLdStExFrm()....
> -    return DisassembleLdStExFrm(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -  default:
> -    break;
> -  }
> -
> -  if (Opcode == ARM::SETEND) {
> -    NumOpsAdded = 1;
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 9, 9)));
> -    return true;
> -  }
> -
> -  // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
> -  // opcodes which match the same real instruction. This is needed since there's
> -  // no current handling of optional arguments. Fix here when a better handling
> -  // of optional arguments is implemented.
> -  if (Opcode == ARM::CPS3p) {   // M = 1
> -    // Let's reject these impossible imod values by returning false:
> -    // 1. (imod=0b01)
> -    //
> -    // AsmPrinter cannot handle imod=0b00, plus (imod=0b00,M=1,iflags!=0) is an
> -    // invalid combination, so we just check for imod=0b00 here.
> -    if (slice(insn, 19, 18) == 0 || slice(insn, 19, 18) == 1)
> -      return false;
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 18))); // imod
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 8, 6)));   // iflags
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));   // mode
> -    NumOpsAdded = 3;
> -    return true;
> -  }
> -  if (Opcode == ARM::CPS2p) { // mode = 0, M = 0
> -    // Let's reject these impossible imod values by returning false:
> -    // 1. (imod=0b00,M=0)
> -    // 2. (imod=0b01)
> -    if (slice(insn, 19, 18) == 0 || slice(insn, 19, 18) == 1)
> -      return false;
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 18))); // imod
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 8, 6)));   // iflags
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -  if (Opcode == ARM::CPS1p) { // imod = 0, iflags = 0, M = 1
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  // DBG has its option specified in Inst{3-0}.
> -  if (Opcode == ARM::DBG) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  // BKPT takes an imm32 val equal to ZeroExtend(Inst{19-8:3-0}).
> -  if (Opcode == ARM::BKPT) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 8) << 4 |
> -                                       slice(insn, 3, 0)));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  if (PreLoadOpcode(Opcode))
> -    return DisassemblePreLoadFrm(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -
> -  assert(0 && "Unexpected misc instruction!");
> -  return false;
> -}
> -
> -/// FuncPtrs - FuncPtrs maps ARMFormat to its corresponding DisassembleFP.
> -/// We divide the disassembly task into different categories, with each one
> -/// corresponding to a specific instruction encoding format.  There could be
> -/// exceptions when handling a specific format, and that is why the Opcode is
> -/// also present in the function prototype.
> -static const DisassembleFP FuncPtrs[] = {
> -  &DisassemblePseudo,
> -  &DisassembleMulFrm,
> -  &DisassembleBrFrm,
> -  &DisassembleBrMiscFrm,
> -  &DisassembleDPFrm,
> -  &DisassembleDPSoRegRegFrm,
> -  &DisassembleLdFrm,
> -  &DisassembleStFrm,
> -  &DisassembleLdMiscFrm,
> -  &DisassembleStMiscFrm,
> -  &DisassembleLdStMulFrm,
> -  &DisassembleLdStExFrm,
> -  &DisassembleArithMiscFrm,
> -  &DisassembleSatFrm,
> -  &DisassembleExtFrm,
> -  &DisassembleVFPUnaryFrm,
> -  &DisassembleVFPBinaryFrm,
> -  &DisassembleVFPConv1Frm,
> -  &DisassembleVFPConv2Frm,
> -  &DisassembleVFPConv3Frm,
> -  &DisassembleVFPConv4Frm,
> -  &DisassembleVFPConv5Frm,
> -  &DisassembleVFPLdStFrm,
> -  &DisassembleVFPLdStMulFrm,
> -  &DisassembleVFPMiscFrm,
> -  &DisassembleThumbFrm,
> -  &DisassembleMiscFrm,
> -  &DisassembleNGetLnFrm,
> -  &DisassembleNSetLnFrm,
> -  &DisassembleNDupFrm,
> -
> -  // VLD and VST (including one lane) Instructions.
> -  &DisassembleNLdSt,
> -
> -  // A7.4.6 One register and a modified immediate value
> -  // 1-Register Instructions with imm.
> -  // LLVM only defines VMOVv instructions.
> -  &DisassembleN1RegModImmFrm,
> -
> -  // 2-Register Instructions with no imm.
> -  &DisassembleN2RegFrm,
> -
> -  // 2-Register Instructions with imm (vector convert float/fixed point).
> -  &DisassembleNVCVTFrm,
> -
> -  // 2-Register Instructions with imm (vector dup lane).
> -  &DisassembleNVecDupLnFrm,
> -
> -  // Vector Shift Left Instructions.
> -  &DisassembleN2RegVecShLFrm,
> -
> -  // Vector Shift Righ Instructions, which has different interpretation of the
> -  // shift amount from the imm6 field.
> -  &DisassembleN2RegVecShRFrm,
> -
> -  // 3-Register Data-Processing Instructions.
> -  &DisassembleN3RegFrm,
> -
> -  // Vector Shift (Register) Instructions.
> -  // D:Vd M:Vm N:Vn (notice that M:Vm is the first operand)
> -  &DisassembleN3RegVecShFrm,
> -
> -  // Vector Extract Instructions.
> -  &DisassembleNVecExtractFrm,
> -
> -  // Vector [Saturating Rounding Doubling] Multiply [Accumulate/Subtract] [Long]
> -  // By Scalar Instructions.
> -  &DisassembleNVecMulScalarFrm,
> -
> -  // Vector Table Lookup uses byte indexes in a control vector to look up byte
> -  // values in a table and generate a new vector.
> -  &DisassembleNVTBLFrm,
> -
> -  &DisassembleDPSoRegImmFrm,
> -
> -
> -  NULL
> -};
> -
> -/// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
> -/// The general idea is to set the Opcode for the MCInst, followed by adding
> -/// the appropriate MCOperands to the MCInst.  ARM Basic MC Builder delegates
> -/// to the Format-specific disassemble function for disassembly, followed by
> -/// TryPredicateAndSBitModifier() to do PredicateOperand and OptionalDefOperand
> -/// which follow the Dst/Src Operands.
> -bool ARMBasicMCBuilder::BuildIt(MCInst &MI, uint32_t insn) {
> -  // Stage 1 sets the Opcode.
> -  MI.setOpcode(Opcode);
> -  // If the number of operands is zero, we're done!
> -  if (NumOps == 0)
> -    return true;
> -
> -  // Stage 2 calls the format-specific disassemble function to build the operand
> -  // list.
> -  if (Disasm == NULL)
> -    return false;
> -  unsigned NumOpsAdded = 0;
> -  bool OK = (*Disasm)(MI, Opcode, insn, NumOps, NumOpsAdded, this);
> -
> -  if (!OK || this->Err != 0) return false;
> -  if (NumOpsAdded >= NumOps)
> -    return true;
> -
> -  // Stage 3 deals with operands unaccounted for after stage 2 is finished.
> -  // FIXME: Should this be done selectively?
> -  return TryPredicateAndSBitModifier(MI, Opcode, insn, NumOps - NumOpsAdded);
> -}
> -
> -// A8.3 Conditional execution
> -// A8.3.1 Pseudocode details of conditional execution
> -// Condition bits '111x' indicate the instruction is always executed.
> -static uint32_t CondCode(uint32_t CondField) {
> -  if (CondField == 0xF)
> -    return ARMCC::AL;
> -  return CondField;
> -}
> -
> -/// DoPredicateOperands - DoPredicateOperands process the predicate operands
> -/// of some Thumb instructions which come before the reglist operands.  It
> -/// returns true if the two predicate operands have been processed.
> -bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, unsigned Opcode,
> -    uint32_t /* insn */, unsigned short NumOpsRemaining) {
> -
> -  assert(NumOpsRemaining > 0 && "Invalid argument");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned Idx = MI.getNumOperands();
> -
> -  // First, we check whether this instr specifies the PredicateOperand through
> -  // a pair of MCOperandInfos with isPredicate() property.
> -  if (NumOpsRemaining >= 2 &&
> -      OpInfo[Idx].isPredicate() && OpInfo[Idx+1].isPredicate() &&
> -      OpInfo[Idx].RegClass < 0 &&
> -      OpInfo[Idx+1].RegClass == ARM::CCRRegClassID)
> -  {
> -    // If we are inside an IT block, get the IT condition bits maintained via
> -    // ARMBasicMCBuilder::ITState[7:0], through ARMBasicMCBuilder::GetITCond().
> -    // See also A2.5.2.
> -    if (InITBlock())
> -      MI.addOperand(MCOperand::CreateImm(GetITCond()));
> -    else
> -      MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
> -    MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
> -    return true;
> -  }
> -
> -  return false;
> -}
> -
> -/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
> -/// the possible Predicate and SBitModifier, to build the remaining MCOperand
> -/// constituents.
> -bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOpsRemaining) {
> -
> -  assert(NumOpsRemaining > 0 && "Invalid argument");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  const std::string &Name = ARMInsts[Opcode].Name;
> -  unsigned Idx = MI.getNumOperands();
> -  uint64_t TSFlags = ARMInsts[Opcode].TSFlags;
> -
> -  // First, we check whether this instr specifies the PredicateOperand through
> -  // a pair of MCOperandInfos with isPredicate() property.
> -  if (NumOpsRemaining >= 2 &&
> -      OpInfo[Idx].isPredicate() && OpInfo[Idx+1].isPredicate() &&
> -      OpInfo[Idx].RegClass < 0 &&
> -      OpInfo[Idx+1].RegClass == ARM::CCRRegClassID)
> -  {
> -    // If we are inside an IT block, get the IT condition bits maintained via
> -    // ARMBasicMCBuilder::ITState[7:0], through ARMBasicMCBuilder::GetITCond().
> -    // See also A2.5.2.
> -    if (InITBlock())
> -      MI.addOperand(MCOperand::CreateImm(GetITCond()));
> -    else {
> -      if (Name.length() > 1 && Name[0] == 't') {
> -        // Thumb conditional branch instructions have their cond field embedded,
> -        // like ARM.
> -        //
> -        // A8.6.16 B
> -        // Check for undefined encodings.
> -        unsigned cond;
> -        if (Name == "t2Bcc") {
> -          if ((cond = slice(insn, 25, 22)) >= 14)
> -            return false;
> -          MI.addOperand(MCOperand::CreateImm(CondCode(cond)));
> -        } else if (Name == "tBcc") {
> -          if ((cond = slice(insn, 11, 8)) == 14)
> -            return false;
> -          MI.addOperand(MCOperand::CreateImm(CondCode(cond)));
> -        } else
> -          MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
> -      } else {
> -        // ARM instructions get their condition field from Inst{31-28}.
> -        // We should reject Inst{31-28} = 0b1111 as invalid encoding.
> -        if (!isNEONDomain(TSFlags) && getCondField(insn) == 0xF)
> -          return false;
> -        MI.addOperand(MCOperand::CreateImm(CondCode(getCondField(insn))));
> -      }
> -    }
> -    MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
> -    Idx += 2;
> -    NumOpsRemaining -= 2;
> -  }
> -
> -  if (NumOpsRemaining == 0)
> -    return true;
> -
> -  // Next, if OptionalDefOperand exists, we check whether the 'S' bit is set.
> -  if (OpInfo[Idx].isOptionalDef() && OpInfo[Idx].RegClass==ARM::CCRRegClassID) {
> -    MI.addOperand(MCOperand::CreateReg(getSBit(insn) == 1 ? ARM::CPSR : 0));
> -    --NumOpsRemaining;
> -  }
> -
> -  if (NumOpsRemaining == 0)
> -    return true;
> -  else
> -    return false;
> -}
> -
> -/// RunBuildAfterHook - RunBuildAfterHook performs operations deemed necessary
> -/// after BuildIt is finished.
> -bool ARMBasicMCBuilder::RunBuildAfterHook(bool Status, MCInst &MI,
> -    uint32_t insn) {
> -
> -  if (!SP) return Status;
> -
> -  if (Opcode == ARM::t2IT)
> -    Status = SP->InitIT(slice(insn, 7, 0)) ? Status : false;
> -  else if (InITBlock())
> -    SP->UpdateIT();
> -
> -  return Status;
> -}
> -
> -/// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
> -ARMBasicMCBuilder::ARMBasicMCBuilder(unsigned opc, ARMFormat format,
> -                                     unsigned short num)
> -  : Opcode(opc), Format(format), NumOps(num), SP(0), Err(0) {
> -  unsigned Idx = (unsigned)format;
> -  assert(Idx < (array_lengthof(FuncPtrs) - 1) && "Unknown format");
> -  Disasm = FuncPtrs[Idx];
> -}
> -
> -/// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
> -/// infrastructure of an MCInst given the Opcode and Format of the instr.
> -/// Return NULL if it fails to create/return a proper builder.  API clients
> -/// are responsible for freeing up of the allocated memory.  Cacheing can be
> -/// performed by the API clients to improve performance.
> -ARMBasicMCBuilder *llvm::CreateMCBuilder(unsigned Opcode, ARMFormat Format) {
> -  // For "Unknown format", fail by returning a NULL pointer.
> -  if ((unsigned)Format >= (array_lengthof(FuncPtrs) - 1)) {
> -    DEBUG(errs() << "Unknown format\n");
> -    return 0;
> -  }
> -
> -  return new ARMBasicMCBuilder(Opcode, Format,
> -                               ARMInsts[Opcode].getNumOperands());
> -}
> -
> -/// tryAddingSymbolicOperand - tryAddingSymbolicOperand trys to add a symbolic
> -/// operand in place of the immediate Value in the MCInst.  The immediate
> -/// Value has had any PC adjustment made by the caller.  If the getOpInfo()
> -/// function was set as part of the setupBuilderForSymbolicDisassembly() call
> -/// then that function is called to get any symbolic information at the
> -/// builder's Address for this instrution.  If that returns non-zero then the
> -/// symbolic information it returns is used to create an MCExpr and that is
> -/// added as an operand to the MCInst.  This function returns true if it adds
> -/// an operand to the MCInst and false otherwise.
> -bool ARMBasicMCBuilder::tryAddingSymbolicOperand(uint64_t Value,
> -                                                 uint64_t InstSize,
> -                                                 MCInst &MI) {
> -  if (!GetOpInfo)
> -    return false;
> -
> -  struct LLVMOpInfo1 SymbolicOp;
> -  SymbolicOp.Value = Value;
> -  if (!GetOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp))
> -    return false;
> -
> -  const MCExpr *Add = NULL;
> -  if (SymbolicOp.AddSymbol.Present) {
> -    if (SymbolicOp.AddSymbol.Name) {
> -      StringRef Name(SymbolicOp.AddSymbol.Name);
> -      MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
> -      Add = MCSymbolRefExpr::Create(Sym, *Ctx);
> -    } else {
> -      Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx);
> -    }
> -  }
> -
> -  const MCExpr *Sub = NULL;
> -  if (SymbolicOp.SubtractSymbol.Present) {
> -    if (SymbolicOp.SubtractSymbol.Name) {
> -      StringRef Name(SymbolicOp.SubtractSymbol.Name);
> -      MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
> -      Sub = MCSymbolRefExpr::Create(Sym, *Ctx);
> -    } else {
> -      Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx);
> -    }
> -  }
> -
> -  const MCExpr *Off = NULL;
> -  if (SymbolicOp.Value != 0)
> -    Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx);
> -
> -  const MCExpr *Expr;
> -  if (Sub) {
> -    const MCExpr *LHS;
> -    if (Add)
> -      LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx);
> -    else
> -      LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx);
> -    if (Off != 0)
> -      Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx);
> -    else
> -      Expr = LHS;
> -  } else if (Add) {
> -    if (Off != 0)
> -      Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx);
> -    else
> -      Expr = Add;
> -  } else {
> -    if (Off != 0)
> -      Expr = Off;
> -    else
> -      Expr = MCConstantExpr::Create(0, *Ctx);
> -  }
> -
> -  if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16)
> -    MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx)));
> -  else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16)
> -    MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx)));
> -  else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None)
> -    MI.addOperand(MCOperand::CreateExpr(Expr));
> -  else 
> -    assert("bad SymbolicOp.VariantKind");
> -
> -  return true;
> -}
> 
> Removed: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h?rev=137143&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h (removed)
> @@ -1,337 +0,0 @@
> -//===- ARMDisassemblerCore.h - ARM disassembler helpers ---------*- C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -//
> -// This file is part of the ARM Disassembler.
> -//
> -// The first part defines the enumeration type of ARM instruction format, which
> -// specifies the encoding used by the instruction, as well as a helper function
> -// to convert the enums to printable char strings.
> -//
> -// It also contains code to represent the concepts of Builder and DisassembleFP
> -// to solve the problem of disassembling an ARM instr.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -#ifndef ARMDISASSEMBLERCORE_H
> -#define ARMDISASSEMBLERCORE_H
> -
> -#include "llvm/MC/MCInst.h"
> -#include "llvm/MC/MCSymbol.h"
> -#include "llvm/MC/MCExpr.h"
> -#include "llvm/MC/MCContext.h"
> -#include "llvm/Target/TargetInstrInfo.h"
> -#include "llvm-c/Disassembler.h"
> -#include "ARMBaseInstrInfo.h"
> -#include "ARMRegisterInfo.h"
> -#include "ARMDisassembler.h"
> -
> -namespace llvm {
> -class MCContext;
> -
> -class ARMUtils {
> -public:
> -  static const char *OpcodeName(unsigned Opcode);
> -};
> -
> -/////////////////////////////////////////////////////
> -//                                                 //
> -//  Enums and Utilities for ARM Instruction Format //
> -//                                                 //
> -/////////////////////////////////////////////////////
> -
> -#define ARM_FORMATS                   \
> -  ENTRY(ARM_FORMAT_PSEUDO,         0) \
> -  ENTRY(ARM_FORMAT_MULFRM,         1) \
> -  ENTRY(ARM_FORMAT_BRFRM,          2) \
> -  ENTRY(ARM_FORMAT_BRMISCFRM,      3) \
> -  ENTRY(ARM_FORMAT_DPFRM,          4) \
> -  ENTRY(ARM_FORMAT_DPSOREGREGFRM,     5) \
> -  ENTRY(ARM_FORMAT_LDFRM,          6) \
> -  ENTRY(ARM_FORMAT_STFRM,          7) \
> -  ENTRY(ARM_FORMAT_LDMISCFRM,      8) \
> -  ENTRY(ARM_FORMAT_STMISCFRM,      9) \
> -  ENTRY(ARM_FORMAT_LDSTMULFRM,    10) \
> -  ENTRY(ARM_FORMAT_LDSTEXFRM,     11) \
> -  ENTRY(ARM_FORMAT_ARITHMISCFRM,  12) \
> -  ENTRY(ARM_FORMAT_SATFRM,        13) \
> -  ENTRY(ARM_FORMAT_EXTFRM,        14) \
> -  ENTRY(ARM_FORMAT_VFPUNARYFRM,   15) \
> -  ENTRY(ARM_FORMAT_VFPBINARYFRM,  16) \
> -  ENTRY(ARM_FORMAT_VFPCONV1FRM,   17) \
> -  ENTRY(ARM_FORMAT_VFPCONV2FRM,   18) \
> -  ENTRY(ARM_FORMAT_VFPCONV3FRM,   19) \
> -  ENTRY(ARM_FORMAT_VFPCONV4FRM,   20) \
> -  ENTRY(ARM_FORMAT_VFPCONV5FRM,   21) \
> -  ENTRY(ARM_FORMAT_VFPLDSTFRM,    22) \
> -  ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 23) \
> -  ENTRY(ARM_FORMAT_VFPMISCFRM,    24) \
> -  ENTRY(ARM_FORMAT_THUMBFRM,      25) \
> -  ENTRY(ARM_FORMAT_MISCFRM,       26) \
> -  ENTRY(ARM_FORMAT_NEONGETLNFRM,  27) \
> -  ENTRY(ARM_FORMAT_NEONSETLNFRM,  28) \
> -  ENTRY(ARM_FORMAT_NEONDUPFRM,    29) \
> -  ENTRY(ARM_FORMAT_NLdSt,         30) \
> -  ENTRY(ARM_FORMAT_N1RegModImm,   31) \
> -  ENTRY(ARM_FORMAT_N2Reg,         32) \
> -  ENTRY(ARM_FORMAT_NVCVT,         33) \
> -  ENTRY(ARM_FORMAT_NVecDupLn, 34) \
> -  ENTRY(ARM_FORMAT_N2RegVecShL,   35) \
> -  ENTRY(ARM_FORMAT_N2RegVecShR,   36) \
> -  ENTRY(ARM_FORMAT_N3Reg,         37) \
> -  ENTRY(ARM_FORMAT_N3RegVecSh,    38) \
> -  ENTRY(ARM_FORMAT_NVecExtract,   39) \
> -  ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
> -  ENTRY(ARM_FORMAT_NVTBL,         41) \
> -  ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42)
> -
> -// ARM instruction format specifies the encoding used by the instruction.
> -#define ENTRY(n, v) n = v,
> -typedef enum {
> -  ARM_FORMATS
> -  ARM_FORMAT_NA
> -} ARMFormat;
> -#undef ENTRY
> -
> -// Converts enum to const char*.
> -static const inline char *stringForARMFormat(ARMFormat form) {
> -#define ENTRY(n, v) case n: return #n;
> -  switch(form) {
> -    ARM_FORMATS
> -  case ARM_FORMAT_NA:
> -  default:
> -    return "";
> -  }
> -#undef ENTRY
> -}
> -
> -/// Expands on the enum definitions from ARMBaseInstrInfo.h.
> -/// They are being used by the disassembler implementation.
> -namespace ARMII {
> -  enum {
> -    NEONRegMask = 15,
> -    GPRRegMask = 15,
> -    NEON_RegRdShift = 12,
> -    NEON_D_BitShift = 22,
> -    NEON_RegRnShift = 16,
> -    NEON_N_BitShift = 7,
> -    NEON_RegRmShift = 0,
> -    NEON_M_BitShift = 5
> -  };
> -}
> -
> -/// Utility function for extracting [From, To] bits from a uint32_t.
> -static inline unsigned slice(uint32_t Bits, unsigned From, unsigned To) {
> -  assert(From < 32 && To < 32 && From >= To);
> -  return (Bits >> To) & ((1 << (From - To + 1)) - 1);
> -}
> -
> -/// Utility function for setting [From, To] bits to Val for a uint32_t.
> -static inline void setSlice(unsigned &Bits, unsigned From, unsigned To,
> -                            unsigned Val) {
> -  assert(From < 32 && To < 32 && From >= To);
> -  uint32_t Mask = ((1 << (From - To + 1)) - 1);
> -  Bits &= ~(Mask << To);
> -  Bits |= (Val & Mask) << To;
> -}
> -
> -// Return an integer result equal to the number of bits of x that are ones.
> -static inline uint32_t
> -BitCount (uint64_t x)
> -{
> -    // c accumulates the total bits set in x
> -    uint32_t c;
> -    for (c = 0; x; ++c)
> -    {
> -        x &= x - 1; // clear the least significant bit set
> -    }
> -    return c;
> -}
> -
> -static inline bool
> -BitIsSet (const uint64_t value, const uint64_t bit)
> -{
> -    return (value & (1ull << bit)) != 0;
> -}
> -
> -static inline bool
> -BitIsClear (const uint64_t value, const uint64_t bit)
> -{
> -    return (value & (1ull << bit)) == 0;
> -}
> -
> -/// Various utilities for checking the target specific flags.
> -
> -/// A unary data processing instruction doesn't have an Rn operand.
> -static inline bool isUnaryDP(uint64_t TSFlags) {
> -  return (TSFlags & ARMII::UnaryDP);
> -}
> -
> -/// A NEON Domain instruction has cond field (Inst{31-28}) as 0b1111.
> -static inline bool isNEONDomain(uint64_t TSFlags) {
> -  return (TSFlags & ARMII::DomainNEON) ||
> -         (TSFlags & ARMII::DomainNEONA8);
> -}
> -
> -/// This four-bit field describes the addressing mode used.
> -/// See also ARMBaseInstrInfo.h.
> -static inline unsigned getAddrMode(uint64_t TSFlags) {
> -  return (TSFlags & ARMII::AddrModeMask);
> -}
> -
> -/// {IndexModePre, IndexModePost}
> -/// Only valid for load and store ops.
> -/// See also ARMBaseInstrInfo.h.
> -static inline unsigned getIndexMode(uint64_t TSFlags) {
> -  return (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
> -}
> -
> -/// Pre-/post-indexed operations define an extra $base_wb in the OutOperandList.
> -static inline bool isPrePostLdSt(uint64_t TSFlags) {
> -  return (TSFlags & ARMII::IndexModeMask) != 0;
> -}
> -
> -// Forward declaration.
> -class ARMBasicMCBuilder;
> -
> -// Builder Object is mostly ignored except in some Thumb disassemble functions.
> -typedef ARMBasicMCBuilder *BO;
> -
> -/// DisassembleFP - DisassembleFP points to a function that disassembles an insn
> -/// and builds the MCOperand list upon disassembly.  It returns false on failure
> -/// or true on success.  The number of operands added is updated upon success.
> -typedef bool (*DisassembleFP)(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO Builder);
> -
> -/// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
> -/// infrastructure of an MCInst given the Opcode and Format of the instr.
> -/// Return NULL if it fails to create/return a proper builder.  API clients
> -/// are responsible for freeing up of the allocated memory.  Cacheing can be
> -/// performed by the API clients to improve performance.
> -extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
> -
> -/// ARMBasicMCBuilder - ARMBasicMCBuilder represents an ARM MCInst builder that
> -/// knows how to build up the MCOperand list.
> -class ARMBasicMCBuilder {
> -  friend ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
> -  unsigned Opcode;
> -  ARMFormat Format;
> -  unsigned short NumOps;
> -  DisassembleFP Disasm;
> -  Session *SP;
> -  int Err; // !=0 if the builder encounters some error condition during build.
> -
> -private:
> -  /// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
> -  ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num);
> -
> -public:
> -  ARMBasicMCBuilder(ARMBasicMCBuilder &B)
> -    : Opcode(B.Opcode), Format(B.Format), NumOps(B.NumOps), Disasm(B.Disasm),
> -      SP(B.SP), GetOpInfo(0), DisInfo(0), Ctx(0) {
> -    Err = 0;
> -  }
> -
> -  virtual ~ARMBasicMCBuilder() {}
> -
> -  void SetSession(Session *sp) {
> -    SP = sp;
> -  }
> -
> -  void SetErr(int ErrCode) {
> -    Err = ErrCode;
> -  }
> -
> -  /// DoPredicateOperands - DoPredicateOperands process the predicate operands
> -  /// of some Thumb instructions which come before the reglist operands.  It
> -  /// returns true if the two predicate operands have been processed.
> -  bool DoPredicateOperands(MCInst& MI, unsigned Opcode,
> -      uint32_t insn, unsigned short NumOpsRemaning);
> -  
> -  /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
> -  /// the possible Predicate and SBitModifier, to build the remaining MCOperand
> -  /// constituents.
> -  bool TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
> -      uint32_t insn, unsigned short NumOpsRemaning);
> -
> -  /// InITBlock - InITBlock returns true if we are inside an IT block.
> -  bool InITBlock() {
> -    if (SP)
> -      return SP->ITCounter > 0;
> -
> -    return false;
> -  }
> -
> -  /// Build - Build delegates to BuildIt to perform the heavy liftling.  After
> -  /// that, it invokes RunBuildAfterHook where some housekeepings can be done.
> -  virtual bool Build(MCInst &MI, uint32_t insn) {
> -    bool Status = BuildIt(MI, insn);
> -    return RunBuildAfterHook(Status, MI, insn);
> -  }
> -
> -  /// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
> -  /// The general idea is to set the Opcode for the MCInst, followed by adding
> -  /// the appropriate MCOperands to the MCInst.  ARM Basic MC Builder delegates
> -  /// to the Format-specific disassemble function for disassembly, followed by
> -  /// TryPredicateAndSBitModifier() for PredicateOperand and OptionalDefOperand
> -  /// which follow the Dst/Src Operands.
> -  virtual bool BuildIt(MCInst &MI, uint32_t insn);
> -
> -  /// RunBuildAfterHook - RunBuildAfterHook performs operations deemed necessary
> -  /// after BuildIt is finished.
> -  virtual bool RunBuildAfterHook(bool Status, MCInst &MI, uint32_t insn);
> -
> -private:
> -  /// Get condition of the current IT instruction.
> -  unsigned GetITCond() {
> -    assert(SP);
> -    return slice(SP->ITState, 7, 4);
> -  }
> -
> -private:
> -  //
> -  // Hooks for symbolic disassembly via the public 'C' interface.
> -  //
> -  // The function to get the symbolic information for operands.
> -  LLVMOpInfoCallback GetOpInfo;
> -  // The pointer to the block of symbolic information for above call back.
> -  void *DisInfo;
> -  // The assembly context for creating symbols and MCExprs in place of
> -  // immediate operands when there is symbolic information.
> -  MCContext *Ctx;
> -  // The address of the instruction being disassembled.
> -  uint64_t Address;
> -
> -public:
> -  void setupBuilderForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,
> -                                          void *disInfo, MCContext *ctx,
> -                                          uint64_t address) {
> -    GetOpInfo = getOpInfo;
> -    DisInfo = disInfo;
> -    Ctx = ctx;
> -    Address = address;
> -  }
> -
> -  uint64_t getBuilderAddress() const { return Address; }
> -
> -  /// tryAddingSymbolicOperand - tryAddingSymbolicOperand trys to add a symbolic
> -  /// operand in place of the immediate Value in the MCInst.  The immediate
> -  /// Value has had any PC adjustment made by the caller.  If the getOpInfo()
> -  /// function was set as part of the setupBuilderForSymbolicDisassembly() call
> -  /// then that function is called to get any symbolic information at the
> -  /// builder's Address for this instrution.  If that returns non-zero then the
> -  /// symbolic information it returns is used to create an MCExpr and that is
> -  /// added as an operand to the MCInst.  This function returns true if it adds
> -  /// an operand to the MCInst and false otherwise.
> -  bool tryAddingSymbolicOperand(uint64_t Value, uint64_t InstSize, MCInst &MI);
> -
> -};
> -
> -} // namespace llvm
> -
> -#endif
> 
> Modified: llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/CMakeLists.txt Tue Aug  9 15:55:18 2011
> @@ -2,7 +2,6 @@
> 
> add_llvm_library(LLVMARMDisassembler
>   ARMDisassembler.cpp
> -  ARMDisassemblerCore.cpp
>   )
> # workaround for hanging compilation on MSVC8, 9 and 10
> if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 )
> 
> Removed: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h?rev=137143&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (removed)
> @@ -1,2461 +0,0 @@
> -//===- ThumbDisassemblerCore.h - Thumb disassembler helpers -----*- C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -//
> -// This file is part of the ARM Disassembler.
> -// It contains code for disassembling a Thumb instr.  It is to be included by
> -// ARMDisassemblerCore.cpp because it contains the static DisassembleThumbFrm()
> -// function which acts as the dispatcher to disassemble a Thumb instruction.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -///////////////////////////////
> -//                           //
> -//     Utility Functions     //
> -//                           //
> -///////////////////////////////
> -
> -// Utilities for 16-bit Thumb instructions.
> -/*
> -15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> -               [  tRt ]
> -                      [ tRm ]  [ tRn ]  [ tRd ]
> -                         D  [   Rm   ]  [  Rd ]
> -
> -                      [ imm3]
> -               [    imm5    ]
> -                   i     [    imm5   ]
> -                            [       imm7      ]
> -                         [       imm8         ]
> -               [             imm11            ]
> -
> -            [   cond  ]
> -*/
> -
> -// Extract tRt: Inst{10-8}.
> -static inline unsigned getT1tRt(uint32_t insn) {
> -  return slice(insn, 10, 8);
> -}
> -
> -// Extract tRm: Inst{8-6}.
> -static inline unsigned getT1tRm(uint32_t insn) {
> -  return slice(insn, 8, 6);
> -}
> -
> -// Extract tRn: Inst{5-3}.
> -static inline unsigned getT1tRn(uint32_t insn) {
> -  return slice(insn, 5, 3);
> -}
> -
> -// Extract tRd: Inst{2-0}.
> -static inline unsigned getT1tRd(uint32_t insn) {
> -  return slice(insn, 2, 0);
> -}
> -
> -// Extract [D:Rd]: Inst{7:2-0}.
> -static inline unsigned getT1Rd(uint32_t insn) {
> -  return slice(insn, 7, 7) << 3 | slice(insn, 2, 0);
> -}
> -
> -// Extract Rm: Inst{6-3}.
> -static inline unsigned getT1Rm(uint32_t insn) {
> -  return slice(insn, 6, 3);
> -}
> -
> -// Extract imm3: Inst{8-6}.
> -static inline unsigned getT1Imm3(uint32_t insn) {
> -  return slice(insn, 8, 6);
> -}
> -
> -// Extract imm5: Inst{10-6}.
> -static inline unsigned getT1Imm5(uint32_t insn) {
> -  return slice(insn, 10, 6);
> -}
> -
> -// Extract i:imm5: Inst{9:7-3}.
> -static inline unsigned getT1Imm6(uint32_t insn) {
> -  return slice(insn, 9, 9) << 5 | slice(insn, 7, 3);
> -}
> -
> -// Extract imm7: Inst{6-0}.
> -static inline unsigned getT1Imm7(uint32_t insn) {
> -  return slice(insn, 6, 0);
> -}
> -
> -// Extract imm8: Inst{7-0}.
> -static inline unsigned getT1Imm8(uint32_t insn) {
> -  return slice(insn, 7, 0);
> -}
> -
> -// Extract imm11: Inst{10-0}.
> -static inline unsigned getT1Imm11(uint32_t insn) {
> -  return slice(insn, 10, 0);
> -}
> -
> -// Extract cond: Inst{11-8}.
> -static inline unsigned getT1Cond(uint32_t insn) {
> -  return slice(insn, 11, 8);
> -}
> -
> -static inline bool IsGPR(unsigned RegClass) {
> -  return RegClass == ARM::GPRRegClassID || RegClass == ARM::rGPRRegClassID;
> -}
> -
> -// Utilities for 32-bit Thumb instructions.
> -
> -static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
> -
> -// Extract imm4: Inst{19-16}.
> -static inline unsigned getImm4(uint32_t insn) {
> -  return slice(insn, 19, 16);
> -}
> -
> -// Extract imm3: Inst{14-12}.
> -static inline unsigned getImm3(uint32_t insn) {
> -  return slice(insn, 14, 12);
> -}
> -
> -// Extract imm8: Inst{7-0}.
> -static inline unsigned getImm8(uint32_t insn) {
> -  return slice(insn, 7, 0);
> -}
> -
> -// A8.6.61 LDRB (immediate, Thumb) and friends
> -// +/-: Inst{9}
> -// imm8: Inst{7-0}
> -static inline int decodeImm8(uint32_t insn) {
> -  int Offset = getImm8(insn);
> -  return slice(insn, 9, 9) ? Offset : -Offset;
> -}
> -
> -// Extract imm12: Inst{11-0}.
> -static inline unsigned getImm12(uint32_t insn) {
> -  return slice(insn, 11, 0);
> -}
> -
> -// A8.6.63 LDRB (literal) and friends
> -// +/-: Inst{23}
> -// imm12: Inst{11-0}
> -static inline int decodeImm12(uint32_t insn) {
> -  int Offset = getImm12(insn);
> -  return slice(insn, 23, 23) ? Offset : -Offset;
> -}
> -
> -// Extract imm2: Inst{7-6}.
> -static inline unsigned getImm2(uint32_t insn) {
> -  return slice(insn, 7, 6);
> -}
> -
> -// For BFI, BFC, t2SBFX, and t2UBFX.
> -// Extract lsb: Inst{14-12:7-6}.
> -static inline unsigned getLsb(uint32_t insn) {
> -  return getImm3(insn) << 2 | getImm2(insn);
> -}
> -
> -// For BFI and BFC.
> -// Extract msb: Inst{4-0}.
> -static inline unsigned getMsb(uint32_t insn) {
> -  return slice(insn, 4, 0);
> -}
> -
> -// For t2SBFX and t2UBFX.
> -// Extract widthminus1: Inst{4-0}.
> -static inline unsigned getWidthMinus1(uint32_t insn) {
> -  return slice(insn, 4, 0);
> -}
> -
> -// For t2ADDri12 and t2SUBri12.
> -// imm12 = i:imm3:imm8;
> -static inline unsigned getIImm3Imm8(uint32_t insn) {
> -  return slice(insn, 26, 26) << 11 | getImm3(insn) << 8 | getImm8(insn);
> -}
> -
> -// For t2MOVi16 and t2MOVTi16.
> -// imm16 = imm4:i:imm3:imm8;
> -static inline unsigned getImm16(uint32_t insn) {
> -  return getImm4(insn) << 12 | slice(insn, 26, 26) << 11 |
> -    getImm3(insn) << 8 | getImm8(insn);
> -}
> -
> -// Inst{5-4} encodes the shift type.
> -static inline unsigned getShiftTypeBits(uint32_t insn) {
> -  return slice(insn, 5, 4);
> -}
> -
> -// Inst{14-12}:Inst{7-6} encodes the imm5 shift amount.
> -static inline unsigned getShiftAmtBits(uint32_t insn) {
> -  return getImm3(insn) << 2 | getImm2(insn);
> -}
> -
> -// A8.6.17 BFC
> -// Encoding T1 ARMv6T2, ARMv7
> -// LLVM-specific encoding for #<lsb> and #<width>
> -static inline bool getBitfieldInvMask(uint32_t insn, uint32_t &mask) {
> -  uint32_t lsb = getImm3(insn) << 2 | getImm2(insn);
> -  uint32_t msb = getMsb(insn);
> -  uint32_t Val = 0;
> -  if (msb < lsb) {
> -    DEBUG(errs() << "Encoding error: msb < lsb\n");
> -    return false;
> -  }
> -  for (uint32_t i = lsb; i <= msb; ++i)
> -    Val |= (1 << i);
> -  mask = ~Val;
> -  return true;
> -}
> -
> -// A8.4 Shifts applied to a register
> -// A8.4.1 Constant shifts
> -// A8.4.3 Pseudocode details of instruction-specified shifts and rotates
> -//
> -// decodeImmShift() returns the shift amount and the the shift opcode.
> -// Note that, as of Jan-06-2010, LLVM does not support rrx shifted operands yet.
> -static inline unsigned decodeImmShift(unsigned bits2, unsigned imm5,
> -                                      ARM_AM::ShiftOpc &ShOp) {
> -
> -  assert(imm5 < 32 && "Invalid imm5 argument");
> -  switch (bits2) {
> -  default: assert(0 && "No such value");
> -  case 0:
> -    ShOp = (imm5 == 0 ? ARM_AM::no_shift : ARM_AM::lsl);
> -    return imm5;
> -  case 1:
> -    ShOp = ARM_AM::lsr;
> -    return (imm5 == 0 ? 32 : imm5);
> -  case 2:
> -    ShOp = ARM_AM::asr;
> -    return (imm5 == 0 ? 32 : imm5);
> -  case 3:
> -    ShOp = (imm5 == 0 ? ARM_AM::rrx : ARM_AM::ror);
> -    return (imm5 == 0 ? 1 : imm5);
> -  }
> -}
> -
> -// A6.3.2 Modified immediate constants in Thumb instructions
> -//
> -// ThumbExpandImm() returns the modified immediate constant given an imm12 for
> -// Thumb data-processing instructions with modified immediate.
> -// See also A6.3.1 Data-processing (modified immediate).
> -static inline unsigned ThumbExpandImm(unsigned imm12) {
> -  assert(imm12 <= 0xFFF && "Invalid imm12 argument");
> -
> -  // If the leading two bits is 0b00, the modified immediate constant is
> -  // obtained by splatting the low 8 bits into the first byte, every other byte,
> -  // or every byte of a 32-bit value.
> -  //
> -  // Otherwise, a rotate right of '1':imm12<6:0> by the amount imm12<11:7> is
> -  // performed.
> -
> -  if (slice(imm12, 11, 10) == 0) {
> -    unsigned short control = slice(imm12, 9, 8);
> -    unsigned imm8 = slice(imm12, 7, 0);
> -    switch (control) {
> -    default:
> -      assert(0 && "No such value");
> -      return 0;
> -    case 0:
> -      return imm8;
> -    case 1:
> -      return imm8 << 16 | imm8;
> -    case 2:
> -      return imm8 << 24 | imm8 << 8;
> -    case 3:
> -      return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8;
> -    }
> -  } else {
> -    // A rotate is required.
> -    unsigned Val = 1 << 7 | slice(imm12, 6, 0);
> -    unsigned Amt = slice(imm12, 11, 7);
> -    return ARM_AM::rotr32(Val, Amt);
> -  }
> -}
> -
> -static inline int decodeImm32_B_EncodingT3(uint32_t insn) {
> -  bool S = slice(insn, 26, 26);
> -  bool J1 = slice(insn, 13, 13);
> -  bool J2 = slice(insn, 11, 11);
> -  unsigned Imm21 = slice(insn, 21, 16) << 12 | slice(insn, 10, 0) << 1;
> -  if (S) Imm21 |= 1 << 20;
> -  if (J2) Imm21 |= 1 << 19;
> -  if (J1) Imm21 |= 1 << 18;
> -
> -  return SignExtend32<21>(Imm21);
> -}
> -
> -static inline int decodeImm32_B_EncodingT4(uint32_t insn) {
> -  unsigned S = slice(insn, 26, 26);
> -  bool I1 = slice(insn, 13, 13) == S;
> -  bool I2 = slice(insn, 11, 11) == S;
> -  unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
> -  if (S) Imm25 |= 1 << 24;
> -  if (I1) Imm25 |= 1 << 23;
> -  if (I2) Imm25 |= 1 << 22;
> -
> -  return SignExtend32<25>(Imm25);
> -}
> -
> -static inline int decodeImm32_BL(uint32_t insn) {
> -  unsigned S = slice(insn, 26, 26);
> -  bool I1 = slice(insn, 13, 13) == S;
> -  bool I2 = slice(insn, 11, 11) == S;
> -  unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
> -  if (S) Imm25 |= 1 << 24;
> -  if (I1) Imm25 |= 1 << 23;
> -  if (I2) Imm25 |= 1 << 22;
> -
> -  return SignExtend32<25>(Imm25);
> -}
> -
> -static inline int decodeImm32_BLX(uint32_t insn) {
> -  unsigned S = slice(insn, 26, 26);
> -  bool I1 = slice(insn, 13, 13) == S;
> -  bool I2 = slice(insn, 11, 11) == S;
> -  unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 1) << 2;
> -  if (S) Imm25 |= 1 << 24;
> -  if (I1) Imm25 |= 1 << 23;
> -  if (I2) Imm25 |= 1 << 22;
> -
> -  return SignExtend32<25>(Imm25);
> -}
> -
> -///////////////////////////////////////////////
> -//                                           //
> -// Thumb1 instruction disassembly functions. //
> -//                                           //
> -///////////////////////////////////////////////
> -
> -// See "Utilities for 16-bit Thumb instructions" for register naming convention.
> -
> -// A6.2.1 Shift (immediate), add, subtract, move, and compare
> -//
> -// shift immediate:         tRd CPSR tRn imm5
> -// add/sub register:        tRd CPSR tRn tRm
> -// add/sub 3-bit immediate: tRd CPSR tRn imm3
> -// add/sub 8-bit immediate: tRt CPSR tRt(TIED_TO) imm8
> -// mov/cmp immediate:       tRt [CPSR] imm8 (CPSR present for mov)
> -//
> -// Special case:
> -// tMOVSr:                  tRd tRn
> -static bool DisassembleThumb1General(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID
> -         && "Invalid arguments");
> -
> -  bool Imm3 = (Opcode == ARM::tADDi3 || Opcode == ARM::tSUBi3);
> -
> -  // Use Rt implies use imm8.
> -  bool UseRt = (Opcode == ARM::tADDi8 || Opcode == ARM::tSUBi8 ||
> -                Opcode == ARM::tMOVi8 || Opcode == ARM::tCMPi8);
> -
> -  // Add the destination operand.
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                  UseRt ? getT1tRt(insn) : getT1tRd(insn))));
> -  ++OpIdx;
> -
> -  // Check whether the next operand to be added is a CCR Register.
> -  if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
> -    assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
> -    MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
> -    ++OpIdx;
> -  }
> -
> -  // Check whether the next operand to be added is a Thumb1 Register.
> -  assert(OpIdx < NumOps && "More operands expected");
> -  if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
> -    // For UseRt, the reg operand is tied to the first reg operand.
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                    UseRt ? getT1tRt(insn) : getT1tRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  // Special case for tMOVSr.
> -  if (OpIdx == NumOps)
> -    return true;
> -
> -  // The next available operand is either a reg operand or an imm operand.
> -  if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
> -    // Three register operand instructions.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                       getT1tRm(insn))));
> -  } else {
> -    assert(OpInfo[OpIdx].RegClass < 0 &&
> -           !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
> -           && "Pure imm operand expected");
> -    unsigned Imm = 0;
> -    if (UseRt)
> -      Imm = getT1Imm8(insn);
> -    else if (Imm3)
> -      Imm = getT1Imm3(insn);
> -    else {
> -      Imm = getT1Imm5(insn);
> -      ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 12, 11));
> -      getImmShiftSE(ShOp, Imm);
> -    }
> -    MI.addOperand(MCOperand::CreateImm(Imm));
> -  }
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// A6.2.2 Data-processing
> -//
> -// tCMPr, tTST, tCMN: tRd tRn
> -// tMVN, tRSB:        tRd CPSR tRn
> -// Others:            tRd CPSR tRd(TIED_TO) tRn
> -static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
> -         (OpInfo[1].RegClass == ARM::CCRRegClassID
> -          || OpInfo[1].RegClass == ARM::tGPRRegClassID)
> -         && "Invalid arguments");
> -
> -  // Add the destination operand.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRd(insn))));
> -  ++OpIdx;
> -
> -  // Check whether the next operand to be added is a CCR Register.
> -  if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
> -    assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
> -    MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
> -    ++OpIdx;
> -  }
> -
> -  // We have either { tRd(TIED_TO), tRn } or { tRn } remaining.
> -  // Process the TIED_TO operand first.
> -
> -  assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
> -         && "Thumb reg operand expected");
> -  int Idx;
> -  if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -    // The reg operand is tied to the first reg operand.
> -    MI.addOperand(MI.getOperand(Idx));
> -    ++OpIdx;
> -  }
> -
> -  // Process possible next reg operand.
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
> -    // Add tRn operand.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                       getT1tRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// A6.2.3 Special data instructions and branch and exchange
> -//
> -// tADDhirr: Rd Rd(TIED_TO) Rm
> -// tCMPhir:  Rd Rm
> -// tMOVr, tMOVgpr2gpr, tMOVgpr2tgpr, tMOVtgpr2gpr: Rd|tRd Rm|tRn
> -// tBX: Rm
> -// tBX_RET: 0 operand
> -// tBX_RET_vararg: Rm
> -// tBLXr: Rm
> -// tBRIND: Rm
> -static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  // tBX_RET has 0 operand.
> -  if (NumOps == 0)
> -    return true;
> -
> -  // BX/BLX/tBRIND (indirect branch, i.e, mov pc, Rm) has 1 reg operand: Rm.
> -  if (Opcode==ARM::tBLXr || Opcode==ARM::tBX || Opcode==ARM::tBRIND) {
> -    if (Opcode == ARM::tBLXr) {
> -      // Handling the two predicate operands before the reg operand.
> -      if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
> -        return false;
> -      NumOpsAdded += 2;
> -    }
> -
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       getT1Rm(insn))));
> -    NumOpsAdded += 1;
> -
> -    if (Opcode == ARM::tBX) {
> -      // Handling the two predicate operands after the reg operand.
> -      if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
> -        return false;
> -      NumOpsAdded += 2;
> -    }
> -
> -    return true;
> -  }
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  // Add the destination operand.
> -  unsigned RegClass = OpInfo[OpIdx].RegClass;
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass,
> -                                  IsGPR(RegClass) ? getT1Rd(insn)
> -                                                  : getT1tRd(insn))));
> -  ++OpIdx;
> -
> -  // We have either { Rd(TIED_TO), Rm } or { Rm|tRn } remaining.
> -  // Process the TIED_TO operand first.
> -
> -  assert(OpIdx < NumOps && "More operands expected");
> -  int Idx;
> -  if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -    // The reg operand is tied to the first reg operand.
> -    MI.addOperand(MI.getOperand(Idx));
> -    ++OpIdx;
> -  }
> -
> -  // The next reg operand is either Rm or tRn.
> -  assert(OpIdx < NumOps && "More operands expected");
> -  RegClass = OpInfo[OpIdx].RegClass;
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RegClass,
> -                                  IsGPR(RegClass) ? getT1Rm(insn)
> -                                                  : getT1tRn(insn))));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// A8.6.59 LDR (literal)
> -//
> -// tLDRpci: tRt imm8*4
> -static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
> -         (OpInfo[1].RegClass < 0 &&
> -          !OpInfo[1].isPredicate() &&
> -          !OpInfo[1].isOptionalDef())
> -         && "Invalid arguments");
> -
> -  // Add the destination operand.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRt(insn))));
> -
> -  // And the (imm8 << 2) operand.
> -  MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn) << 2));
> -
> -  NumOpsAdded = 2;
> -
> -  return true;
> -}
> -
> -// Thumb specific addressing modes (see ARMInstrThumb.td):
> -//
> -// t_addrmode_rr := reg + reg
> -//
> -// t_addrmode_s4 := reg + reg
> -//                  reg + imm5 * 4
> -//
> -// t_addrmode_s2 := reg + reg
> -//                  reg + imm5 * 2
> -//
> -// t_addrmode_s1 := reg + reg
> -//                  reg + imm5
> -//
> -// t_addrmode_sp := sp + imm8 * 4
> -//
> -
> -// A8.6.63 LDRB (literal)
> -// A8.6.79 LDRSB (literal)
> -// A8.6.75 LDRH (literal)
> -// A8.6.83 LDRSH (literal)
> -// A8.6.59 LDR (literal)
> -//
> -// These instrs calculate an address from the PC value and an immediate offset.
> -// Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
> -static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps >= 2 &&
> -         OpInfo[0].RegClass == ARM::GPRRegClassID &&
> -         OpInfo[1].RegClass < 0 &&
> -         "Expect >= 2 operands, first as reg, and second as imm operand");
> -
> -  // Build the register operand, followed by the (+/-)imm12 immediate.
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRd(insn))));
> -
> -  MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
> -
> -  NumOpsAdded = 2;
> -
> -  return true;
> -}
> -
> -
> -// A6.2.4 Load/store single data item
> -//
> -// Load/Store Register (reg|imm):      tRd tRn imm5|tRm
> -// Load Register Signed Byte|Halfword: tRd tRn tRm
> -static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  assert(NumOps >= 2
> -         && OpInfo[0].RegClass == ARM::tGPRRegClassID
> -         && OpInfo[1].RegClass == ARM::tGPRRegClassID
> -         && "Expect >= 2 operands and first two as thumb reg operands");
> -
> -  // Add the destination reg and the base reg.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRd(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRn(insn))));
> -  OpIdx = 2;
> -
> -  // We have either { imm5 } or { tRm } remaining.
> -  // Note that STR/LDR (register) should skip the imm5 offset operand for
> -  // t_addrmode_s[1|2|4].
> -
> -  assert(OpIdx < NumOps && "More operands expected");
> -
> -  if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() &&
> -      !OpInfo[OpIdx].isOptionalDef()) {
> -    // Table A6-5 16-bit Thumb Load/store instructions
> -    // opA = 0b0101 for STR/LDR (register) and friends.
> -    // Otherwise, we have STR/LDR (immediate) and friends.
> -    assert(opA != 5 && "Immediate operand expected for this opcode");
> -    MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn)));
> -    ++OpIdx;
> -  } else {
> -    // The next reg operand is tRm, the offset.
> -    assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
> -           && "Thumb reg operand expected");
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                       getT1tRm(insn))));
> -    ++OpIdx;
> -  }
> -  return true;
> -}
> -
> -// A6.2.4 Load/store single data item
> -//
> -// Load/Store Register SP relative: tRt ARM::SP imm8
> -static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
> -         && "Unexpected opcode");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::tGPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::GPRRegClassID &&
> -         (OpInfo[2].RegClass < 0 &&
> -          !OpInfo[2].isPredicate() &&
> -          !OpInfo[2].isOptionalDef())
> -         && "Invalid arguments");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRt(insn))));
> -  MI.addOperand(MCOperand::CreateReg(ARM::SP));
> -  MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
> -  NumOpsAdded = 3;
> -  return true;
> -}
> -
> -// Table A6-1 16-bit Thumb instruction encoding
> -// A8.6.10 ADR
> -//
> -// tADDrPCi: tRt imm8
> -static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(Opcode == ARM::tADDrPCi && "Unexpected opcode");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
> -         (OpInfo[1].RegClass < 0 &&
> -          !OpInfo[1].isPredicate() &&
> -          !OpInfo[1].isOptionalDef())
> -         && "Invalid arguments");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRt(insn))));
> -  MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
> -  NumOpsAdded = 2;
> -  return true;
> -}
> -
> -// Table A6-1 16-bit Thumb instruction encoding
> -// A8.6.8 ADD (SP plus immediate)
> -//
> -// tADDrSPi: tRt ARM::SP imm8
> -static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(Opcode == ARM::tADDrSPi && "Unexpected opcode");
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::tGPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::GPRRegClassID &&
> -         (OpInfo[2].RegClass < 0 &&
> -          !OpInfo[2].isPredicate() &&
> -          !OpInfo[2].isOptionalDef())
> -         && "Invalid arguments");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRt(insn))));
> -  MI.addOperand(MCOperand::CreateReg(ARM::SP));
> -  MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
> -  NumOpsAdded = 3;
> -  return true;
> -}
> -
> -// tPUSH, tPOP: Pred-Imm Pred-CCR register_list
> -//
> -// where register_list = low registers + [lr] for PUSH or
> -//                       low registers + [pc] for POP
> -//
> -// "low registers" is specified by Inst{7-0}
> -// lr|pc is specified by Inst{8}
> -static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Unexpected opcode");
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  // Handling the two predicate operands before the reglist.
> -  if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
> -    OpIdx += 2;
> -  else {
> -    DEBUG(errs() << "Expected predicate operands not found.\n");
> -    return false;
> -  }
> -
> -  unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
> -    | slice(insn, 7, 0);
> -
> -  // Fill the variadic part of reglist.
> -  for (unsigned i = 0; i < 16; ++i) {
> -    if ((RegListBits >> i) & 1) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         i)));
> -      ++OpIdx;
> -    }
> -  }
> -
> -  return true;
> -}
> -
> -// A6.2.5 Miscellaneous 16-bit instructions
> -// Delegate to DisassembleThumb1PushPop() for tPUSH & tPOP.
> -//
> -// tADDspi, tSUBspi: ARM::SP ARM::SP(TIED_TO) imm7
> -// t2IT:             firstcond=Inst{7-4} mask=Inst{3-0}
> -// tCBNZ, tCBZ:      tRd imm6*2
> -// tBKPT:            imm8
> -// tNOP, tSEV, tYIELD, tWFE, tWFI:
> -//   no operand (except predicate pair)
> -// tSETEND: i1
> -// Others:           tRd tRn
> -static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  if (NumOps == 0)
> -    return true;
> -
> -  if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
> -    return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -
> -  // Predicate operands are handled elsewhere.
> -  if (NumOps == 2 &&
> -      OpInfo[0].isPredicate() && OpInfo[1].isPredicate() &&
> -      OpInfo[0].RegClass < 0 && OpInfo[1].RegClass == ARM::CCRRegClassID) {
> -    return true;
> -  }
> -
> -  if (Opcode == ARM::tADDspi || Opcode == ARM::tSUBspi) {
> -    // Special case handling for tADDspi and tSUBspi.
> -    // A8.6.8 ADD (SP plus immediate) & A8.6.215 SUB (SP minus immediate)
> -    MI.addOperand(MCOperand::CreateReg(ARM::SP));
> -    MI.addOperand(MCOperand::CreateReg(ARM::SP));
> -    MI.addOperand(MCOperand::CreateImm(getT1Imm7(insn)));
> -    NumOpsAdded = 3;
> -    return true;
> -  }
> -
> -  if (Opcode == ARM::t2IT) {
> -    // Special case handling for If-Then.
> -    // A8.6.50 IT
> -    // Tag the (firstcond[0] bit << 4) along with mask.
> -
> -    // firstcond
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 4)));
> -
> -    // firstcond[0] and mask
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -
> -  if (Opcode == ARM::tBKPT) {
> -    MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn))); // breakpoint value
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  // CPS has a singleton $opt operand that contains the following information:
> -  // The first op would be 0b10 as enable and 0b11 as disable in regular ARM,
> -  // but in Thumb it's is 0 as enable and 1 as disable. So map it to ARM's
> -  // default one. The second get the AIF flags from Inst{2-0}.
> -  if (Opcode == ARM::tCPS) {
> -    MI.addOperand(MCOperand::CreateImm(2 + slice(insn, 4, 4)));
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 2, 0)));
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -
> -  if (Opcode == ARM::tSETEND) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 1)));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
> -         (OpInfo[1].RegClass < 0 || OpInfo[1].RegClass==ARM::tGPRRegClassID)
> -         && "Expect >=2 operands");
> -
> -  // Add the destination operand.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                     getT1tRd(insn))));
> -
> -  if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
> -    // Two register instructions.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                       getT1tRn(insn))));
> -  } else {
> -    // CBNZ, CBZ
> -    assert((Opcode == ARM::tCBNZ || Opcode == ARM::tCBZ) &&"Unexpected opcode");
> -    MI.addOperand(MCOperand::CreateImm(getT1Imm6(insn) * 2));
> -  }
> -
> -  NumOpsAdded = 2;
> -
> -  return true;
> -}
> -
> -// A8.6.53  LDM / LDMIA
> -// A8.6.189 STM / STMIA
> -//
> -// tLDMIA_UPD/tSTMIA_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
> -// tLDMIA:                tRt AM4ModeImm Pred-Imm Pred-CCR register_list
> -static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
> -                                     uint32_t insn, unsigned short NumOps,
> -                                     unsigned &NumOpsAdded, BO B) {
> -  assert((Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) &&
> -         "Unexpected opcode");
> -
> -  unsigned tRt = getT1tRt(insn);
> -  NumOpsAdded = 0;
> -
> -  // WB register, if necessary.
> -  if (Opcode == ARM::tLDMIA_UPD || Opcode == ARM::tSTMIA_UPD) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       tRt)));
> -    ++NumOpsAdded;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     tRt)));
> -  ++NumOpsAdded;
> -
> -  // Handling the two predicate operands before the reglist.
> -  if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
> -    NumOpsAdded += 2;
> -  } else {
> -    DEBUG(errs() << "Expected predicate operands not found.\n");
> -    return false;
> -  }
> -
> -  unsigned RegListBits = slice(insn, 7, 0);
> -  if (BitCount(RegListBits) < 1) {
> -    DEBUG(errs() << "if BitCount(registers) < 1 then UNPREDICTABLE\n");
> -    return false;
> -  }
> -
> -  // Fill the variadic part of reglist.
> -  for (unsigned i = 0; i < 8; ++i)
> -    if ((RegListBits >> i) & 1) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
> -                                                         i)));
> -      ++NumOpsAdded;
> -    }
> -
> -  return true;
> -}
> -
> -static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                  B);
> -}
> -
> -static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                  B);
> -}
> -
> -// A8.6.16 B Encoding T1
> -// cond = Inst{11-8} & imm8 = Inst{7-0}
> -// imm32 = SignExtend(imm8:'0', 32)
> -//
> -// tBcc: offset Pred-Imm Pred-CCR
> -// tSVC: imm8 Pred-Imm Pred-CCR
> -// tTRAP: 0 operand (early return)
> -static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO) {
> -
> -  if (Opcode == ARM::tTRAP)
> -    return true;
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps == 3 && OpInfo[0].RegClass < 0 &&
> -         OpInfo[1].isPredicate() && OpInfo[2].RegClass == ARM::CCRRegClassID
> -         && "Exactly 3 operands expected");
> -
> -  unsigned Imm8 = getT1Imm8(insn);
> -  MI.addOperand(MCOperand::CreateImm(
> -                  Opcode == ARM::tBcc ? SignExtend32<9>(Imm8 << 1)
> -                                      : (int)Imm8));
> -
> -  // Predicate operands by ARMBasicMCBuilder::TryPredicateAndSBitModifier().
> -  // But note that for tBcc, if cond = '1110' then UNDEFINED.
> -  if (Opcode == ARM::tBcc && slice(insn, 11, 8) == 14) {
> -    DEBUG(errs() << "if cond = '1110' then UNDEFINED\n");
> -    return false;
> -  }
> -  NumOpsAdded = 1;
> -
> -  return true;
> -}
> -
> -// A8.6.16 B Encoding T2
> -// imm11 = Inst{10-0}
> -// imm32 = SignExtend(imm11:'0', 32)
> -//
> -// tB: offset
> -static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  assert(NumOps == 1 && OpInfo[0].RegClass < 0 && "1 imm operand expected");
> -
> -  unsigned Imm11 = getT1Imm11(insn);
> -
> -  MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1)));
> -
> -  NumOpsAdded = 1;
> -
> -  return true;
> -
> -}
> -
> -// See A6.2 16-bit Thumb instruction encoding for instruction classes
> -// corresponding to op.
> -//
> -// Table A6-1 16-bit Thumb instruction encoding (abridged)
> -// op    Instruction or instruction class
> -// ------  --------------------------------------------------------------------
> -// 00xxxx  Shift (immediate), add, subtract, move, and compare on page A6-7
> -// 010000  Data-processing on page A6-8
> -// 010001  Special data instructions and branch and exchange on page A6-9
> -// 01001x  Load from Literal Pool, see LDR (literal) on page A8-122
> -// 0101xx  Load/store single data item on page A6-10
> -// 011xxx
> -// 100xxx
> -// 10100x  Generate PC-relative address, see ADR on page A8-32
> -// 10101x  Generate SP-relative address, see ADD (SP plus immediate) on
> -//         page A8-28
> -// 1011xx  Miscellaneous 16-bit instructions on page A6-11
> -// 11000x  Store multiple registers, see STM / STMIA / STMEA on page A8-374
> -// 11001x  Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
> -// 1101xx  Conditional branch, and Supervisor Call on page A6-13
> -// 11100x  Unconditional Branch, see B on page A8-44
> -//
> -static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  unsigned op1 = slice(op, 5, 4);
> -  unsigned op2 = slice(op, 3, 2);
> -  unsigned op3 = slice(op, 1, 0);
> -  unsigned opA = slice(op, 5, 2);
> -  switch (op1) {
> -  case 0:
> -    // A6.2.1 Shift (immediate), add, subtract, move, and compare
> -    return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -  case 1:
> -    switch (op2) {
> -    case 0:
> -      switch (op3) {
> -      case 0:
> -        // A6.2.2 Data-processing
> -        return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      case 1:
> -        // A6.2.3 Special data instructions and branch and exchange
> -        return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                        B);
> -      default:
> -        // A8.6.59 LDR (literal)
> -        return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      }
> -      break;
> -    default:
> -      // A6.2.4 Load/store single data item
> -      return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                   B);
> -      break;
> -    }
> -    break;
> -  case 2:
> -    switch (op2) {
> -    case 0:
> -      // A6.2.4 Load/store single data item
> -      return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                   B);
> -    case 1:
> -      // A6.2.4 Load/store single data item
> -      return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -    case 2:
> -      if (op3 <= 1) {
> -        // A8.6.10 ADR
> -        return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                       B);
> -      } else {
> -        // A8.6.8 ADD (SP plus immediate)
> -        return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                       B);
> -      }
> -    default:
> -      // A6.2.5 Miscellaneous 16-bit instructions
> -      return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -    }
> -    break;
> -  case 3:
> -    switch (op2) {
> -    case 0:
> -      if (op3 <= 1) {
> -        // A8.6.189 STM / STMIA / STMEA
> -        return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      } else {
> -        // A8.6.53 LDM / LDMIA / LDMFD
> -        return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      }
> -    case 1:
> -      // A6.2.6 Conditional branch, and Supervisor Call
> -      return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -    case 2:
> -      // Unconditional Branch, see B on page A8-44
> -      return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -    default:
> -      assert(0 && "Unreachable code");
> -      break;
> -    }
> -    break;
> -  default:
> -    assert(0 && "Unreachable code");
> -    break;
> -  }
> -
> -  return false;
> -}
> -
> -///////////////////////////////////////////////
> -//                                           //
> -// Thumb2 instruction disassembly functions. //
> -//                                           //
> -///////////////////////////////////////////////
> -
> -///////////////////////////////////////////////////////////
> -//                                                       //
> -// Note: the register naming follows the ARM convention! //
> -//                                                       //
> -///////////////////////////////////////////////////////////
> -
> -static inline bool Thumb2SRSOpcode(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return false;
> -  case ARM::t2SRSDBW: case ARM::t2SRSDB:
> -  case ARM::t2SRSIAW: case ARM::t2SRSIA:
> -    return true;
> -  }
> -}
> -
> -static inline bool Thumb2RFEOpcode(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return false;
> -  case ARM::t2RFEDBW: case ARM::t2RFEDB:
> -  case ARM::t2RFEIAW: case ARM::t2RFEIA:
> -    return true;
> -  }
> -}
> -
> -// t2SRS[IA|DB]W/t2SRS[IA|DB]: mode_imm = Inst{4-0}
> -static bool DisassembleThumb2SRS(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded) {
> -  MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
> -  NumOpsAdded = 1;
> -  return true;
> -}
> -
> -// t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
> -static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -  unsigned Rn = decodeRn(insn);
> -  if (Rn == 15) {
> -    DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
> -    return false;
> -  }
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,ARM::GPRRegClassID,Rn)));
> -  NumOpsAdded = 1;
> -  return true;
> -}
> -
> -static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  if (Thumb2SRSOpcode(Opcode))
> -    return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
> -
> -  if (Thumb2RFEOpcode(Opcode))
> -    return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -
> -  assert((Opcode == ARM::t2LDMIA || Opcode == ARM::t2LDMIA_UPD ||
> -          Opcode == ARM::t2LDMDB || Opcode == ARM::t2LDMDB_UPD ||
> -          Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
> -          Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
> -         && "Unexpected opcode");
> -  assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
> -
> -  NumOpsAdded = 0;
> -
> -  unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
> -
> -  // Writeback to base.
> -  if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD ||
> -      Opcode == ARM::t2STMIA_UPD || Opcode == ARM::t2STMDB_UPD) {
> -    MI.addOperand(MCOperand::CreateReg(Base));
> -    ++NumOpsAdded;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(Base));
> -  ++NumOpsAdded;
> -
> -  // Handling the two predicate operands before the reglist.
> -  if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
> -    NumOpsAdded += 2;
> -  } else {
> -    DEBUG(errs() << "Expected predicate operands not found.\n");
> -    return false;
> -  }
> -
> -  unsigned RegListBits = insn & ((1 << 16) - 1);
> -
> -  // Fill the variadic part of reglist.
> -  for (unsigned i = 0; i < 16; ++i)
> -    if ((RegListBits >> i) & 1) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                         i)));
> -      ++NumOpsAdded;
> -    }
> -
> -  return true;
> -}
> -
> -// t2LDREX: Rd Rn
> -// t2LDREXD: Rd Rs Rn
> -// t2LDREXB, t2LDREXH: Rd Rn
> -// t2STREX: Rs Rd Rn
> -// t2STREXD: Rm Rd Rs Rn
> -// t2STREXB, t2STREXH: Rm Rd Rn
> -static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2
> -         && OpInfo[0].RegClass > 0
> -         && OpInfo[1].RegClass > 0
> -         && "Expect >=2 operands and first two as reg operands");
> -
> -  bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
> -  bool isSW = (Opcode == ARM::t2LDREX || Opcode == ARM::t2STREX);
> -  bool isDW = (Opcode == ARM::t2LDREXD || Opcode == ARM::t2STREXD);
> -
> -  unsigned Rt  = decodeRd(insn);
> -  unsigned Rt2 = decodeRs(insn); // But note that this is Rd for t2STREX.
> -  unsigned Rd  = decodeRm(insn);
> -  unsigned Rn  = decodeRn(insn);
> -
> -  // Some sanity checking first.
> -  if (isStore) {
> -    // if d == n || d == t then UNPREDICTABLE
> -    // if d == n || d == t || d == t2 then UNPREDICTABLE
> -    if (isDW) {
> -      if (Rd == Rn || Rd == Rt || Rd == Rt2) {
> -        DEBUG(errs() << "if d == n || d == t || d == t2 then UNPREDICTABLE\n");
> -        return false;
> -      }
> -    } else {
> -      if (isSW) {
> -        if (Rt2 == Rn || Rt2 == Rt) {
> -          DEBUG(errs() << "if d == n || d == t then UNPREDICTABLE\n");
> -          return false;
> -        }
> -      } else {
> -        if (Rd == Rn || Rd == Rt) {
> -          DEBUG(errs() << "if d == n || d == t then UNPREDICTABLE\n");
> -          return false;
> -        }
> -      }
> -    }
> -  } else {
> -    // Load
> -    // A8.6.71 LDREXD
> -    // if t == t2 then UNPREDICTABLE
> -    if (isDW && Rt == Rt2) {
> -      DEBUG(errs() << "if t == t2 then UNPREDICTABLE\n");
> -      return false;
> -    }
> -  }
> -
> -  // Add the destination operand for store.
> -  if (isStore) {
> -    MI.addOperand(MCOperand::CreateReg(
> -                    getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                    isSW ? Rt2 : Rd)));
> -    ++OpIdx;
> -  }
> -
> -  // Source operand for store and destination operand for load.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     Rt)));
> -  ++OpIdx;
> -
> -  // Thumb2 doubleword complication: with an extra source/destination operand.
> -  if (isDW) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
> -                                                       Rt2)));
> -    ++OpIdx;
> -  }
> -
> -  // Finally add the pointer operand.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     Rn)));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
> -// t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
> -// t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
> -//
> -// Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
> -// disassembly only and do not have a tied_to writeback base register operand.
> -static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -  if (!OpInfo) return false;
> -
> -  // Thumnb allows for specifying Rt and Rt2, unlike ARM (which has Rt2==Rt+1).
> -  unsigned Rt  = decodeRd(insn);
> -  unsigned Rt2 = decodeRs(insn);
> -  unsigned Rn  = decodeRn(insn);
> -
> -  // Some sanity checking first.
> -
> -  // A8.6.67 LDRD (literal) has its W bit as (0).
> -  if (Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST) {
> -    if (Rn == 15 && slice(insn, 21, 21) != 0)
> -      return false;
> -  } else {
> -    // For Dual Store, PC cannot be used as the base register.
> -    if (Rn == 15) {
> -      DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
> -      return false;
> -    }
> -  }
> -  if (Rt == Rt2) {
> -    DEBUG(errs() << "if t == t2 then UNPREDICTABLE\n");
> -    return false;
> -  }
> -  if (Opcode != ARM::t2LDRDi8 && Opcode != ARM::t2STRDi8) {
> -    if (Rn == Rt || Rn == Rt2) {
> -      DEBUG(errs() << "if wback && (n == t || n == t2) then UNPREDICTABLE\n");
> -      return false;
> -    }
> -  }
> -
> -  // Add the <Rt> <Rt2> operands.
> -  unsigned RegClassPair = OpInfo[0].RegClass;
> -  unsigned RegClassBase = OpInfo[2].RegClass;
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
> -                                                     decodeRd(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
> -                                                     decodeRs(insn))));
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
> -                                                     decodeRn(insn))));
> -  unsigned Added = 4;
> -  switch (MI.getOpcode()) {
> -    case ARM::t2LDRD_PRE:
> -    case ARM::t2LDRD_POST:
> -    case ARM::t2STRD_PRE:
> -    case ARM::t2STRD_POST:
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
> -                                                         decodeRn(insn))));
> -      Added = 5;
> -    default:
> -      break;
> -  }
> -
> -  // Finally add (+/-)imm8*4, depending on the U bit.
> -  int Offset = getImm8(insn) * 4;
> -  if (getUBit(insn) == 0)
> -    Offset = -Offset;
> -  MI.addOperand(MCOperand::CreateImm(Offset));
> -  NumOpsAdded = Added;
> -
> -  return true;
> -}
> -
> -// t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
> -static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  assert(NumOps >= 2 && "Expect >= 2 operands");
> -
> -  // The generic version of TBB/TBH needs a base register.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  // Add the index register.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRm(insn))));
> -  NumOpsAdded = 2;
> -
> -  return true;
> -}
> -
> -static inline bool Thumb2ShiftOpcode(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return false;
> -  case ARM::t2MOVCClsl: case ARM::t2MOVCClsr:
> -  case ARM::t2MOVCCasr: case ARM::t2MOVCCror:
> -  case ARM::t2LSLri:    case ARM::t2LSRri:
> -  case ARM::t2ASRri:    case ARM::t2RORri:
> -    return true;
> -  }
> -}
> -
> -// A6.3.11 Data-processing (shifted register)
> -//
> -// Two register operands (Rn=0b1111 no 1st operand reg): Rs Rm
> -// Two register operands (Rs=0b1111 no dst operand reg): Rn Rm
> -// Three register operands: Rs Rn Rm
> -// Three register operands: (Rn=0b1111 Conditional Move) Rs Ro(TIED_TO) Rm
> -//
> -// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
> -// register with shift forms: (Rm, ConstantShiftSpecifier).
> -// Constant shift specifier: Imm = (ShOp | ShAmt<<3).
> -//
> -// There are special instructions, like t2MOVsra_flag and t2MOVsrl_flag, which
> -// only require two register operands: Rd, Rm in ARM Reference Manual terms, and
> -// nothing else, because the shift amount is already specified.
> -// Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
> -static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  // Special case handling.
> -  if (Opcode == ARM::t2BR_JT) {
> -    assert(NumOps == 4
> -           && OpInfo[0].RegClass == ARM::GPRRegClassID
> -           && OpInfo[1].RegClass == ARM::GPRRegClassID
> -           && OpInfo[2].RegClass < 0
> -           && OpInfo[3].RegClass < 0
> -           && "Exactly 4 operands expect and first two as reg operands");
> -    // Only need to populate the src reg operand.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -    MI.addOperand(MCOperand::CreateReg(0));
> -    MI.addOperand(MCOperand::CreateImm(0));
> -    MI.addOperand(MCOperand::CreateImm(0));
> -    NumOpsAdded = 4;
> -    return true;
> -  }
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2
> -         && (OpInfo[0].RegClass == ARM::GPRRegClassID ||
> -             OpInfo[0].RegClass == ARM::rGPRRegClassID)
> -         && (OpInfo[1].RegClass == ARM::GPRRegClassID ||
> -             OpInfo[1].RegClass == ARM::rGPRRegClassID)
> -         && "Expect >= 2 operands and first two as reg operands");
> -
> -  bool ThreeReg = (NumOps > 2 && (OpInfo[2].RegClass == ARM::GPRRegClassID ||
> -                                  OpInfo[2].RegClass == ARM::rGPRRegClassID));
> -  bool NoDstReg = (decodeRs(insn) == 0xF);
> -
> -  // Build the register operands, followed by the constant shift specifier.
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, OpInfo[0].RegClass,
> -                                  NoDstReg ? decodeRn(insn) : decodeRs(insn))));
> -  ++OpIdx;
> -
> -  if (ThreeReg) {
> -    int Idx;
> -    if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -      // Process tied_to operand constraint.
> -      MI.addOperand(MI.getOperand(Idx));
> -      ++OpIdx;
> -    } else if (!NoDstReg) {
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[1].RegClass,
> -                                                         decodeRn(insn))));
> -      ++OpIdx;
> -    } else {
> -      DEBUG(errs() << "Thumb2 encoding error: d==15 for three-reg operands.\n");
> -      return false;
> -    }
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeRm(insn))));
> -  ++OpIdx;
> -
> -  if (NumOps == OpIdx)
> -    return true;
> -
> -  if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
> -      && !OpInfo[OpIdx].isOptionalDef()) {
> -
> -    if (Thumb2ShiftOpcode(Opcode)) {
> -      unsigned Imm = getShiftAmtBits(insn);
> -      ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 5, 4));
> -      getImmShiftSE(ShOp, Imm);
> -      MI.addOperand(MCOperand::CreateImm(Imm));
> -    } else {
> -      // Build the constant shift specifier operand.
> -      unsigned imm5 = getShiftAmtBits(insn);
> -      // The PKHBT/PKHTB instructions have an implied shift type and so just
> -      // use a plain immediate for the amount.
> -      if (Opcode == ARM::t2PKHBT || Opcode == ARM::t2PKHTB)
> -        MI.addOperand(MCOperand::CreateImm(imm5));
> -      else {
> -        ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
> -        unsigned bits2 = getShiftTypeBits(insn);
> -        unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
> -        MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
> -      }
> -    }
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// A6.3.1 Data-processing (modified immediate)
> -//
> -// Two register operands: Rs Rn ModImm
> -// One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
> -// One register operands (Rn=0b1111 no explicit src reg): Rs ModImm -
> -// {t2MOVi, t2MVNi}
> -//
> -// ModImm = ThumbExpandImm(i:imm3:imm8)
> -static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  unsigned RdRegClassID = OpInfo[0].RegClass;
> -  assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
> -                         RdRegClassID == ARM::rGPRRegClassID)
> -         && "Expect >= 2 operands and first one as reg operand");
> -
> -  unsigned RnRegClassID = OpInfo[1].RegClass;
> -  bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
> -                 || RnRegClassID == ARM::rGPRRegClassID);
> -  bool NoDstReg = (decodeRs(insn) == 0xF);
> -
> -  // Build the register operands, followed by the modified immediate.
> -
> -  MI.addOperand(MCOperand::CreateReg(
> -                  getRegisterEnum(B, RdRegClassID,
> -                                  NoDstReg ? decodeRn(insn) : decodeRs(insn))));
> -  ++OpIdx;
> -
> -  if (TwoReg) {
> -    if (NoDstReg) {
> -      DEBUG(errs()<<"Thumb2 encoding error: d==15 for DPModImm 2-reg instr.\n");
> -      return false;
> -    }
> -    int Idx;
> -    if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -      // The reg operand is tied to the first reg operand.
> -      MI.addOperand(MI.getOperand(Idx));
> -    } else {
> -      // Add second reg operand.
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
> -                                                         decodeRn(insn))));
> -    }
> -    ++OpIdx;
> -  }
> -
> -  // The modified immediate operand should come next.
> -  assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
> -         !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
> -         && "Pure imm operand expected");
> -
> -  // i:imm3:imm8
> -  // A6.3.2 Modified immediate constants in Thumb instructions
> -  unsigned imm12 = getIImm3Imm8(insn);
> -  MI.addOperand(MCOperand::CreateImm(ThumbExpandImm(imm12)));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
> -  switch (Opcode) {
> -  case ARM::t2SSAT: case ARM::t2SSAT16:
> -  case ARM::t2USAT: case ARM::t2USAT16:
> -    return true;
> -  default:
> -    return false;
> -  }
> -}
> -
> -/// DisassembleThumb2Sat - Disassemble Thumb2 saturate instructions:
> -/// o t2SSAT, t2USAT: Rs sat_pos Rn shamt
> -/// o t2SSAT16, t2USAT16: Rs sat_pos Rn
> -static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
> -                                 unsigned &NumOpsAdded, BO B) {
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  NumOpsAdded = MCID.getNumOperands() - 2; // ignore predicate operands
> -
> -  // Disassemble the register def.
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRs(insn))));
> -
> -  unsigned Pos = slice(insn, 4, 0);
> -  MI.addOperand(MCOperand::CreateImm(Pos));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRn(insn))));
> -
> -  if (NumOpsAdded == 4) {
> -    // Inst{6} encodes the shift type.
> -    bool isASR = slice(insn, 6, 6);
> -    // Inst{11-7} encodes the imm5 shift amount.
> -    unsigned ShAmt = slice(insn, 11, 7);
> -    MI.addOperand(MCOperand::CreateImm(isASR << 5 | ShAmt));
> -  }
> -  return true;
> -}
> -
> -// A6.3.3 Data-processing (plain binary immediate)
> -//
> -// o t2ADDri12, t2SUBri12: Rs Rn imm12
> -// o t2LEApcrel (ADR): Rs imm12
> -// o t2BFC (BFC): Rs Ro(TIED_TO) bf_inv_mask_imm
> -// o t2BFI (BFI): Rs Ro(TIED_TO) Rn bf_inv_mask_imm
> -// o t2MOVi16: Rs imm16
> -// o t2MOVTi16: Rs imm16
> -// o t2SBFX (SBFX): Rs Rn lsb width
> -// o t2UBFX (UBFX): Rs Rn lsb width
> -// o t2BFI (BFI): Rs Rn lsb width
> -static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  unsigned RdRegClassID = OpInfo[0].RegClass;
> -  assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
> -                         RdRegClassID == ARM::rGPRRegClassID)
> -         && "Expect >= 2 operands and first one as reg operand");
> -
> -  unsigned RnRegClassID = OpInfo[1].RegClass;
> -  bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
> -                 || RnRegClassID == ARM::rGPRRegClassID);
> -
> -  // Build the register operand(s), followed by the immediate(s).
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RdRegClassID,
> -                                                     decodeRs(insn))));
> -  ++OpIdx;
> -
> -  if (TwoReg) {
> -    assert(NumOps >= 3 && "Expect >= 3 operands");
> -    int Idx;
> -    if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
> -      // Process tied_to operand constraint.
> -      MI.addOperand(MI.getOperand(Idx));
> -    } else {
> -      // Add src reg operand.
> -      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
> -                                                         decodeRn(insn))));
> -    }
> -    ++OpIdx;
> -  }
> -
> -  if (Opcode == ARM::t2BFI) {
> -    // Add val reg operand.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
> -         && !OpInfo[OpIdx].isOptionalDef()
> -         && "Pure imm operand expected");
> -
> -  // Pre-increment OpIdx.
> -  ++OpIdx;
> -
> -  if (Opcode == ARM::t2ADDri12 || Opcode == ARM::t2SUBri12
> -      || Opcode == ARM::t2LEApcrel)
> -    MI.addOperand(MCOperand::CreateImm(getIImm3Imm8(insn)));
> -  else if (Opcode == ARM::t2MOVi16 || Opcode == ARM::t2MOVTi16) {
> -    if (!B->tryAddingSymbolicOperand(getImm16(insn), 4, MI))
> -      MI.addOperand(MCOperand::CreateImm(getImm16(insn)));
> -  } else if (Opcode == ARM::t2BFC || Opcode == ARM::t2BFI) {
> -    uint32_t mask = 0;
> -    if (getBitfieldInvMask(insn, mask))
> -      MI.addOperand(MCOperand::CreateImm(mask));
> -    else
> -      return false;
> -  } else {
> -    // Handle the case of: lsb width
> -    assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
> -            && "Unexpected opcode");
> -    MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
> -    MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn)));
> -
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// A6.3.4 Table A6-15 Miscellaneous control instructions
> -// A8.6.41 DMB
> -// A8.6.42 DSB
> -// A8.6.49 ISB
> -static inline bool t2MiscCtrlInstr(uint32_t insn) {
> -  if (slice(insn, 31, 20) == 0xf3b && slice(insn, 15, 14) == 2 &&
> -      slice(insn, 12, 12) == 0)
> -    return true;
> -
> -  return false;
> -}
> -
> -// A6.3.4 Branches and miscellaneous control
> -//
> -// A8.6.16 B
> -// Branches: t2B, t2Bcc -> imm operand
> -//
> -// Branches: t2TPsoft -> no operand
> -//
> -// A8.6.23 BL, BLX (immediate)
> -// Branches (defined in ARMInstrThumb.td): tBL, tBLXi -> imm operand
> -//
> -// A8.6.26
> -// t2BXJ -> Rn
> -//
> -// Miscellaneous control:
> -//   -> no operand (except pred-imm pred-ccr for CLREX, memory barrier variants)
> -//
> -// Hint: t2NOP, t2YIELD, t2WFE, t2WFI, t2SEV
> -//   -> no operand (except pred-imm pred-ccr)
> -//
> -// t2DBG -> imm4 = Inst{3-0}
> -//
> -// t2MRS/t2MRSsys -> Rs
> -// t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
> -// t2SMC -> imm4 = Inst{19-16}
> -static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  if (NumOps == 0)
> -    return true;
> -
> -  if (Opcode == ARM::t2DMB || Opcode == ARM::t2DSB) {
> -    // Inst{3-0} encodes the memory barrier option for the variants.
> -    unsigned opt = slice(insn, 3, 0);
> -    switch (opt) {
> -    case ARM_MB::SY:  case ARM_MB::ST:
> -    case ARM_MB::ISH: case ARM_MB::ISHST:
> -    case ARM_MB::NSH: case ARM_MB::NSHST:
> -    case ARM_MB::OSH: case ARM_MB::OSHST:
> -      MI.addOperand(MCOperand::CreateImm(opt));
> -      NumOpsAdded = 1;
> -      return true;
> -    default:
> -      return false;
> -    }
> -  }
> -
> -  if (t2MiscCtrlInstr(insn))
> -    return true;
> -
> -  switch (Opcode) {
> -  case ARM::t2CLREX:
> -  case ARM::t2NOP:
> -  case ARM::t2YIELD:
> -  case ARM::t2WFE:
> -  case ARM::t2WFI:
> -  case ARM::t2SEV:
> -    return true;
> -  default:
> -    break;
> -  }
> -
> -  // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
> -  // opcodes which match the same real instruction. This is needed since there's
> -  // no current handling of optional arguments. Fix here when a better handling
> -  // of optional arguments is implemented.
> -  if (Opcode == ARM::t2CPS3p) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5)));  // iflags
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));  // mode
> -    NumOpsAdded = 3;
> -    return true;
> -  }
> -  if (Opcode == ARM::t2CPS2p) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5)));  // iflags
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -  if (Opcode == ARM::t2CPS1p) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  // DBG has its option specified in Inst{3-0}.
> -  if (Opcode == ARM::t2DBG) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  // MRS and MRSsys take one GPR reg Rs.
> -  if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRs(insn))));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -  // BXJ takes one GPR reg Rn.
> -  if (Opcode == ARM::t2BXJ) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -  // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
> -  // bit 4, and the special register fields in bits 3-0.
> -  if (Opcode == ARM::t2MSR) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
> -                                       slice(insn, 11, 8) /* Special Reg */));
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRn(insn))));
> -    NumOpsAdded = 2;
> -    return true;
> -  }
> -  // SMC take imm4.
> -  if (Opcode == ARM::t2SMC) {
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
> -    NumOpsAdded = 1;
> -    return true;
> -  }
> -
> -  // Some instructions have predicate operands first before the immediate.
> -  if (Opcode == ARM::tBLXi || Opcode == ARM::tBL) {
> -    // Handling the two predicate operands before the imm operand.
> -    if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
> -      NumOpsAdded += 2;
> -    else {
> -      DEBUG(errs() << "Expected predicate operands not found.\n");
> -      return false;
> -    }
> -  }
> -
> -  // Add the imm operand.
> -  int Offset = 0;
> -
> -  switch (Opcode) {
> -  default:
> -    assert(0 && "Unexpected opcode");
> -    return false;
> -  case ARM::t2B:
> -    Offset = decodeImm32_B_EncodingT4(insn);
> -    break;
> -  case ARM::t2Bcc:
> -    Offset = decodeImm32_B_EncodingT3(insn);
> -    break;
> -  case ARM::tBL:
> -    Offset = decodeImm32_BL(insn);
> -    break;
> -  case ARM::tBLXi:
> -    Offset = decodeImm32_BLX(insn);
> -    break;
> -  }
> -
> -  if (!B->tryAddingSymbolicOperand(Offset + B->getBuilderAddress() + 4, 4, MI))
> -    MI.addOperand(MCOperand::CreateImm(Offset));
> -
> -  // This is an increment as some predicate operands may have been added first.
> -  NumOpsAdded += 1;
> -
> -  return true;
> -}
> -
> -static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
> -  switch (Opcode) {
> -  default:
> -    return false;
> -  case ARM::t2PLDi12:   case ARM::t2PLDi8:
> -  case ARM::t2PLDs:
> -  case ARM::t2PLDWi12:  case ARM::t2PLDWi8:
> -  case ARM::t2PLDWs:
> -  case ARM::t2PLIi12:   case ARM::t2PLIi8:
> -  case ARM::t2PLIs:
> -    return true;
> -  }
> -}
> -
> -static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  // Preload Data/Instruction requires either 2 or 3 operands.
> -  // t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
> -  // t2PLDr:                      Rn Rm
> -  // t2PLDs:                      Rn Rm imm2=Inst{5-4}
> -  // Same pattern applies for t2PLDW* and t2PLI*.
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2 &&
> -         OpInfo[0].RegClass == ARM::GPRRegClassID &&
> -         "Expect >= 2 operands and first one as reg operand");
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                     decodeRn(insn))));
> -  ++OpIdx;
> -
> -  if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
> -                                                       decodeRm(insn))));
> -  } else {
> -    assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
> -           && !OpInfo[OpIdx].isOptionalDef()
> -           && "Pure imm operand expected");
> -    int Offset = 0;
> -    if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
> -        Opcode == ARM::t2PLIi8) {
> -      // A8.6.117 Encoding T2: add = FALSE
> -      unsigned Imm8 = getImm8(insn);
> -      Offset = -1 * Imm8;
> -    } else {
> -      // The i12 forms.  See, for example, A8.6.117 Encoding T1.
> -      // Note that currently t2PLDi12 also handles the previously named t2PLDpci
> -      // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
> -      Offset = decodeImm12(insn);
> -    }
> -    MI.addOperand(MCOperand::CreateImm(Offset));
> -  }
> -  ++OpIdx;
> -
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
> -      !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -    // Fills in the shift amount for t2PLDs, t2PLDWs, t2PLIs.
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -static bool BadRegsThumb2LdSt(unsigned Opcode, uint32_t insn, bool Load,
> -      unsigned R0, unsigned R1, unsigned R2, bool UseRm, bool WB) {
> -
> -  // Inst{22-21} encodes the data item transferred for load/store.
> -  // For single word, it is encoded as ob10.
> -  bool Word = (slice(insn, 22, 21) == 2);
> -  bool Half = (slice(insn, 22, 21) == 1);
> -  bool Byte = (slice(insn, 22, 21) == 0);
> -
> -  if (UseRm && BadReg(R2)) {
> -    DEBUG(errs() << "if BadReg(m) then UNPREDICTABLE\n");
> -    return true;
> -  }
> -
> -  if (Load) {
> -    if (!Word && R0 == 13) {
> -      DEBUG(errs() << "if t == 13 then UNPREDICTABLE\n");
> -      return true;
> -    }
> -    if (Byte) {
> -      if (WB && R0 == 15 && slice(insn, 10, 8) == 3)  {
> -        // A8.6.78 LDRSB (immediate) Encoding T2 (errata markup 8.0)
> -        DEBUG(errs() << "if t == 15 && PUW == '011' then UNPREDICTABLE\n");
> -        return true;
> -      }
> -    }
> -    // A6.3.8 Load halfword, memory hints
> -    if (Half) {
> -      if (WB) {
> -        if (R0 == R1)  {
> -          // A8.6.82 LDRSH (immediate) Encoding T2
> -          DEBUG(errs() << "if WB && n == t then UNPREDICTABLE\n");
> -          return true;
> -        }
> -        if (R0 == 15 && slice(insn, 10, 8) == 3)  {
> -          // A8.6.82 LDRSH (immediate) Encoding T2 (errata markup 8.0)
> -          DEBUG(errs() << "if t == 15 && PUW == '011' then UNPREDICTABLE\n");
> -          return true;
> -        }
> -      } else {
> -        if (Opcode == ARM::t2LDRHi8 || Opcode == ARM::t2LDRSHi8) {
> -          if (R0 == 15 && slice(insn, 10, 8) == 4) {
> -            // A8.6.82 LDRSH (immediate) Encoding T2
> -            DEBUG(errs() << "if Rt == '1111' and PUW == '100' then SEE"
> -                         << " \"Unallocated memory hints\"\n");
> -            return true;
> -          }
> -        } else {
> -          if (R0 == 15) {
> -            // A8.6.82 LDRSH (immediate) Encoding T1
> -            DEBUG(errs() << "if Rt == '1111' then SEE"
> -                         << " \"Unallocated memory hints\"\n");
> -            return true;
> -          }
> -        }
> -      }
> -    }
> -  } else {
> -    if (WB && R0 == R1) {
> -      DEBUG(errs() << "if wback && n == t then UNPREDICTABLE\n");
> -      return true;
> -    }
> -    if ((WB && R0 == 15) || (!WB && R1 == 15)) {
> -      DEBUG(errs() << "if Rn == '1111' then UNDEFINED\n");
> -      return true;
> -    }
> -    if (Word) {
> -      if ((WB && R1 == 15) || (!WB && R0 == 15)) {
> -        DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
> -        return true;
> -      }
> -    } else {
> -      if ((WB && BadReg(R1)) || (!WB && BadReg(R0))) {
> -        DEBUG(errs() << "if BadReg(t) then UNPREDICTABLE\n");
> -        return true;
> -      }
> -    }
> -  }
> -  return false;
> -}
> -
> -// A6.3.10 Store single data item
> -// A6.3.9 Load byte, memory hints
> -// A6.3.8 Load halfword, memory hints
> -// A6.3.7 Load word
> -//
> -// For example,
> -//
> -// t2LDRi12:   Rd Rn (+)imm12
> -// t2LDRi8:    Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
> -// t2LDRs:     Rd Rn Rm ConstantShiftSpecifier (see also
> -//             DisassembleThumb2DPSoReg)
> -// t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
> -// t2LDR_PRE:  Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
> -//
> -// t2STRi12:   Rd Rn (+)imm12
> -// t2STRi8:    Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
> -// t2STRs:     Rd Rn Rm ConstantShiftSpecifier (see also
> -//             DisassembleThumb2DPSoReg)
> -// t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
> -// t2STR_PRE:  Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
> -//
> -// Note that for indexed modes, the Rn(TIED_TO) operand needs to be populated
> -// correctly, as LLVM AsmPrinter depends on it.  For indexed stores, the first
> -// operand is Rn; for all the other instructions, Rd is the first operand.
> -//
> -// Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
> -// Delegates to DisassembleThumb2Ldpci() for load * literal operations.
> -static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
> -    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  unsigned Rn = decodeRn(insn);
> -
> -  if (Thumb2PreloadOpcode(Opcode))
> -    return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -
> -  // See, for example, A6.3.7 Load word: Table A6-18 Load word.
> -  if (Load && Rn == 15)
> -    return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 3 &&
> -         OpInfo[0].RegClass > 0 &&
> -         OpInfo[1].RegClass > 0 &&
> -         "Expect >= 3 operands and first two as reg operands");
> -
> -  bool ThreeReg = (OpInfo[2].RegClass > 0);
> -  bool TIED_TO = ThreeReg && MCID.getOperandConstraint(2, MCOI::TIED_TO) != -1;
> -  bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
> -
> -  // Build the register operands, followed by the immediate.
> -  unsigned R0 = 0, R1 = 0, R2 = 0;
> -  unsigned Rd = decodeRd(insn);
> -  int Imm = 0;
> -
> -  if (!Load && TIED_TO) {
> -    R0 = Rn;
> -    R1 = Rd;
> -  } else {
> -    R0 = Rd;
> -    R1 = Rn;
> -  }
> -  if (ThreeReg) {
> -    if (TIED_TO) {
> -      R2 = Rn;
> -      Imm = decodeImm8(insn);
> -    } else {
> -      R2 = decodeRm(insn);
> -      // See, for example, A8.6.64 LDRB (register).
> -      // And ARMAsmPrinter::printT2AddrModeSoRegOperand().
> -      // LSL is the default shift opc, and LLVM does not expect it to be encoded
> -      // as part of the immediate operand.
> -      // Imm = ARM_AM::getSORegOpc(ARM_AM::lsl, slice(insn, 5, 4));
> -      Imm = slice(insn, 5, 4);
> -    }
> -  } else {
> -    if (Imm12)
> -      Imm = getImm12(insn);
> -    else
> -      Imm = decodeImm8(insn);
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     R0)));
> -  ++OpIdx;
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     R1)));
> -  ++OpIdx;
> -
> -  if (ThreeReg) {
> -    // This could be an offset register or a TIED_TO register.
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
> -                                                       R2)));
> -    ++OpIdx;
> -  }
> -
> -  if (BadRegsThumb2LdSt(Opcode, insn, Load, R0, R1, R2, ThreeReg & !TIED_TO,
> -                        TIED_TO))
> -    return false;
> -
> -  assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
> -         && !OpInfo[OpIdx].isOptionalDef()
> -         && "Pure imm operand expected");
> -
> -  MI.addOperand(MCOperand::CreateImm(Imm));
> -  ++OpIdx;
> -
> -  return true;
> -}
> -
> -// A6.3.12 Data-processing (register)
> -//
> -// Two register operands [rotate]:   Rs Rm [rotation(= (rotate:'000'))]
> -// Three register operands only:     Rs Rn Rm
> -// Three register operands [rotate]: Rs Rn Rm [rotation(= (rotate:'000'))]
> -//
> -// Parallel addition and subtraction 32-bit Thumb instructions: Rs Rn Rm
> -//
> -// Miscellaneous operations: Rs [Rn] Rm
> -static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCInstrDesc &MCID = ARMInsts[Opcode];
> -  const MCOperandInfo *OpInfo = MCID.OpInfo;
> -  unsigned &OpIdx = NumOpsAdded;
> -
> -  OpIdx = 0;
> -
> -  assert(NumOps >= 2 &&
> -         OpInfo[0].RegClass > 0 &&
> -         OpInfo[1].RegClass > 0 &&
> -         "Expect >= 2 operands and first two as reg operands");
> -
> -  // Build the register operands, followed by the optional rotation amount.
> -
> -  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeRs(insn))));
> -  ++OpIdx;
> -
> -  if (ThreeReg) {
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
> -                                                       decodeRn(insn))));
> -    ++OpIdx;
> -  }
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
> -                                                     decodeRm(insn))));
> -  ++OpIdx;
> -
> -  if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
> -      && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
> -    // Add the rotation amount immediate.
> -    MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
> -    ++OpIdx;
> -  }
> -
> -  return true;
> -}
> -
> -// A6.3.16 Multiply, multiply accumulate, and absolute difference
> -//
> -// t2MLA, t2MLS, t2SMMLA, t2SMMLS: Rs Rn Rm Ra=Inst{15-12}
> -// t2MUL, t2SMMUL:                 Rs Rn Rm
> -// t2SMLA[BB|BT|TB|TT|WB|WT]:      Rs Rn Rm Ra=Inst{15-12}
> -// t2SMUL[BB|BT|TB|TT|WB|WT]:      Rs Rn Rm
> -//
> -// Dual halfword multiply: t2SMUAD[X], t2SMUSD[X], t2SMLAD[X], t2SMLSD[X]:
> -//   Rs Rn Rm Ra=Inst{15-12}
> -//
> -// Unsigned Sum of Absolute Differences [and Accumulate]
> -//    Rs Rn Rm [Ra=Inst{15-12}]
> -static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -
> -  assert(NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::rGPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::rGPRRegClassID &&
> -         OpInfo[2].RegClass == ARM::rGPRRegClassID &&
> -         "Expect >= 3 operands and first three as reg operands");
> -
> -  // Build the register operands.
> -
> -  bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRs(insn))));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRn(insn))));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRm(insn))));
> -
> -  if (FourReg)
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                       decodeRd(insn))));
> -
> -  NumOpsAdded = FourReg ? 4 : 3;
> -
> -  return true;
> -}
> -
> -// A6.3.17 Long multiply, long multiply accumulate, and divide
> -//
> -// t2SMULL, t2UMULL, t2SMLAL, t2UMLAL, t2UMAAL: RdLo RdHi Rn Rm
> -// where RdLo = Inst{15-12} and RdHi = Inst{11-8}
> -//
> -// Halfword multiple accumulate long: t2SMLAL<x><y>: RdLo RdHi Rn Rm
> -// where RdLo = Inst{15-12} and RdHi = Inst{11-8}
> -//
> -// Dual halfword multiple: t2SMLALD[X], t2SMLSLD[X]: RdLo RdHi Rn Rm
> -// where RdLo = Inst{15-12} and RdHi = Inst{11-8}
> -//
> -// Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
> -static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
> -
> -  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
> -
> -  assert(NumOps >= 3 &&
> -         OpInfo[0].RegClass == ARM::rGPRRegClassID &&
> -         OpInfo[1].RegClass == ARM::rGPRRegClassID &&
> -         OpInfo[2].RegClass == ARM::rGPRRegClassID &&
> -         "Expect >= 3 operands and first three as reg operands");
> -
> -  bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
> -
> -  // Build the register operands.
> -
> -  if (FourReg)
> -    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                       decodeRd(insn))));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRs(insn))));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRn(insn))));
> -
> -  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
> -                                                     decodeRm(insn))));
> -
> -  if (FourReg)
> -    NumOpsAdded = 4;
> -  else
> -    NumOpsAdded = 3;
> -
> -  return true;
> -}
> -
> -// See A6.3 32-bit Thumb instruction encoding for instruction classes
> -// corresponding to (op1, op2, op).
> -//
> -// Table A6-9 32-bit Thumb instruction encoding
> -// op1  op2    op  Instruction class, see
> -// ---  -------  --  -----------------------------------------------------------
> -// 01  00xx0xx  -  Load/store multiple on page A6-23
> -//     00xx1xx  -  Load/store dual, load/store exclusive, table branch on
> -//                 page A6-24
> -//     01xxxxx  -  Data-processing (shifted register) on page A6-31
> -//     1xxxxxx  -  Coprocessor instructions on page A6-40
> -// 10  x0xxxxx  0  Data-processing (modified immediate) on page A6-15
> -//     x1xxxxx  0  Data-processing (plain binary immediate) on page A6-19
> -//         -    1  Branches and miscellaneous control on page A6-20
> -// 11  000xxx0  -  Store single data item on page A6-30
> -//     001xxx0  -  Advanced SIMD element or structure load/store instructions
> -//                 on page A7-27
> -//     00xx001  - Load byte, memory hints on page A6-28
> -//     00xx011  -  Load halfword, memory hints on page A6-26
> -//     00xx101  -  Load word on page A6-25
> -//     00xx111  -  UNDEFINED
> -//     010xxxx  -  Data-processing (register) on page A6-33
> -//     0110xxx  -  Multiply, multiply accumulate, and absolute difference on
> -//                 page A6-38
> -//     0111xxx  -  Long multiply, long multiply accumulate, and divide on
> -//                 page A6-39
> -//     1xxxxxx  -  Coprocessor instructions on page A6-40
> -//
> -static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
> -    MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
> -    unsigned &NumOpsAdded, BO B) {
> -
> -  switch (op1) {
> -  case 1:
> -    if (slice(op2, 6, 5) == 0) {
> -      if (slice(op2, 2, 2) == 0) {
> -        // Load/store multiple.
> -        return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                        B);
> -      }
> -
> -      // Load/store dual, load/store exclusive, table branch, otherwise.
> -      assert(slice(op2, 2, 2) == 1 && "Thumb2 encoding error!");
> -      if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
> -          (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
> -        // Load/store exclusive.
> -        return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                       B);
> -      }
> -      if (Opcode == ARM::t2LDRDi8 ||
> -          Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
> -          Opcode == ARM::t2STRDi8 ||
> -          Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
> -        // Load/store dual.
> -        return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                         B);
> -      }
> -      if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
> -        // Table branch.
> -        return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      }
> -    } else if (slice(op2, 6, 5) == 1) {
> -      // Data-processing (shifted register).
> -      return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -    }
> -
> -    // FIXME: A6.3.18 Coprocessor instructions
> -    // But see ThumbDisassembler::getInstruction().
> -
> -    break;
> -  case 2:
> -    if (op == 0) {
> -      if (slice(op2, 5, 5) == 0)
> -        // Data-processing (modified immediate)
> -        return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                         B);
> -      if (Thumb2SaturateOpcode(Opcode))
> -        return DisassembleThumb2Sat(MI, Opcode, insn, NumOpsAdded, B);
> -
> -      // Data-processing (plain binary immediate)
> -      return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                       B);
> -    }
> -    // Branches and miscellaneous control on page A6-20.
> -    return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                       B);
> -  case 3:
> -    switch (slice(op2, 6, 5)) {
> -    case 0:
> -      // Load/store instructions...
> -      if (slice(op2, 0, 0) == 0) {
> -        if (slice(op2, 4, 4) == 0) {
> -          // Store single data item on page A6-30
> -          return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
> -                                       B);
> -        } else {
> -          // FIXME: Advanced SIMD element or structure load/store instructions.
> -          // But see ThumbDisassembler::getInstruction().
> -          ;
> -        }
> -      } else {
> -        // Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
> -        return DisassembleThumb2LdSt(true, MI, Opcode, insn, NumOps,
> -                                     NumOpsAdded, B);
> -      }
> -      break;
> -    case 1:
> -      if (slice(op2, 4, 4) == 0) {
> -        // A6.3.12 Data-processing (register)
> -        return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      } else if (slice(op2, 3, 3) == 0) {
> -        // A6.3.16 Multiply, multiply accumulate, and absolute difference
> -        return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
> -      } else {
> -        // A6.3.17 Long multiply, long multiply accumulate, and divide
> -        return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
> -                                        B);
> -      }
> -      break;
> -    default:
> -      // FIXME: A6.3.18 Coprocessor instructions
> -      // But see ThumbDisassembler::getInstruction().
> -      ;
> -      break;
> -    }
> -
> -    break;
> -  default:
> -    assert(0 && "Thumb2 encoding error!");
> -    break;
> -  }
> -
> -  return false;
> -}
> -
> -static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
> -    unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
> -
> -  uint16_t HalfWord = slice(insn, 31, 16);
> -
> -  if (HalfWord == 0) {
> -    // A6.2 16-bit Thumb instruction encoding
> -    // op = bits[15:10]
> -    uint16_t op = slice(insn, 15, 10);
> -    return DisassembleThumb1(op, MI, Opcode, insn, NumOps, NumOpsAdded,
> -                             Builder);
> -  }
> -
> -  unsigned bits15_11 = slice(HalfWord, 15, 11);
> -
> -  // A6.1 Thumb instruction set encoding
> -  if (!(bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F)) {
> -    assert("Bits[15:11] first halfword of Thumb2 instruction is out of range");
> -    return false;
> -  }
> -
> -  // A6.3 32-bit Thumb instruction encoding
> -
> -  uint16_t op1 = slice(HalfWord, 12, 11);
> -  uint16_t op2 = slice(HalfWord, 10, 4);
> -  uint16_t op = slice(insn, 15, 15);
> -
> -  return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,
> -                           Builder);
> -}
> 
> Modified: llvm/trunk/lib/Target/ARM/Makefile
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Makefile?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Makefile (original)
> +++ llvm/trunk/lib/Target/ARM/Makefile Tue Aug  9 15:55:18 2011
> @@ -18,7 +18,7 @@
>                 ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
>                 ARMGenDecoderTables.inc ARMGenEDInfo.inc \
>                 ARMGenFastISel.inc ARMGenMCCodeEmitter.inc \
> -        ARMGenMCPseudoLowering.inc
> +        ARMGenMCPseudoLowering.inc ARMGenDisassemblerTables.inc
> 
> DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
> 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Aug  9 15:55:18 2011
> @@ -60,11 +60,14 @@
> # CHECK:    ldrh    r0, [r2], #0
> 0xb0 0x00 0xd2 0xe0
> 
> +# CHECK:    ldrh    r0, [r2]
> +0xb0 0x00 0xd2 0xe1
> +
> # CHECK:    ldrht    r0, [r2], #15
> 0xbf 0x00 0xf2 0xe0
> 
> # CHECK:    ldrsbtvs    lr, [r2], -r9
> -0xd9 0xe9 0x32 0x60
> +0xd9 0xe0 0x32 0x60
> 
> # CHECK:    lsls    r0, r2, #31
> 0x82 0x0f 0xb0 0xe1
> @@ -177,7 +180,7 @@
> 0x15 0xff 0x2f 0x01
> 
> # CHECK:    uqadd16mi    r6, r11, r8
> -0x18 0x60 0x6b 0x46
> +0x18 0x6F 0x6b 0x46
> 
> # CHECK:    str    r0, [sp, #4]
> 0x04 0x00 0x8d 0xe5
> @@ -230,7 +233,7 @@
> # CHECK:    umull    r1, r2, r3, r4
> 0x93 0x14 0x82 0xe0
> 
> -# CHECK:    pld    [pc, #-0]
> +# CHECK:    pldw    [pc, #-0]
> 0x00 0xf0 0x1f 0xf5
> 
> # CHECK:    pli    [pc, #-0]
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-BFI-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-BFI-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-BFI-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-BFI-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,8 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=60 Name=BFI Format=ARM_FORMAT_DPFRM(4)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 0| 0: 1: 1: 1| 1: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 1| 0: 1: 1: 0|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,10 +1,11 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=2249 Name=tBcc Format=ARM_FORMAT_THUMBFRM(25)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 1: 0: 1| 1: 1: 1: 0| 0: 1: 1: 0| 1: 1: 1: 1|
> # -------------------------------------------------------------------------------------------------
> -# 
> +#
> # if cond = '1110' then UNDEFINED
> 0x6f 0xde
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # invalid imod value (0b01)
> 0xc0 0x67 0x4 0xf1
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # invalid (imod, M, iflags) combination
> 0x93 0x1c 0x02 0xf1
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1908 Name=t2DMB Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-DSB-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-DSB-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-DSB-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-DSB-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=102 Name=DSB Format=ARM_FORMAT_MISCFRM(26)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=0 Name=PHI Format=(42)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 0: 1| 1: 1: 0: 0| 0: 0: 0: 1| 1: 1: 1: 1| 1: 0: 1: 1| 0: 1: 0: 0| 1: 0: 0: 1| 0: 0: 1: 0|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=140 Name=LDRB_POST Format=ARM_FORMAT_LDFRM(6)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1930 Name=t2LDRD_PRE Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=0 Name=PHI Format=(42)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 0| 0: 1: 1: 0| 0: 0: 1: 1| 0: 1: 1: 1| 0: 1: 0: 1| 0: 0: 0: 1| 0: 0: 0: 1| 0: 0: 0: 0|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # LDR_PRE/POST has encoding Inst{4} = 0.
> 0xde 0x69 0x18 0x46
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=165 Name=LDR_PRE Format=ARM_FORMAT_LDFRM(6)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-LSL-regform.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LSL-regform.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LSL-regform.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LSL-regform.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=196 Name=MOVs Format=ARM_FORMAT_DPSOREGFRM(5)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-MCR-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MCR-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MCR-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MCR-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=171 Name=MCR Format=ARM_FORMAT_BRFRM(2)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 0: 0: 1: 0| 1: 1: 1: 0| 1: 0: 1: 0| 0: 0: 0: 0| 0: 0: 0: 1| 1: 0: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=185 Name=MOVTi16 Format=ARM_FORMAT_DPFRM(4)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=0 Name=PHI Format=(42)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| 1: 1: 0: 0| 1: 1: 0: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 1: 0|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=196 Name=MOVs Format=ARM_FORMAT_DPSOREGFRM(5)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 0: 1| 0: 0: 0: 1| 1: 0: 1: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 0: 1: 0| 1: 0: 0: 1| 0: 0: 1: 1|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=0 Name=PHI Format=(42)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| 1: 1: 0: 0| 1: 1: 0: 1| 0: 0: 0: 1| 0: 0: 0: 0| 0: 0: 1: 0|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=206 Name=MSRi Format=ARM_FORMAT_BRFRM(2)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=134 Name=LDMIA Format=ARM_FORMAT_LDSTMULFRM(10)
> -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 1: 0: 0: 0| 1: 0: 0: 1| 1: 0: 0: 1| 1: 0: 1: 1| 0: 0: 0: 1| 0: 0: 1: 1| 0: 0: 1: 0|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-RSC-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-RSC-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-RSC-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-RSC-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=261 Name=RSCrs Format=ARM_FORMAT_DPSOREGFRM(5)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=271 Name=SBFX Format=ARM_FORMAT_DPFRM(4)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=284 Name=SMLAD Format=ARM_FORMAT_MULFRM(1)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-SRS-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-SRS-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-SRS-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-SRS-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,7 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=0 Name=PHI Format=(42)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 1: 0: 0: 0| 1: 1: 0: 0| 0: 1: 0: 1| 0: 0: 0: 1| 1: 1: 0: 0| 1: 0: 0: 0| 0: 0: 1: 1|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=322 Name=SSAT Format=ARM_FORMAT_SATFRM(13)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=2313 Name=tSTMIA_UPD Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=355 Name=STRBrs Format=ARM_FORMAT_STFRM(7)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=390 Name=SXTBr_rot Format=ARM_FORMAT_EXTFRM(14)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,11 +1,11 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=419 Name=UMAAL Format=ARM_FORMAT_MULFRM(1)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 0: 0: 0: 0| 0: 1: 0: 0| 1: 1: 1: 1| 1: 0: 1: 1| 1: 1: 1: 1| 1: 0: 0: 1| 1: 0: 0: 0|
> # -------------------------------------------------------------------------------------------------
> #
> # A8.6.244 UMAAL
> # if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
> -0x98 0xbf 0x4f 0xf0 
> +0x98 0xbf 0x4f 0xf0
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=426 Name=UQADD8 Format=ARM_FORMAT_DPFRM(4)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=737 Name=VLD1DUPq8_UPD Format=ARM_FORMAT_NLdSt(30)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,11 +1,11 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=871 Name=VLD3DUPd32_UPD Format=ARM_FORMAT_NLdSt(30)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 0: 1: 0: 0| 1: 0: 1: 0| 0: 0: 1: 0| 0: 0: 1: 0| 1: 1: 1: 0| 1: 0: 0: 1| 0: 0: 1: 0|
> # -------------------------------------------------------------------------------------------------
> -# 
> +#
> # A8.6.315 VLD3 (single 3-element structure to all lanes)
> # The a bit must be encoded as 0.
> 0xa2 0xf9 0x92 0x2e
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # core registers out of range
> 0xa5 0xba 0x72 0xed
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1225 Name=VQADDsv16i8 Format=ARM_FORMAT_N3Reg(37)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt Tue Aug  9 15:55:18 2011
> @@ -1,7 +1,8 @@
> # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1641 Name=VST2b32_UPD Format=ARM_FORMAT_NLdSt(30)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 0: 1: 0: 0| 0: 0: 0: 0| 0: 0: 1: 1| 0: 0: 0: 0| 1: 0: 0: 1| 1: 0: 1: 1| 0: 0: 1: 1|
> # -------------------------------------------------------------------------------------------------
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1894 Name=t2Bcc Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,10 +1,10 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=1922 Name=t2LDRBT Format=ARM_FORMAT_THUMBFRM(25)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 1| 1: 0: 0: 0| 0: 0: 0: 1| 0: 0: 0: 0| 1: 1: 1: 1| 1: 1: 1: 0| 0: 0: 0: 0| 0: 0: 1: 1|
> # -------------------------------------------------------------------------------------------------
> -# 
> +#
> # The unpriviledged Load/Store cannot have SP or PC as Rt.
> 0x10 0xf8 0x3 0xfe
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1934 Name=t2LDREXD Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1953 Name=t2LDRSHi12 Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=1954 Name=t2LDRSHi8 Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=2124 Name=t2STRD_PRE Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=2127 Name=t2STREXB Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,10 +1,10 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> 
> # Opcode=2128 Name=t2STREXD Format=ARM_FORMAT_THUMBFRM(25)
> -#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> +#  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
> # -------------------------------------------------------------------------------------------------
> # | 1: 1: 1: 0| 1: 0: 0: 0| 1: 1: 0: 0| 0: 0: 1: 0| 0: 1: 1: 1| 1: 0: 0: 0| 0: 1: 1: 1| 1: 0: 0: 0|
> # -------------------------------------------------------------------------------------------------
> -# 
> +#
> # if d == n || d == t || d == t2 then UNPREDICTABLE
> mc-input.txt:1:1: warning: invalid instruction encoding
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt Tue Aug  9 15:55:18 2011
> @@ -1,4 +1,5 @@
> # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding}
> +# XFAIL: *
> 
> # Opcode=2137 Name=t2STR_POST Format=ARM_FORMAT_THUMBFRM(25)
> #  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 
> 
> Modified: llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/ARM/neon-tests.txt Tue Aug  9 15:55:18 2011
> @@ -24,7 +24,7 @@
> # CHECK:    vld1.32    {d3[], d4[]}, [r0, :32]!
> 0xbd 0x3c 0xa0 0xf4
> 
> -# CHECK:    vld4.16    {d3[], d4[], d5[], d6[]}, [r0, :64]!
> +# CHECK:    vld4.16    {d3[], d5[], d7[], d9[]}, [r0, :64]!
> 0x7d 0x3f 0xa0 0xf4
> 
> # CHECK:    vorr    d0, d15, d15
> @@ -87,5 +87,5 @@
> # CHECK:    usada8mi    r8, r9, r5, r9
> 0x19 0x95 0x88 0x47
> 
> -# CHECK:    vext.8    q4, q2, q1, #4
> +# CHECK:    vext.32    q4, q2, q1, #1
> 0x42 0x84 0xb4 0xf2
> 
> Modified: llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp?rev=137144&r1=137143&r2=137144&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp Tue Aug  9 15:55:18 2011
> @@ -128,12 +128,5 @@
>     return;
>   }
> 
> -  // Fixed-instruction-length targets use a common disassembler.
> -  // ARM use its own implementation for now.
> -  if (Target.getName() == "ARM") {
> -    ARMDecoderEmitter(Records).run(OS);
> -    return;
> -  }  
> -
>   FixedLenDecoderEmitter(Records).run(OS);
> }
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list