//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */

#include <stdio.h>
#include <string.h>

#include "ARMAddressingModes.h"
#include "ARMBaseInfo.h"
#include "../../SubtargetFeature.h"
#include "../../MCFixedLenDisassembler.h"
#include "../../MCInst.h"
#include "../../MCInstrDesc.h"
#include "../../MCRegisterInfo.h"
#include "../../LEB128.h"
#include "../../MCDisassembler.h"

#include "ARMDisassembler.h"

//#define GET_REGINFO_ENUM
//#include "X86GenRegisterInfo.inc"

#define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc"

#define GET_INSTRINFO_ENUM
#include "ARMGenInstrInfo.inc"

typedef struct ITStatus {
	//std_vector<unsigned char> ITStates;
	unsigned char ITStates[128];	// FIXME
	unsigned int size;
} ITStatus;

static bool ITStatus_push_back(ITStatus *it, char v)
{
	it->ITStates[it->size] = v;
	it->size++;

	return true;
}

// Returns true if the current instruction is in an IT block
static bool ITStatus_instrInITBlock(ITStatus *it)
{
	//return !ITStates.empty();
	return (it->size > 0);
}

// Returns true if current instruction is the last instruction in an IT block
static bool ITStatus_instrLastInITBlock(ITStatus *it)
{
	return (it->size == 1);
}

// Handles the condition code status of instructions in IT blocks

// Returns the condition code for instruction in IT block
static unsigned ITStatus_getITCC(ITStatus *it)
{
	unsigned CC = ARMCC_AL;
	if (ITStatus_instrInITBlock(it))
		//CC = ITStates.back();
		CC = it->ITStates[it->size-1];
	return CC;
}

// Advances the IT block state to the next T or E
static void ITStatus_advanceITState(ITStatus *it)
{
	//ITStates.pop_back();
	it->size--;
}

// Called when decoding an IT instruction. Sets the IT state for the following
// instructions that for the IT block. Firstcond and Mask correspond to the 
// fields in the IT instruction encoding.
static void ITStatus_setITState(ITStatus *it, char Firstcond, char Mask)
{
	// (3 - the number of trailing zeros) is the number of then / else.
	unsigned CondBit0 = Firstcond & 1;
	unsigned NumTZ = CountTrailingZeros_32(Mask);
	unsigned char CCBits = (unsigned char)Firstcond & 0xf;
	unsigned Pos;
	//assert(NumTZ <= 3 && "Invalid IT mask!");
	// push condition codes onto the stack the correct order for the pops
	for (Pos = NumTZ+1; Pos <= 3; ++Pos) {
		bool T = ((Mask >> Pos) & 1) == CondBit0;
		if (T)
			ITStatus_push_back(it, CCBits);
		else
			ITStatus_push_back(it, CCBits ^ 1);
	}
	ITStatus_push_back(it, CCBits);
}

/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.

// FIXME: make this ITBlock private for each Disassembler handle
static ITStatus ITBlock;

static bool Check(DecodeStatus *Out, DecodeStatus In)
{
	switch (In) {
		case MCDisassembler_Success:
			// Out stays the same.
			return true;
		case MCDisassembler_SoftFail:
			*Out = In;
			return true;
		case MCDisassembler_Fail:
			*Out = In;
			return false;
		default:	// never reached
			return false;
	}
}

// Forward declare these because the autogenerated code will reference them.
// Definitions are further down.
static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSOImmOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst,
		unsigned Insn, uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst,unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst * Inst,
		unsigned Insn, uint64_t Adddress, const void *Decoder);
static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst,unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeNEONModImmInstruction(MCInst *Inst,unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder);
static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder);
static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder);
static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder);
static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst,unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeIT(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst,unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst,unsigned Insn,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2Adr(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);

static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeMRRC2(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
#define GET_SUBTARGETINFO_ENUM
#include "ARMGenSubtargetInfo.inc"

#define GET_SUBTARGETINFO_MC_DESC
#include "ARMGenSubtargetInfo.inc"

// Hacky: enable all features for disassembler
static uint64_t ARM_getFeatureBits(int mode)
{
	int i;
	uint64_t Bits = 0;
	for (i = 0; i < sizeof(ARMFeatureKV)/sizeof(ARMFeatureKV[0]); i++) {
		Bits |= ARMFeatureKV[i].Value;
	}

	if (mode == 4)
		Bits -= ARM_ModeThumb;

	return Bits;
}

#include "ARMGenDisassemblerTables.inc"

static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (Val == 0xF) return MCDisassembler_Fail;
	// AL predicate is not allowed on Thumb1 branches.
	if (MCInst_getOpcode(Inst) == ARM_tBcc && Val == 0xE)
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
	if (Val == ARMCC_AL) {
		MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	} else
		MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_CPSR));
	return MCDisassembler_Success;
}

#define GET_REGINFO_MC_DESC
#include "ARMGenRegisterInfo.inc"
void ARM_init(MCRegisterInfo *MRI)
{
	/*
	   InitMCRegisterInfo(ARMRegDesc, 288,
	   RA, PC,
	   ARMMCRegisterClasses, 100,
	   ARMRegUnitRoots, 76, ARMRegDiffLists, ARMRegStrings,
	   ARMSubRegIdxLists, 57,
	   ARMSubRegIdxRanges, ARMRegEncodingTable);
	 */

	MCRegisterInfo_InitMCRegisterInfo(MRI, ARMRegDesc, 288,
			0, 0, 
			ARMMCRegisterClasses, 100,
			0, 0, ARMRegDiffLists, 0, 
			ARMSubRegIdxLists, 57,
			0);
}

static DecodeStatus _ARM_getInstruction(MCInst *MI, unsigned char *code, size_t code_len,
		uint16_t *Size, size_t Address)
{
	uint8_t bytes[4];

	ITBlock.size = 0;

	//assert(!(STI.getFeatureBits() & ARM_ModeThumb) &&
	//       "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");

	if (code_len < 4)
		return MCDisassembler_Fail;

	memcpy(bytes, code, 4);

	// 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.
	DecodeStatus result = decodeInstruction_4(DecoderTableARM32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	// VFP and NEON instructions, similarly, are shared between ARM
	// and Thumb modes.
	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableVFP32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableVFPV832, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableNEONData32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		// Add a fake predicate operand, because we share these instruction
		// definitions with Thumb2 where these instructions are predicable.
		if (!DecodePredicateOperand(MI, 0xE, Address, NULL))
			return MCDisassembler_Fail;
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		// Add a fake predicate operand, because we share these instruction
		// definitions with Thumb2 where these instructions are predicable.
		if (!DecodePredicateOperand(MI, 0xE, Address, NULL))
			return MCDisassembler_Fail;
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		// Add a fake predicate operand, because we share these instruction
		// definitions with Thumb2 where these instructions are predicable.
		if (!DecodePredicateOperand(MI, 0xE, Address, NULL))
			return MCDisassembler_Fail;
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTablev8NEON32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTablev8Crypto32, MI, insn, Address, 4);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}


	MCInst_clear(MI);
	*Size = 0;
	return MCDisassembler_Fail;
}

// Thumb1 instructions don't have explicit S bits.  Rather, they
// implicitly set CPSR.  Since it's not represented in the encoding, the
// auto-generated decoder won't inject the CPSR operand.  We need to fix
// that as a post-pass.
static void AddThumb1SBit(MCInst *MI, bool InITBlock)
{
	MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
	unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
	unsigned i;

	for (i = 0; i < NumOps; ++i) {
		if (i == MCInst_getNumOperands(MI)) break;
		if (MCOperandInfo_isOptionalDef(&OpInfo[i]) && OpInfo[i].RegClass == ARM_CCRRegClassID) {
			if (i > 0 && MCOperandInfo_isPredicate(&OpInfo[i-1])) continue;
			MCInst_insert(MI, i, MCOperand_CreateReg(InITBlock ? 0 : ARM_CPSR));
			return;
		}
	}

	//MI.insert(I, MCOperand_CreateReg(InITBlock ? 0 : ARM_CPSR));
	MCInst_insert(MI, i, MCOperand_CreateReg(InITBlock ? 0 : ARM_CPSR));
}

// Most Thumb instructions don't have explicit predicates in the
// encoding, but rather get their predicates from IT context.  We need
// to fix up the predicate operands using this context information as a
// post-pass.
static DecodeStatus AddThumbPredicate(MCInst *MI)
{
	DecodeStatus S = MCDisassembler_Success;

	// A few instructions actually have predicates encoded in them.  Don't
	// try to overwrite it if we're seeing one of those.
	switch (MCInst_getOpcode(MI)) {
		case ARM_tBcc:
		case ARM_t2Bcc:
		case ARM_tCBZ:
		case ARM_tCBNZ:
		case ARM_tCPS:
		case ARM_t2CPS3p:
		case ARM_t2CPS2p:
		case ARM_t2CPS1p:
		case ARM_tMOVSr:
		case ARM_tSETEND:
			// Some instructions (mostly conditional branches) are not
			// allowed in IT blocks.
			if (ITStatus_instrInITBlock(&ITBlock))
				S = MCDisassembler_SoftFail;
			else
				return MCDisassembler_Success;
			break;
		case ARM_tB:
		case ARM_t2B:
		case ARM_t2TBB:
		case ARM_t2TBH:
			// Some instructions (mostly unconditional branches) can
			// only appears at the end of, or outside of, an IT.
			//if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
			if (ITStatus_instrInITBlock(&ITBlock) && !ITStatus_instrLastInITBlock(&ITBlock))
				S = MCDisassembler_SoftFail;
			break;
		default:
			break;
	}

	// If we're in an IT block, base the predicate on that.  Otherwise,
	// assume a predicate of AL.
	unsigned CC;
	CC = ITStatus_getITCC(&ITBlock);
	if (CC == 0xF) 
		CC = ARMCC_AL;
	if (ITStatus_instrInITBlock(&ITBlock))
		ITStatus_advanceITState(&ITBlock);

	MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
	unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
	unsigned i;
	for (i = 0; i < NumOps; ++i) {
		if (i == MCInst_getNumOperands(MI)) break;
		if (MCOperandInfo_isPredicate(&OpInfo[i])) {
			MCInst_insert(MI, i, MCOperand_CreateImm(CC));
			if (CC == ARMCC_AL)
				MCInst_insert(MI, i+1, MCOperand_CreateReg(0));
			else
				MCInst_insert(MI, i+1, MCOperand_CreateReg(ARM_CPSR));
			return S;
		}
	}

	MCInst_insert(MI, i, MCOperand_CreateImm(CC));
	if (CC == ARMCC_AL)
		MCInst_insert(MI, i+1, MCOperand_CreateReg(0));
	else
		MCInst_insert(MI, i+1, MCOperand_CreateReg(ARM_CPSR));

	return S;
}

// Thumb VFP instructions are a special case.  Because we share their
// encodings between ARM and Thumb modes, and they are predicable in ARM
// mode, the auto-generated decoder will give them an (incorrect)
// predicate operand.  We need to rewrite these operands based on the IT
// context as a post-pass.
static void UpdateThumbVFPPredicate(MCInst *MI)
{
	unsigned CC;
	CC = ITStatus_getITCC(&ITBlock);
	if (ITStatus_instrInITBlock(&ITBlock))
		ITStatus_advanceITState(&ITBlock);

	MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
	unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
	unsigned i;
	for (i = 0; i < NumOps; ++i) {
		if (MCOperandInfo_isPredicate(&OpInfo[i])) {
			MCOperand_setImm(MCInst_getOperand(MI, i), CC);
			if (CC == ARMCC_AL)
				MCOperand_setReg(MCInst_getOperand(MI, i+1), 0);
			else
				MCOperand_setReg(MCInst_getOperand(MI, i+1), ARM_CPSR);
			return;
		}
	}
}

static DecodeStatus _Thumb_getInstruction(MCInst *MI, unsigned char *code, size_t code_len,
		uint16_t *Size, size_t Address)
{
	uint8_t bytes[4];

	ITBlock.size = 0;

	//assert((STI.getFeatureBits() & ARM_ModeThumb) &&
	//       "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");

	// We want to read exactly 2 bytes of data.
	if (code_len < 2)
		return MCDisassembler_Fail;

	memcpy(bytes, code, 2);

	uint16_t insn16 = (bytes[1] << 8) | bytes[0];
	DecodeStatus result = decodeInstruction_2(DecoderTableThumb16, MI, insn16, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 2;
		Check(&result, AddThumbPredicate(MI));
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_2(DecoderTableThumbSBit16, MI, insn16, Address, 2);
	if (result) {
		*Size = 2;
		bool InITBlock = ITStatus_instrInITBlock(&ITBlock);
		Check(&result, AddThumbPredicate(MI));
		AddThumb1SBit(MI, InITBlock);
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_2(DecoderTableThumb216, MI, insn16, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 2;

		// Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
		// the Thumb predicate.
		if (MCInst_getOpcode(MI) == ARM_t2IT && ITStatus_instrInITBlock(&ITBlock))
			result = MCDisassembler_SoftFail;

		Check(&result, 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 (MCInst_getOpcode(MI) == ARM_t2IT) {

			unsigned Firstcond = MCOperand_getImm(MCInst_getOperand(MI, 0));
			unsigned Mask = MCOperand_getImm(MCInst_getOperand(MI, 1));
			ITStatus_setITState(&ITBlock, Firstcond, Mask);
		}

		return result;
	}

	// We want to read exactly 4 bytes of data.
	//if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
	//  *Size = 0;
	//  return MCDisassembler_Fail;
	//}

	memcpy(bytes, code, 4);

	uint32_t insn32 = (bytes[3] <<  8) |
		(bytes[2] <<  0) |
		(bytes[1] << 24) |
		(bytes[0] << 16);
	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableThumb32, MI, insn32, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		bool InITBlock = ITStatus_instrInITBlock(&ITBlock);
		Check(&result, AddThumbPredicate(MI));
		AddThumb1SBit(MI, InITBlock);
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableThumb232, MI, insn32, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		Check(&result, AddThumbPredicate(MI));
		return result;
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		UpdateThumbVFPPredicate(MI);
		return result;
	}

	if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {
		MCInst_clear(MI);
		result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, 2);
		if (result != MCDisassembler_Fail) {
			*Size = 4;
			UpdateThumbVFPPredicate(MI);
			return result;
		}
	}

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableVFPV832, MI, insn32, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {
		MCInst_clear(MI);
		result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn32, Address, 2);
		if (result != MCDisassembler_Fail) {
			*Size = 4;
			Check(&result, AddThumbPredicate(MI));
			return result;
		}
	}

	if (fieldFromInstruction_4(insn32, 24, 8) == 0xF9) {
		MCInst_clear(MI);
		uint32_t NEONLdStInsn = insn32;
		NEONLdStInsn &= 0xF0FFFFFF;
		NEONLdStInsn |= 0x04000000;
		result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, Address, 2);
		if (result != MCDisassembler_Fail) {
			*Size = 4;
			Check(&result, AddThumbPredicate(MI));
			return result;
		}
	}

	if (fieldFromInstruction_4(insn32, 24, 4) == 0xF) {
		MCInst_clear(MI);
		uint32_t NEONDataInsn = insn32;
		NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
		NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
		NEONDataInsn |= 0x12000000; // Set bits 28 and 25
		result = decodeInstruction_4(DecoderTableNEONData32, MI, NEONDataInsn, Address, 2);
		if (result != MCDisassembler_Fail) {
			*Size = 4;
			Check(&result, AddThumbPredicate(MI));
			return result;
		}
	}

	MCInst_clear(MI);
	uint32_t NEONCryptoInsn = insn32;
	NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
	NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
	NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
	result = decodeInstruction_4(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
			Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	MCInst_clear(MI);
	uint32_t NEONv8Insn = insn32;
	NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
	result = decodeInstruction_4(DecoderTablev8NEON32, MI, NEONv8Insn, Address, 2);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

	MCInst_clear(MI);
	*Size = 0;
	return MCDisassembler_Fail;
}

bool Thumb_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr,
		uint16_t *size, size_t address, void *info)
{
	//cs_struct *handle = (cs_struct *)ud;
	DecodeStatus status = _Thumb_getInstruction(instr, code, code_len, size, address);

	return status == MCDisassembler_Success;
}

bool ARM_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr,
		uint16_t *size, size_t address, void *info)
{
	//cs_struct *handle = (cs_struct *)ud;
	DecodeStatus status = _ARM_getInstruction(instr, code, code_len, size, address);

	return status == MCDisassembler_Success;
	//return status != MCDisassembler_Fail;
}

static const uint16_t GPRDecoderTable[] = {
	ARM_R0, ARM_R1, ARM_R2, ARM_R3,
	ARM_R4, ARM_R5, ARM_R6, ARM_R7,
	ARM_R8, ARM_R9, ARM_R10, ARM_R11,
	ARM_R12, ARM_SP, ARM_LR, ARM_PC
};

static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 15)
		return MCDisassembler_Fail;

	unsigned Register = GPRDecoderTable[RegNo];
	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	if (RegNo == 15) 
		S = MCDisassembler_SoftFail;

	Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));

	return S;
}

static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	if (RegNo == 15) {
		MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_APSR_NZCV));
		return MCDisassembler_Success;
	}

	Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
	return S;
}

static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 7)
		return MCDisassembler_Fail;
	return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
}

static const uint16_t GPRPairDecoderTable[] = {
	ARM_R0_R1, ARM_R2_R3,   ARM_R4_R5,  ARM_R6_R7,
	ARM_R8_R9, ARM_R10_R11, ARM_R12_SP
};

static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	if (RegNo > 13)
		return MCDisassembler_Fail;

	if ((RegNo & 1) || RegNo == 0xe)
		S = MCDisassembler_SoftFail;

	unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
	MCInst_addOperand(Inst, MCOperand_CreateReg(RegisterPair));
	return S;
}

static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	unsigned Register = 0;
	switch (RegNo) {
		case 0:
			Register = ARM_R0;
			break;
		case 1:
			Register = ARM_R1;
			break;
		case 2:
			Register = ARM_R2;
			break;
		case 3:
			Register = ARM_R3;
			break;
		case 9:
			Register = ARM_R9;
			break;
		case 12:
			Register = ARM_R12;
			break;
		default:
			return MCDisassembler_Fail;
	}

	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	if (RegNo == 13 || RegNo == 15)
		S = MCDisassembler_SoftFail;
	Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
	return S;
}

static const uint16_t SPRDecoderTable[] = {
	ARM_S0,  ARM_S1,  ARM_S2,  ARM_S3,
	ARM_S4,  ARM_S5,  ARM_S6,  ARM_S7,
	ARM_S8,  ARM_S9, ARM_S10, ARM_S11,
	ARM_S12, ARM_S13, ARM_S14, ARM_S15,
	ARM_S16, ARM_S17, ARM_S18, ARM_S19,
	ARM_S20, ARM_S21, ARM_S22, ARM_S23,
	ARM_S24, ARM_S25, ARM_S26, ARM_S27,
	ARM_S28, ARM_S29, ARM_S30, ARM_S31
};

static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 31)
		return MCDisassembler_Fail;

	unsigned Register = SPRDecoderTable[RegNo];
	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static const uint16_t DPRDecoderTable[] = {
	ARM_D0,  ARM_D1,  ARM_D2,  ARM_D3,
	ARM_D4,  ARM_D5,  ARM_D6,  ARM_D7,
	ARM_D8,  ARM_D9, ARM_D10, ARM_D11,
	ARM_D12, ARM_D13, ARM_D14, ARM_D15,
	ARM_D16, ARM_D17, ARM_D18, ARM_D19,
	ARM_D20, ARM_D21, ARM_D22, ARM_D23,
	ARM_D24, ARM_D25, ARM_D26, ARM_D27,
	ARM_D28, ARM_D29, ARM_D30, ARM_D31
};

static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 31)
		return MCDisassembler_Fail;

	unsigned Register = DPRDecoderTable[RegNo];
	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 7)
		return MCDisassembler_Fail;
	return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
}

	static DecodeStatus
DecodeDPR_VFP2RegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 15)
		return MCDisassembler_Fail;
	return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
}

static const uint16_t QPRDecoderTable[] = {
	ARM_Q0,  ARM_Q1,  ARM_Q2,  ARM_Q3,
	ARM_Q4,  ARM_Q5,  ARM_Q6,  ARM_Q7,
	ARM_Q8,  ARM_Q9, ARM_Q10, ARM_Q11,
	ARM_Q12, ARM_Q13, ARM_Q14, ARM_Q15
};

static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 31 || (RegNo & 1) != 0)
		return MCDisassembler_Fail;
	RegNo >>= 1;

	unsigned Register = QPRDecoderTable[RegNo];
	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static const uint16_t DPairDecoderTable[] = {
	ARM_Q0,  ARM_D1_D2,   ARM_Q1,  ARM_D3_D4,   ARM_Q2,  ARM_D5_D6,
	ARM_Q3,  ARM_D7_D8,   ARM_Q4,  ARM_D9_D10,  ARM_Q5,  ARM_D11_D12,
	ARM_Q6,  ARM_D13_D14, ARM_Q7,  ARM_D15_D16, ARM_Q8,  ARM_D17_D18,
	ARM_Q9,  ARM_D19_D20, ARM_Q10, ARM_D21_D22, ARM_Q11, ARM_D23_D24,
	ARM_Q12, ARM_D25_D26, ARM_Q13, ARM_D27_D28, ARM_Q14, ARM_D29_D30,
	ARM_Q15
};

static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 30)
		return MCDisassembler_Fail;

	unsigned Register = DPairDecoderTable[RegNo];
	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static const uint16_t DPairSpacedDecoderTable[] = {
	ARM_D0_D2,   ARM_D1_D3,   ARM_D2_D4,   ARM_D3_D5,
	ARM_D4_D6,   ARM_D5_D7,   ARM_D6_D8,   ARM_D7_D9,
	ARM_D8_D10,  ARM_D9_D11,  ARM_D10_D12, ARM_D11_D13,
	ARM_D12_D14, ARM_D13_D15, ARM_D14_D16, ARM_D15_D17,
	ARM_D16_D18, ARM_D17_D19, ARM_D18_D20, ARM_D19_D21,
	ARM_D20_D22, ARM_D21_D23, ARM_D22_D24, ARM_D23_D25,
	ARM_D24_D26, ARM_D25_D27, ARM_D26_D28, ARM_D27_D29,
	ARM_D28_D30, ARM_D29_D31
};

static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder)
{
	if (RegNo > 29)
		return MCDisassembler_Fail;

	unsigned Register = DPairSpacedDecoderTable[RegNo];
	MCInst_addOperand(Inst, MCOperand_CreateReg(Register));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (Val)
		MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_CPSR));
	else
		MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeSOImmOperand(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) & 0x1F));
	MCInst_addOperand(Inst, MCOperand_CreateImm(rot_imm));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
	unsigned type = fieldFromInstruction_4(Val, 5, 2);
	unsigned imm = fieldFromInstruction_4(Val, 7, 5);

	// Register-immediate
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;

	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 (Shift == ARM_AM_ror && imm == 0)
		Shift = ARM_AM_rrx;

	unsigned Op = Shift | (imm << 3);
	MCInst_addOperand(Inst, MCOperand_CreateImm(Op));

	return S;
}

static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
	unsigned type = fieldFromInstruction_4(Val, 5, 2);
	unsigned Rs = fieldFromInstruction_4(Val, 8, 4);

	// Register-register
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
		return MCDisassembler_Fail;

	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;
	}

	MCInst_addOperand(Inst, MCOperand_CreateImm(Shift));

	return S;
}

static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	bool writebackLoad = false;
	unsigned writebackReg = 0;
	switch (MCInst_getOpcode(Inst)) {
		default:
			break;
		case ARM_LDMIA_UPD:
		case ARM_LDMDB_UPD:
		case ARM_LDMIB_UPD:
		case ARM_LDMDA_UPD:
		case ARM_t2LDMIA_UPD:
		case ARM_t2LDMDB_UPD:
			writebackLoad = true;
			writebackReg = MCOperand_getReg(MCInst_getOperand(Inst, 0));
			break;
	}

	// Empty register lists are not allowed.
	if (Val == 0) return MCDisassembler_Fail;
	unsigned i;
	for (i = 0; i < 16; ++i) {
		if (Val & (1 << i)) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
				return MCDisassembler_Fail;
			// Writeback not allowed if Rn is in the target list.
			if (writebackLoad && writebackReg == MCOperand_getReg(&(Inst->Operands[Inst->size-1])))
				Check(&S, MCDisassembler_SoftFail);
		}
	}

	return S;
}

static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
	unsigned regs = fieldFromInstruction_4(Val, 0, 8);

	// In case of unpredictable encoding, tweak the operands.
	if (regs == 0 || (Vd + regs) > 32) {
		regs = Vd + regs > 32 ? 32 - Vd : regs;
		regs = (1u > regs? 1u : regs);
		S = MCDisassembler_SoftFail;
	}

	if (!Check(&S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
		return MCDisassembler_Fail;
	unsigned i;
	for (i = 0; i < (regs - 1); ++i) {
		if (!Check(&S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	return S;
}

static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
	unsigned regs = fieldFromInstruction_4(Val, 1, 7);

	// In case of unpredictable encoding, tweak the operands.
	if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
		regs = Vd + regs > 32 ? 32 - Vd : regs;
		regs = (1u > regs? 1u : regs);
		regs = (16u > regs? regs : 16u);
		S = MCDisassembler_SoftFail;
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
		return MCDisassembler_Fail;
	unsigned i;
	for (i = 0; i < (regs - 1); ++i) {
		if (!Check(&S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	return S;
}

static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	// This operand encodes a mask of contiguous zeros between a specified MSB
	// and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
	// the mask of all bits LSB-and-lower, and then xor them to create
	// the mask of that's all ones on [msb, lsb].  Finally we not it to
	// create the final mask.
	unsigned msb = fieldFromInstruction_4(Val, 5, 5);
	unsigned lsb = fieldFromInstruction_4(Val, 0, 5);

	DecodeStatus S = MCDisassembler_Success;
	if (lsb > msb) {
		Check(&S, MCDisassembler_SoftFail);
		// The check above will cause the warning for the "potentially undefined
		// instruction encoding" but we can't build a bad MCOperand value here
		// with a lsb > msb or else printing the MCInst will cause a crash.
		lsb = msb;
	}

	uint32_t msb_mask = 0xFFFFFFFF;
	if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
	uint32_t lsb_mask = (1U << lsb) - 1;

	MCInst_addOperand(Inst, MCOperand_CreateImm(~(msb_mask ^ lsb_mask)));
	return S;
}

static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned CRd = fieldFromInstruction_4(Insn, 12, 4);
	unsigned coproc = fieldFromInstruction_4(Insn, 8, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned U = fieldFromInstruction_4(Insn, 23, 1);

	switch (MCInst_getOpcode(Inst)) {
		case ARM_LDC_OFFSET:
		case ARM_LDC_PRE:
		case ARM_LDC_POST:
		case ARM_LDC_OPTION:
		case ARM_LDCL_OFFSET:
		case ARM_LDCL_PRE:
		case ARM_LDCL_POST:
		case ARM_LDCL_OPTION:
		case ARM_STC_OFFSET:
		case ARM_STC_PRE:
		case ARM_STC_POST:
		case ARM_STC_OPTION:
		case ARM_STCL_OFFSET:
		case ARM_STCL_PRE:
		case ARM_STCL_POST:
		case ARM_STCL_OPTION:
		case ARM_t2LDC_OFFSET:
		case ARM_t2LDC_PRE:
		case ARM_t2LDC_POST:
		case ARM_t2LDC_OPTION:
		case ARM_t2LDCL_OFFSET:
		case ARM_t2LDCL_PRE:
		case ARM_t2LDCL_POST:
		case ARM_t2LDCL_OPTION:
		case ARM_t2STC_OFFSET:
		case ARM_t2STC_PRE:
		case ARM_t2STC_POST:
		case ARM_t2STC_OPTION:
		case ARM_t2STCL_OFFSET:
		case ARM_t2STCL_PRE:
		case ARM_t2STCL_POST:
		case ARM_t2STCL_OPTION:
			if (coproc == 0xA || coproc == 0xB)
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	MCInst_addOperand(Inst, MCOperand_CreateImm(coproc));
	MCInst_addOperand(Inst, MCOperand_CreateImm(CRd));
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2LDC2_OFFSET:
		case ARM_t2LDC2L_OFFSET:
		case ARM_t2LDC2_PRE:
		case ARM_t2LDC2L_PRE:
		case ARM_t2STC2_OFFSET:
		case ARM_t2STC2L_OFFSET:
		case ARM_t2STC2_PRE:
		case ARM_t2STC2L_PRE:
		case ARM_LDC2_OFFSET:
		case ARM_LDC2L_OFFSET:
		case ARM_LDC2_PRE:
		case ARM_LDC2L_PRE:
		case ARM_STC2_OFFSET:
		case ARM_STC2L_OFFSET:
		case ARM_STC2_PRE:
		case ARM_STC2L_PRE:
		case ARM_t2LDC_OFFSET:
		case ARM_t2LDCL_OFFSET:
		case ARM_t2LDC_PRE:
		case ARM_t2LDCL_PRE:
		case ARM_t2STC_OFFSET:
		case ARM_t2STCL_OFFSET:
		case ARM_t2STC_PRE:
		case ARM_t2STCL_PRE:
		case ARM_LDC_OFFSET:
		case ARM_LDCL_OFFSET:
		case ARM_LDC_PRE:
		case ARM_LDCL_PRE:
		case ARM_STC_OFFSET:
		case ARM_STCL_OFFSET:
		case ARM_STC_PRE:
		case ARM_STCL_PRE:
			imm = ARM_AM_getAM5Opc(U ? ARM_AM_add : ARM_AM_sub, imm);
			MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
			break;
		case ARM_t2LDC2_POST:
		case ARM_t2LDC2L_POST:
		case ARM_t2STC2_POST:
		case ARM_t2STC2L_POST:
		case ARM_LDC2_POST:
		case ARM_LDC2L_POST:
		case ARM_STC2_POST:
		case ARM_STC2L_POST:
		case ARM_t2LDC_POST:
		case ARM_t2LDCL_POST:
		case ARM_t2STC_POST:
		case ARM_t2STCL_POST:
		case ARM_LDC_POST:
		case ARM_LDCL_POST:
		case ARM_STC_POST:
		case ARM_STCL_POST:
			imm |= U << 8;
			// fall through.
		default:
			// The 'option' variant doesn't encode 'U' in the immediate since
			// the immediate is unsigned [0,255].
			MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
			break;
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_LDC_OFFSET:
		case ARM_LDC_PRE:
		case ARM_LDC_POST:
		case ARM_LDC_OPTION:
		case ARM_LDCL_OFFSET:
		case ARM_LDCL_PRE:
		case ARM_LDCL_POST:
		case ARM_LDCL_OPTION:
		case ARM_STC_OFFSET:
		case ARM_STC_PRE:
		case ARM_STC_POST:
		case ARM_STC_OPTION:
		case ARM_STCL_OFFSET:
		case ARM_STCL_PRE:
		case ARM_STCL_POST:
		case ARM_STCL_OPTION:
			if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	return S;
}

static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned reg = fieldFromInstruction_4(Insn, 25, 1);
	unsigned P = fieldFromInstruction_4(Insn, 24, 1);
	unsigned W = fieldFromInstruction_4(Insn, 21, 1);

	// On stores, the writeback operand precedes Rt.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_STR_POST_IMM:
		case ARM_STR_POST_REG:
		case ARM_STRB_POST_IMM:
		case ARM_STRB_POST_REG:
		case ARM_STRT_POST_REG:
		case ARM_STRT_POST_IMM:
		case ARM_STRBT_POST_REG:
		case ARM_STRBT_POST_IMM:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;

	// On loads, the writeback operand comes after Rt.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_LDR_POST_IMM:
		case ARM_LDR_POST_REG:
		case ARM_LDRB_POST_IMM:
		case ARM_LDRB_POST_REG:
		case ARM_LDRBT_POST_REG:
		case ARM_LDRBT_POST_IMM:
		case ARM_LDRT_POST_REG:
		case ARM_LDRT_POST_IMM:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	ARM_AM_AddrOpc Op = ARM_AM_add;
	if (!fieldFromInstruction_4(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 (writeback && (Rn == 15 || Rn == Rt))
		S = MCDisassembler_SoftFail; // UNPREDICTABLE

	if (reg) {
		if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
			return MCDisassembler_Fail;
		ARM_AM_ShiftOpc Opc = ARM_AM_lsl;
		switch( fieldFromInstruction_4(Insn, 5, 2)) {
			case 0:
				Opc = ARM_AM_lsl;
				break;
			case 1:
				Opc = ARM_AM_lsr;
				break;
			case 2:
				Opc = ARM_AM_asr;
				break;
			case 3:
				Opc = ARM_AM_ror;
				break;
			default:
				return MCDisassembler_Fail;
		}
		unsigned amt = fieldFromInstruction_4(Insn, 7, 5);
		if (Opc == ARM_AM_ror && amt == 0)
			Opc = ARM_AM_rrx;
		unsigned imm = ARM_AM_getAM2Opc(Op, amt, Opc, idx_mode);

		MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
	} else {
		MCInst_addOperand(Inst, MCOperand_CreateReg(0));
		unsigned tmp = ARM_AM_getAM2Opc(Op, imm, ARM_AM_lsl, idx_mode);
		MCInst_addOperand(Inst, MCOperand_CreateImm(tmp));
	}

	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
	unsigned Rm = fieldFromInstruction_4(Val,  0, 4);
	unsigned type = fieldFromInstruction_4(Val, 5, 2);
	unsigned imm = fieldFromInstruction_4(Val, 7, 5);
	unsigned U = fieldFromInstruction_4(Val, 12, 1);

	ARM_AM_ShiftOpc ShOp = ARM_AM_lsl;
	switch (type) {
		case 0:
			ShOp = ARM_AM_lsl;
			break;
		case 1:
			ShOp = ARM_AM_lsr;
			break;
		case 2:
			ShOp = ARM_AM_asr;
			break;
		case 3:
			ShOp = ARM_AM_ror;
			break;
	}

	if (ShOp == ARM_AM_ror && imm == 0)
		ShOp = ARM_AM_rrx;

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	unsigned shift;
	if (U)
		shift = ARM_AM_getAM2Opc(ARM_AM_add, imm, ShOp, 0);
	else
		shift = ARM_AM_getAM2Opc(ARM_AM_sub, imm, ShOp, 0);
	MCInst_addOperand(Inst, MCOperand_CreateImm(shift));

	return S;
}

static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned type = fieldFromInstruction_4(Insn, 22, 1);
	unsigned imm = fieldFromInstruction_4(Insn, 8, 4);
	unsigned U = ((~fieldFromInstruction_4(Insn, 23, 1)) & 1) << 8;
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned W = fieldFromInstruction_4(Insn, 21, 1);
	unsigned P = fieldFromInstruction_4(Insn, 24, 1);
	unsigned Rt2 = Rt + 1;

	bool writeback = (W == 1) | (P == 0);

	// For {LD,ST}RD, Rt must be even, else undefined.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_STRD:
		case ARM_STRD_PRE:
		case ARM_STRD_POST:
		case ARM_LDRD:
		case ARM_LDRD_PRE:
		case ARM_LDRD_POST:
			if (Rt & 0x1) S = MCDisassembler_SoftFail;
			break;
		default:
			break;
	}
	switch (MCInst_getOpcode(Inst)) {
		case ARM_STRD:
		case ARM_STRD_PRE:
		case ARM_STRD_POST:
			if (P == 0 && W == 1)
				S = MCDisassembler_SoftFail;

			if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
				S = MCDisassembler_SoftFail;
			if (type && Rm == 15)
				S = MCDisassembler_SoftFail;
			if (Rt2 == 15)
				S = MCDisassembler_SoftFail;
			if (!type && fieldFromInstruction_4(Insn, 8, 4))
				S = MCDisassembler_SoftFail;
			break;
		case ARM_STRH:
		case ARM_STRH_PRE:
		case ARM_STRH_POST:
			if (Rt == 15)
				S = MCDisassembler_SoftFail;
			if (writeback && (Rn == 15 || Rn == Rt))
				S = MCDisassembler_SoftFail;
			if (!type && Rm == 15)
				S = MCDisassembler_SoftFail;
			break;
		case ARM_LDRD:
		case ARM_LDRD_PRE:
		case ARM_LDRD_POST:
			if (type && Rn == 15){
				if (Rt2 == 15)
					S = MCDisassembler_SoftFail;
				break;
			}
			if (P == 0 && W == 1)
				S = MCDisassembler_SoftFail;
			if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
				S = MCDisassembler_SoftFail;
			if (!type && writeback && Rn == 15)
				S = MCDisassembler_SoftFail;
			if (writeback && (Rn == Rt || Rn == Rt2))
				S = MCDisassembler_SoftFail;
			break;
		case ARM_LDRH:
		case ARM_LDRH_PRE:
		case ARM_LDRH_POST:
			if (type && Rn == 15){
				if (Rt == 15)
					S = MCDisassembler_SoftFail;
				break;
			}
			if (Rt == 15)
				S = MCDisassembler_SoftFail;
			if (!type && Rm == 15)
				S = MCDisassembler_SoftFail;
			if (!type && writeback && (Rn == 15 || Rn == Rt))
				S = MCDisassembler_SoftFail;
			break;
		case ARM_LDRSH:
		case ARM_LDRSH_PRE:
		case ARM_LDRSH_POST:
		case ARM_LDRSB:
		case ARM_LDRSB_PRE:
		case ARM_LDRSB_POST:
			if (type && Rn == 15){
				if (Rt == 15)
					S = MCDisassembler_SoftFail;
				break;
			}
			if (type && (Rt == 15 || (writeback && Rn == Rt)))
				S = MCDisassembler_SoftFail;
			if (!type && (Rt == 15 || Rm == 15))
				S = MCDisassembler_SoftFail;
			if (!type && writeback && (Rn == 15 || Rn == Rt))
				S = MCDisassembler_SoftFail;
			break;
		default:
			break;
	}

	if (writeback) { // Writeback
		if (P)
			U |= ARMII_IndexModePre << 9;
		else
			U |= ARMII_IndexModePost << 9;

		// On stores, the writeback operand precedes Rt.
		switch (MCInst_getOpcode(Inst)) {
			case ARM_STRD:
			case ARM_STRD_PRE:
			case ARM_STRD_POST:
			case ARM_STRH:
			case ARM_STRH_PRE:
			case ARM_STRH_POST:
				if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
					return MCDisassembler_Fail;
				break;
			default:
				break;
		}
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	switch (MCInst_getOpcode(Inst)) {
		case ARM_STRD:
		case ARM_STRD_PRE:
		case ARM_STRD_POST:
		case ARM_LDRD:
		case ARM_LDRD_PRE:
		case ARM_LDRD_POST:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	if (writeback) {
		// On loads, the writeback operand comes after Rt.
		switch (MCInst_getOpcode(Inst)) {
			case ARM_LDRD:
			case ARM_LDRD_PRE:
			case ARM_LDRD_POST:
			case ARM_LDRH:
			case ARM_LDRH_PRE:
			case ARM_LDRH_POST:
			case ARM_LDRSH:
			case ARM_LDRSH_PRE:
			case ARM_LDRSH_POST:
			case ARM_LDRSB:
			case ARM_LDRSB_PRE:
			case ARM_LDRSB_POST:
			case ARM_LDRHTr:
			case ARM_LDRSBTr:
				if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
					return MCDisassembler_Fail;
				break;
			default:
				break;
		}
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	if (type) {
		MCInst_addOperand(Inst, MCOperand_CreateReg(0));
		MCInst_addOperand(Inst, MCOperand_CreateImm(U | (imm << 4) | Rm));
	} else {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
			return MCDisassembler_Fail;
		MCInst_addOperand(Inst, MCOperand_CreateImm(U));
	}

	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeRFEInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned mode = fieldFromInstruction_4(Insn, 23, 2);

	switch (mode) {
		case 0:
			mode = ARM_AM_da;
			break;
		case 1:
			mode = ARM_AM_ia;
			break;
		case 2:
			mode = ARM_AM_db;
			break;
		case 3:
			mode = ARM_AM_ib;
			break;
	}

	MCInst_addOperand(Inst, MCOperand_CreateImm(mode));
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (pred == 0xF)
		return DecodeCPSInstruction(Inst, Insn, Address, Decoder);

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;
	return S;
}

static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst *Inst,
		unsigned Insn, uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned reglist = fieldFromInstruction_4(Insn, 0, 16);

	if (pred == 0xF) {
		// Ambiguous with RFE and SRS
		switch (MCInst_getOpcode(Inst)) {
			case ARM_LDMDA:
				MCInst_setOpcode(Inst, ARM_RFEDA);
				break;
			case ARM_LDMDA_UPD:
				MCInst_setOpcode(Inst, ARM_RFEDA_UPD);
				break;
			case ARM_LDMDB:
				MCInst_setOpcode(Inst, ARM_RFEDB);
				break;
			case ARM_LDMDB_UPD:
				MCInst_setOpcode(Inst, ARM_RFEDB_UPD);
				break;
			case ARM_LDMIA:
				MCInst_setOpcode(Inst, ARM_RFEIA);
				break;
			case ARM_LDMIA_UPD:
				MCInst_setOpcode(Inst, ARM_RFEIA_UPD);
				break;
			case ARM_LDMIB:
				MCInst_setOpcode(Inst, ARM_RFEIB);
				break;
			case ARM_LDMIB_UPD:
				MCInst_setOpcode(Inst, ARM_RFEIB_UPD);
				break;
			case ARM_STMDA:
				MCInst_setOpcode(Inst, ARM_SRSDA);
				break;
			case ARM_STMDA_UPD:
				MCInst_setOpcode(Inst, ARM_SRSDA_UPD);
				break;
			case ARM_STMDB:
				MCInst_setOpcode(Inst, ARM_SRSDB);
				break;
			case ARM_STMDB_UPD:
				MCInst_setOpcode(Inst, ARM_SRSDB_UPD);
				break;
			case ARM_STMIA:
				MCInst_setOpcode(Inst, ARM_SRSIA);
				break;
			case ARM_STMIA_UPD:
				MCInst_setOpcode(Inst, ARM_SRSIA_UPD);
				break;
			case ARM_STMIB:
				MCInst_setOpcode(Inst, ARM_SRSIB);
				break;
			case ARM_STMIB_UPD:
				MCInst_setOpcode(Inst, ARM_SRSIB_UPD);
				break;
			default:
				return MCDisassembler_Fail;
		}

		// For stores (which become SRS's, the only operand is the mode.
		if (fieldFromInstruction_4(Insn, 20, 1) == 0) {
			// Check SRS encoding constraints
			if (!(fieldFromInstruction_4(Insn, 22, 1) == 1 &&
						fieldFromInstruction_4(Insn, 20, 1) == 0))
				return MCDisassembler_Fail;

			MCInst_addOperand(Inst, 
					MCOperand_CreateImm(fieldFromInstruction_4(Insn, 0, 4)));
			return S;
		}

		return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail; // Tied
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned imod = fieldFromInstruction_4(Insn, 18, 2);
	unsigned M = fieldFromInstruction_4(Insn, 17, 1);
	unsigned iflags = fieldFromInstruction_4(Insn, 6, 3);
	unsigned mode = fieldFromInstruction_4(Insn, 0, 5);

	DecodeStatus S = MCDisassembler_Success;

	// This decoder is called from multiple location that do not check
	// the full encoding is valid before they do.
	if (fieldFromInstruction_4(Insn, 5, 1) != 0 ||
			fieldFromInstruction_4(Insn, 16, 1) != 0 ||
			fieldFromInstruction_4(Insn, 20, 8) != 0x10)
		return MCDisassembler_Fail;

	// imod == '01' --> UNPREDICTABLE
	// NOTE: Even though this is technically UNPREDICTABLE, we choose to
	// return failure here.  The '01' imod value is unprintable, so there's
	// nothing useful we could do even if we returned UNPREDICTABLE.

	if (imod == 1) return MCDisassembler_Fail;

	if (imod && M) {
		MCInst_setOpcode(Inst, ARM_CPS3p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(imod));
		MCInst_addOperand(Inst, MCOperand_CreateImm(iflags));
		MCInst_addOperand(Inst, MCOperand_CreateImm(mode));
	} else if (imod && !M) {
		MCInst_setOpcode(Inst, ARM_CPS2p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(imod));
		MCInst_addOperand(Inst, MCOperand_CreateImm(iflags));
		if (mode) S = MCDisassembler_SoftFail;
	} else if (!imod && M) {
		MCInst_setOpcode(Inst, ARM_CPS1p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(mode));
		if (iflags) S = MCDisassembler_SoftFail;
	} else {
		// imod == '00' && M == '0' --> UNPREDICTABLE
		MCInst_setOpcode(Inst, ARM_CPS1p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(mode));
		S = MCDisassembler_SoftFail;
	}

	return S;
}

static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned imod = fieldFromInstruction_4(Insn, 9, 2);
	unsigned M = fieldFromInstruction_4(Insn, 8, 1);
	unsigned iflags = fieldFromInstruction_4(Insn, 5, 3);
	unsigned mode = fieldFromInstruction_4(Insn, 0, 5);

	DecodeStatus S = MCDisassembler_Success;

	// imod == '01' --> UNPREDICTABLE
	// NOTE: Even though this is technically UNPREDICTABLE, we choose to
	// return failure here.  The '01' imod value is unprintable, so there's
	// nothing useful we could do even if we returned UNPREDICTABLE.

	if (imod == 1) return MCDisassembler_Fail;

	if (imod && M) {
		MCInst_setOpcode(Inst, ARM_t2CPS3p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(imod));
		MCInst_addOperand(Inst, MCOperand_CreateImm(iflags));
		MCInst_addOperand(Inst, MCOperand_CreateImm(mode));
	} else if (imod && !M) {
		MCInst_setOpcode(Inst, ARM_t2CPS2p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(imod));
		MCInst_addOperand(Inst, MCOperand_CreateImm(iflags));
		if (mode) S = MCDisassembler_SoftFail;
	} else if (!imod && M) {
		MCInst_setOpcode(Inst, ARM_t2CPS1p);
		MCInst_addOperand(Inst, MCOperand_CreateImm(mode));
		if (iflags) S = MCDisassembler_SoftFail;
	} else {
		// imod == '00' && M == '0' --> this is a HINT instruction
		int imm = fieldFromInstruction_4(Insn, 0, 8);
		// HINT are defined only for immediate in [0..4]
		if(imm > 4) return MCDisassembler_Fail;
		MCInst_setOpcode(Inst, ARM_t2HINT);
		MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
	}

	return S;
}

static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 8, 4);
	unsigned imm = 0;

	imm |= (fieldFromInstruction_4(Insn, 0, 8) << 0);
	imm |= (fieldFromInstruction_4(Insn, 12, 3) << 8);
	imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);
	imm |= (fieldFromInstruction_4(Insn, 26, 1) << 11);

	if (MCInst_getOpcode(Inst) == ARM_t2MOVTi16)
		if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
			return MCDisassembler_Fail;
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return S;
}

static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned imm = 0;

	imm |= (fieldFromInstruction_4(Insn, 0, 12) << 0);
	imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);

	if (MCInst_getOpcode(Inst) == ARM_MOVTi16)
		if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
			return MCDisassembler_Fail;

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 8, 4);
	unsigned Ra = fieldFromInstruction_4(Insn, 12, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (pred == 0xF)
		return DecodeCPSInstruction(Inst, Insn, Address, Decoder);

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
		return MCDisassembler_Fail;

	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned add = fieldFromInstruction_4(Val, 12, 1);
	unsigned imm = fieldFromInstruction_4(Val, 0, 12);
	unsigned Rn = fieldFromInstruction_4(Val, 13, 4);

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	if (!add) imm *= -1;
	if (imm == 0 && !add) imm = INT32_MIN;
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
	//if (Rn == 15)
	//  tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);

	return S;
}

static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
	unsigned U = fieldFromInstruction_4(Val, 8, 1);
	unsigned imm = fieldFromInstruction_4(Val, 0, 8);

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	if (U)
		MCInst_addOperand(Inst, MCOperand_CreateImm(ARM_AM_getAM5Opc(ARM_AM_add, imm)));
	else
		MCInst_addOperand(Inst, MCOperand_CreateImm(ARM_AM_getAM5Opc(ARM_AM_sub, imm)));

	return S;
}

static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
}

static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus Status = MCDisassembler_Success;

	// Note the J1 and J2 values are from the encoded instruction.  So here
	// change them to I1 and I2 values via as documented:
	// I1 = NOT(J1 EOR S);
	// I2 = NOT(J2 EOR S);
	// and build the imm32 with one trailing zero as documented:
	// imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
	unsigned S = fieldFromInstruction_4(Insn, 26, 1);
	unsigned J1 = fieldFromInstruction_4(Insn, 13, 1);
	unsigned J2 = fieldFromInstruction_4(Insn, 11, 1);
	unsigned I1 = !(J1 ^ S);
	unsigned I2 = !(J2 ^ S);
	unsigned imm10 = fieldFromInstruction_4(Insn, 16, 10);
	unsigned imm11 = fieldFromInstruction_4(Insn, 0, 11);
	unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
	int imm32 = SignExtend32(tmp << 1, 25);
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm32));

	return Status;
}

static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 24) << 2;

	if (pred == 0xF) {
		MCInst_setOpcode(Inst, ARM_BLXi);
		imm |= fieldFromInstruction_4(Insn, 24, 1) << 1;
		MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(imm, 26)));
		return S;
	}

	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(imm, 26)));
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}


static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
	unsigned align = fieldFromInstruction_4(Val, 4, 2);

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!align)
		MCInst_addOperand(Inst, MCOperand_CreateImm(0));
	else
		MCInst_addOperand(Inst, MCOperand_CreateImm(4 << align));

	return S;
}

static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned wb = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);

	// First output register
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VLD1q16: case ARM_VLD1q32: case ARM_VLD1q64: case ARM_VLD1q8:
		case ARM_VLD1q16wb_fixed: case ARM_VLD1q16wb_register:
		case ARM_VLD1q32wb_fixed: case ARM_VLD1q32wb_register:
		case ARM_VLD1q64wb_fixed: case ARM_VLD1q64wb_register:
		case ARM_VLD1q8wb_fixed: case ARM_VLD1q8wb_register:
		case ARM_VLD2d16: case ARM_VLD2d32: case ARM_VLD2d8:
		case ARM_VLD2d16wb_fixed: case ARM_VLD2d16wb_register:
		case ARM_VLD2d32wb_fixed: case ARM_VLD2d32wb_register:
		case ARM_VLD2d8wb_fixed: case ARM_VLD2d8wb_register:
			if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VLD2b16:
		case ARM_VLD2b32:
		case ARM_VLD2b8:
		case ARM_VLD2b16wb_fixed:
		case ARM_VLD2b16wb_register:
		case ARM_VLD2b32wb_fixed:
		case ARM_VLD2b32wb_register:
		case ARM_VLD2b8wb_fixed:
		case ARM_VLD2b8wb_register:
			if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	// Second output register
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VLD3d8:
		case ARM_VLD3d16:
		case ARM_VLD3d32:
		case ARM_VLD3d8_UPD:
		case ARM_VLD3d16_UPD:
		case ARM_VLD3d32_UPD:
		case ARM_VLD4d8:
		case ARM_VLD4d16:
		case ARM_VLD4d32:
		case ARM_VLD4d8_UPD:
		case ARM_VLD4d16_UPD:
		case ARM_VLD4d32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VLD3q8:
		case ARM_VLD3q16:
		case ARM_VLD3q32:
		case ARM_VLD3q8_UPD:
		case ARM_VLD3q16_UPD:
		case ARM_VLD3q32_UPD:
		case ARM_VLD4q8:
		case ARM_VLD4q16:
		case ARM_VLD4q32:
		case ARM_VLD4q8_UPD:
		case ARM_VLD4q16_UPD:
		case ARM_VLD4q32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
				return MCDisassembler_Fail;
		default:
			break;
	}

	// Third output register
	switch(MCInst_getOpcode(Inst)) {
		case ARM_VLD3d8:
		case ARM_VLD3d16:
		case ARM_VLD3d32:
		case ARM_VLD3d8_UPD:
		case ARM_VLD3d16_UPD:
		case ARM_VLD3d32_UPD:
		case ARM_VLD4d8:
		case ARM_VLD4d16:
		case ARM_VLD4d32:
		case ARM_VLD4d8_UPD:
		case ARM_VLD4d16_UPD:
		case ARM_VLD4d32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VLD3q8:
		case ARM_VLD3q16:
		case ARM_VLD3q32:
		case ARM_VLD3q8_UPD:
		case ARM_VLD3q16_UPD:
		case ARM_VLD3q32_UPD:
		case ARM_VLD4q8:
		case ARM_VLD4q16:
		case ARM_VLD4q32:
		case ARM_VLD4q8_UPD:
		case ARM_VLD4q16_UPD:
		case ARM_VLD4q32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// Fourth output register
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VLD4d8:
		case ARM_VLD4d16:
		case ARM_VLD4d32:
		case ARM_VLD4d8_UPD:
		case ARM_VLD4d16_UPD:
		case ARM_VLD4d32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VLD4q8:
		case ARM_VLD4q16:
		case ARM_VLD4q32:
		case ARM_VLD4q8_UPD:
		case ARM_VLD4q16_UPD:
		case ARM_VLD4q32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// Writeback operand
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VLD1d8wb_fixed:
		case ARM_VLD1d16wb_fixed:
		case ARM_VLD1d32wb_fixed:
		case ARM_VLD1d64wb_fixed:
		case ARM_VLD1d8wb_register:
		case ARM_VLD1d16wb_register:
		case ARM_VLD1d32wb_register:
		case ARM_VLD1d64wb_register:
		case ARM_VLD1q8wb_fixed:
		case ARM_VLD1q16wb_fixed:
		case ARM_VLD1q32wb_fixed:
		case ARM_VLD1q64wb_fixed:
		case ARM_VLD1q8wb_register:
		case ARM_VLD1q16wb_register:
		case ARM_VLD1q32wb_register:
		case ARM_VLD1q64wb_register:
		case ARM_VLD1d8Twb_fixed:
		case ARM_VLD1d8Twb_register:
		case ARM_VLD1d16Twb_fixed:
		case ARM_VLD1d16Twb_register:
		case ARM_VLD1d32Twb_fixed:
		case ARM_VLD1d32Twb_register:
		case ARM_VLD1d64Twb_fixed:
		case ARM_VLD1d64Twb_register:
		case ARM_VLD1d8Qwb_fixed:
		case ARM_VLD1d8Qwb_register:
		case ARM_VLD1d16Qwb_fixed:
		case ARM_VLD1d16Qwb_register:
		case ARM_VLD1d32Qwb_fixed:
		case ARM_VLD1d32Qwb_register:
		case ARM_VLD1d64Qwb_fixed:
		case ARM_VLD1d64Qwb_register:
		case ARM_VLD2d8wb_fixed:
		case ARM_VLD2d16wb_fixed:
		case ARM_VLD2d32wb_fixed:
		case ARM_VLD2q8wb_fixed:
		case ARM_VLD2q16wb_fixed:
		case ARM_VLD2q32wb_fixed:
		case ARM_VLD2d8wb_register:
		case ARM_VLD2d16wb_register:
		case ARM_VLD2d32wb_register:
		case ARM_VLD2q8wb_register:
		case ARM_VLD2q16wb_register:
		case ARM_VLD2q32wb_register:
		case ARM_VLD2b8wb_fixed:
		case ARM_VLD2b16wb_fixed:
		case ARM_VLD2b32wb_fixed:
		case ARM_VLD2b8wb_register:
		case ARM_VLD2b16wb_register:
		case ARM_VLD2b32wb_register:
			MCInst_addOperand(Inst, MCOperand_CreateImm(0));
			break;
		case ARM_VLD3d8_UPD:
		case ARM_VLD3d16_UPD:
		case ARM_VLD3d32_UPD:
		case ARM_VLD3q8_UPD:
		case ARM_VLD3q16_UPD:
		case ARM_VLD3q32_UPD:
		case ARM_VLD4d8_UPD:
		case ARM_VLD4d16_UPD:
		case ARM_VLD4d32_UPD:
		case ARM_VLD4q8_UPD:
		case ARM_VLD4q16_UPD:
		case ARM_VLD4q32_UPD:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// AddrMode6 Base (register+alignment)
	if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	// AddrMode6 Offset (register)
	switch (MCInst_getOpcode(Inst)) {
		default:
			// The below have been updated to have explicit am6offset split
			// between fixed and register offset. For those instructions not
			// yet updated, we need to add an additional reg0 operand for the
			// fixed variant.
			//
			// The fixed offset encodes as Rm == 0xd, so we check for that.
			if (Rm == 0xd) {
				MCInst_addOperand(Inst, MCOperand_CreateReg(0));
				break;
			}
			// Fall through to handle the register offset variant.
		case ARM_VLD1d8wb_fixed:
		case ARM_VLD1d16wb_fixed:
		case ARM_VLD1d32wb_fixed:
		case ARM_VLD1d64wb_fixed:
		case ARM_VLD1d8Twb_fixed:
		case ARM_VLD1d16Twb_fixed:
		case ARM_VLD1d32Twb_fixed:
		case ARM_VLD1d64Twb_fixed:
		case ARM_VLD1d8Qwb_fixed:
		case ARM_VLD1d16Qwb_fixed:
		case ARM_VLD1d32Qwb_fixed:
		case ARM_VLD1d64Qwb_fixed:
		case ARM_VLD1d8wb_register:
		case ARM_VLD1d16wb_register:
		case ARM_VLD1d32wb_register:
		case ARM_VLD1d64wb_register:
		case ARM_VLD1q8wb_fixed:
		case ARM_VLD1q16wb_fixed:
		case ARM_VLD1q32wb_fixed:
		case ARM_VLD1q64wb_fixed:
		case ARM_VLD1q8wb_register:
		case ARM_VLD1q16wb_register:
		case ARM_VLD1q32wb_register:
		case ARM_VLD1q64wb_register:
			// The fixed offset post-increment encodes Rm == 0xd. The no-writeback
			// variant encodes Rm == 0xf. Anything else is a register offset post-
			// increment and we need to add the register operand to the instruction.
			if (Rm != 0xD && Rm != 0xF &&
					!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VLD2d8wb_fixed:
		case ARM_VLD2d16wb_fixed:
		case ARM_VLD2d32wb_fixed:
		case ARM_VLD2b8wb_fixed:
		case ARM_VLD2b16wb_fixed:
		case ARM_VLD2b32wb_fixed:
		case ARM_VLD2q8wb_fixed:
		case ARM_VLD2q16wb_fixed:
		case ARM_VLD2q32wb_fixed:
			break;
	}

	return S;
}

static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned type = fieldFromInstruction_4(Insn, 8, 4);
	unsigned align = fieldFromInstruction_4(Insn, 4, 2);
	if (type == 6 && (align & 2)) return MCDisassembler_Fail;
	if (type == 7 && (align & 2)) return MCDisassembler_Fail;
	if (type == 10 && align == 3) return MCDisassembler_Fail;

	unsigned load = fieldFromInstruction_4(Insn, 21, 1);
	return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
		: DecodeVSTInstruction(Inst, Insn, Address, Decoder);
}

static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	if (size == 3) return MCDisassembler_Fail;

	unsigned type = fieldFromInstruction_4(Insn, 8, 4);
	unsigned align = fieldFromInstruction_4(Insn, 4, 2);
	if (type == 8 && align == 3) return MCDisassembler_Fail;
	if (type == 9 && align == 3) return MCDisassembler_Fail;

	unsigned load = fieldFromInstruction_4(Insn, 21, 1);
	return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
		: DecodeVSTInstruction(Inst, Insn, Address, Decoder);
}

static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	if (size == 3) return MCDisassembler_Fail;

	unsigned align = fieldFromInstruction_4(Insn, 4, 2);
	if (align & 2) return MCDisassembler_Fail;

	unsigned load = fieldFromInstruction_4(Insn, 21, 1);
	return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
		: DecodeVSTInstruction(Inst, Insn, Address, Decoder);
}

static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	if (size == 3) return MCDisassembler_Fail;

	unsigned load = fieldFromInstruction_4(Insn, 21, 1);
	return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
		: DecodeVSTInstruction(Inst, Insn, Address, Decoder);
}

static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned wb = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);

	// Writeback Operand
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VST1d8wb_fixed:
		case ARM_VST1d16wb_fixed:
		case ARM_VST1d32wb_fixed:
		case ARM_VST1d64wb_fixed:
		case ARM_VST1d8wb_register:
		case ARM_VST1d16wb_register:
		case ARM_VST1d32wb_register:
		case ARM_VST1d64wb_register:
		case ARM_VST1q8wb_fixed:
		case ARM_VST1q16wb_fixed:
		case ARM_VST1q32wb_fixed:
		case ARM_VST1q64wb_fixed:
		case ARM_VST1q8wb_register:
		case ARM_VST1q16wb_register:
		case ARM_VST1q32wb_register:
		case ARM_VST1q64wb_register:
		case ARM_VST1d8Twb_fixed:
		case ARM_VST1d16Twb_fixed:
		case ARM_VST1d32Twb_fixed:
		case ARM_VST1d64Twb_fixed:
		case ARM_VST1d8Twb_register:
		case ARM_VST1d16Twb_register:
		case ARM_VST1d32Twb_register:
		case ARM_VST1d64Twb_register:
		case ARM_VST1d8Qwb_fixed:
		case ARM_VST1d16Qwb_fixed:
		case ARM_VST1d32Qwb_fixed:
		case ARM_VST1d64Qwb_fixed:
		case ARM_VST1d8Qwb_register:
		case ARM_VST1d16Qwb_register:
		case ARM_VST1d32Qwb_register:
		case ARM_VST1d64Qwb_register:
		case ARM_VST2d8wb_fixed:
		case ARM_VST2d16wb_fixed:
		case ARM_VST2d32wb_fixed:
		case ARM_VST2d8wb_register:
		case ARM_VST2d16wb_register:
		case ARM_VST2d32wb_register:
		case ARM_VST2q8wb_fixed:
		case ARM_VST2q16wb_fixed:
		case ARM_VST2q32wb_fixed:
		case ARM_VST2q8wb_register:
		case ARM_VST2q16wb_register:
		case ARM_VST2q32wb_register:
		case ARM_VST2b8wb_fixed:
		case ARM_VST2b16wb_fixed:
		case ARM_VST2b32wb_fixed:
		case ARM_VST2b8wb_register:
		case ARM_VST2b16wb_register:
		case ARM_VST2b32wb_register:
			if (Rm == 0xF)
				return MCDisassembler_Fail;
			MCInst_addOperand(Inst, MCOperand_CreateImm(0));
			break;
		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:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// AddrMode6 Base (register+alignment)
	if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	// AddrMode6 Offset (register)
	switch (MCInst_getOpcode(Inst)) {
		default:
			if (Rm == 0xD)
				MCInst_addOperand(Inst, MCOperand_CreateReg(0));
			else if (Rm != 0xF) {
				if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
					return MCDisassembler_Fail;
			}
			break;
		case ARM_VST1d8wb_fixed:
		case ARM_VST1d16wb_fixed:
		case ARM_VST1d32wb_fixed:
		case ARM_VST1d64wb_fixed:
		case ARM_VST1q8wb_fixed:
		case ARM_VST1q16wb_fixed:
		case ARM_VST1q32wb_fixed:
		case ARM_VST1q64wb_fixed:
		case ARM_VST1d8Twb_fixed:
		case ARM_VST1d16Twb_fixed:
		case ARM_VST1d32Twb_fixed:
		case ARM_VST1d64Twb_fixed:
		case ARM_VST1d8Qwb_fixed:
		case ARM_VST1d16Qwb_fixed:
		case ARM_VST1d32Qwb_fixed:
		case ARM_VST1d64Qwb_fixed:
		case ARM_VST2d8wb_fixed:
		case ARM_VST2d16wb_fixed:
		case ARM_VST2d32wb_fixed:
		case ARM_VST2q8wb_fixed:
		case ARM_VST2q16wb_fixed:
		case ARM_VST2q32wb_fixed:
		case ARM_VST2b8wb_fixed:
		case ARM_VST2b16wb_fixed:
		case ARM_VST2b32wb_fixed:
			break;
	}


	// First input register
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VST1q16:
		case ARM_VST1q32:
		case ARM_VST1q64:
		case ARM_VST1q8:
		case ARM_VST1q16wb_fixed:
		case ARM_VST1q16wb_register:
		case ARM_VST1q32wb_fixed:
		case ARM_VST1q32wb_register:
		case ARM_VST1q64wb_fixed:
		case ARM_VST1q64wb_register:
		case ARM_VST1q8wb_fixed:
		case ARM_VST1q8wb_register:
		case ARM_VST2d16:
		case ARM_VST2d32:
		case ARM_VST2d8:
		case ARM_VST2d16wb_fixed:
		case ARM_VST2d16wb_register:
		case ARM_VST2d32wb_fixed:
		case ARM_VST2d32wb_register:
		case ARM_VST2d8wb_fixed:
		case ARM_VST2d8wb_register:
			if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VST2b16:
		case ARM_VST2b32:
		case ARM_VST2b8:
		case ARM_VST2b16wb_fixed:
		case ARM_VST2b16wb_register:
		case ARM_VST2b32wb_fixed:
		case ARM_VST2b32wb_register:
		case ARM_VST2b8wb_fixed:
		case ARM_VST2b8wb_register:
			if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	// Second input register
	switch (MCInst_getOpcode(Inst)) {
		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:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			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:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// Third input register
	switch (MCInst_getOpcode(Inst)) {
		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:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			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:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// Fourth input register
	switch (MCInst_getOpcode(Inst)) {
		case ARM_VST4d8:
		case ARM_VST4d16:
		case ARM_VST4d32:
		case ARM_VST4d8_UPD:
		case ARM_VST4d16_UPD:
		case ARM_VST4d32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VST4q8:
		case ARM_VST4q16:
		case ARM_VST4q32:
		case ARM_VST4q8_UPD:
		case ARM_VST4q16_UPD:
		case ARM_VST4q32_UPD:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	return S;
}

static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned align = fieldFromInstruction_4(Insn, 4, 1);
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);

	if (size == 0 && align == 1)
		return MCDisassembler_Fail;
	align *= (1 << size);

	switch (MCInst_getOpcode(Inst)) {
		case ARM_VLD1DUPq16: case ARM_VLD1DUPq32: case ARM_VLD1DUPq8:
		case ARM_VLD1DUPq16wb_fixed: case ARM_VLD1DUPq16wb_register:
		case ARM_VLD1DUPq32wb_fixed: case ARM_VLD1DUPq32wb_register:
		case ARM_VLD1DUPq8wb_fixed: case ARM_VLD1DUPq8wb_register:
			if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
	}
	if (Rm != 0xF) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));

	// The fixed offset post-increment encodes Rm == 0xd. The no-writeback
	// variant encodes Rm == 0xf. Anything else is a register offset post-
	// increment and we need to add the register operand to the instruction.
	if (Rm != 0xD && Rm != 0xF &&
			!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned align = fieldFromInstruction_4(Insn, 4, 1);
	unsigned size = 1 << fieldFromInstruction_4(Insn, 6, 2);
	align *= 2*size;

	switch (MCInst_getOpcode(Inst)) {
		case ARM_VLD2DUPd16: case ARM_VLD2DUPd32: case ARM_VLD2DUPd8:
		case ARM_VLD2DUPd16wb_fixed: case ARM_VLD2DUPd16wb_register:
		case ARM_VLD2DUPd32wb_fixed: case ARM_VLD2DUPd32wb_register:
		case ARM_VLD2DUPd8wb_fixed: case ARM_VLD2DUPd8wb_register:
			if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VLD2DUPd16x2: case ARM_VLD2DUPd32x2: case ARM_VLD2DUPd8x2:
		case ARM_VLD2DUPd16x2wb_fixed: case ARM_VLD2DUPd16x2wb_register:
		case ARM_VLD2DUPd32x2wb_fixed: case ARM_VLD2DUPd32x2wb_register:
		case ARM_VLD2DUPd8x2wb_fixed: case ARM_VLD2DUPd8x2wb_register:
			if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
	}

	if (Rm != 0xF)
		MCInst_addOperand(Inst, MCOperand_CreateImm(0));

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));

	if (Rm != 0xD && Rm != 0xF) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	return S;
}

static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned inc = fieldFromInstruction_4(Insn, 5, 1) + 1;

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
		return MCDisassembler_Fail;
	if (Rm != 0xF) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(0));

	if (Rm == 0xD)
		MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	else if (Rm != 0xF) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	return S;
}

static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	unsigned inc = fieldFromInstruction_4(Insn, 5, 1) + 1;
	unsigned align = fieldFromInstruction_4(Insn, 4, 1);

	if (size == 0x3) {
		if (align == 0)
			return MCDisassembler_Fail;
		size = 4;
		align = 16;
	} else {
		if (size == 2) {
			size = 1 << size;
			align *= 8;
		} else {
			size = 1 << size;
			align *= 4*size;
		}
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
		return MCDisassembler_Fail;
	if (Rm != 0xF) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));

	if (Rm == 0xD)
		MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	else if (Rm != 0xF) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	return S;
}

	static DecodeStatus
DecodeNEONModImmInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned imm = fieldFromInstruction_4(Insn, 0, 4);
	imm |= fieldFromInstruction_4(Insn, 16, 3) << 4;
	imm |= fieldFromInstruction_4(Insn, 24, 1) << 7;
	imm |= fieldFromInstruction_4(Insn, 8, 4) << 8;
	imm |= fieldFromInstruction_4(Insn, 5, 1) << 12;
	unsigned Q = fieldFromInstruction_4(Insn, 6, 1);

	if (Q) {
		if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
			return MCDisassembler_Fail;
	} else {
		if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	switch (MCInst_getOpcode(Inst)) {
		case ARM_VORRiv4i16:
		case ARM_VORRiv2i32:
		case ARM_VBICiv4i16:
		case ARM_VBICiv2i32:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		case ARM_VORRiv8i16:
		case ARM_VORRiv4i32:
		case ARM_VBICiv8i16:
		case ARM_VBICiv4i32:
			if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	return S;
}

static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 18, 2);

	if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(8 << size));

	return S;
}

static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(8 - Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(16 - Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(32 - Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(64 - Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rn |= fieldFromInstruction_4(Insn, 7, 1) << 4;
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;
	unsigned op = fieldFromInstruction_4(Insn, 6, 1);

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (op) {
		if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
			return MCDisassembler_Fail; // Writeback
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_VTBL2:
		case ARM_VTBX2:
			if (!Check(&S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
				return MCDisassembler_Fail;
			break;
		default:
			if (!Check(&S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned dst = fieldFromInstruction_2(Insn, 8, 3);
	unsigned imm = fieldFromInstruction_2(Insn, 0, 8);

	if (!Check(&S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
		return MCDisassembler_Fail;

	switch(MCInst_getOpcode(Inst)) {
		default:
			return MCDisassembler_Fail;
		case ARM_tADR:
			break; // tADR does not explicitly represent the PC as an operand.
		case ARM_tADDrSPi:
			MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
			break;
	}

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
	return S;
}

static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Val << 1, 12)));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Val, 21)));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(Val << 1));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 0, 3);
	unsigned Rm = fieldFromInstruction_4(Val, 3, 3);

	if (!Check(&S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 0, 3);
	unsigned imm = fieldFromInstruction_4(Val, 3, 5);

	if (!Check(&S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return S;
}

static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	unsigned imm = Val << 2;

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
	//tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);

	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));

	return MCDisassembler_Success;
}

static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 6, 4);
	unsigned Rm = fieldFromInstruction_4(Val, 2, 4);
	unsigned imm = fieldFromInstruction_4(Val, 0, 2);

	// Thumb stores cannot use PC as dest register.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2STRHs:
		case ARM_t2STRBs:
		case ARM_t2STRs:
			if (Rn == 15)
				return MCDisassembler_Fail;
		default:
			break;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return S;
}

static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);

	if (Rn == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRBs:
				MCInst_setOpcode(Inst, ARM_t2LDRBpci);
				break;
			case ARM_t2LDRHs:
				MCInst_setOpcode(Inst, ARM_t2LDRHpci);
				break;
			case ARM_t2LDRSHs:
				MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
				break;
			case ARM_t2LDRSBs:
				MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
				break;
			case ARM_t2LDRs:
				MCInst_setOpcode(Inst, ARM_t2LDRpci);
				break;
			case ARM_t2PLDs:
				MCInst_setOpcode(Inst, ARM_t2PLDpci);
				break;
			case ARM_t2PLIs:
				MCInst_setOpcode(Inst, ARM_t2PLIpci);
				break;
			default:
				return MCDisassembler_Fail;
		}

		return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
	}

	if (Rt == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRSHs:
				return MCDisassembler_Fail;
			case ARM_t2LDRHs:
				// FIXME: this instruction is only available with MP extensions,
				// this should be checked first but we don't have access to the
				// feature bits here.
				MCInst_setOpcode(Inst, ARM_t2PLDWs);
				break;
			default:
				break;
		}
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2PLDs:
		case ARM_t2PLDWs:
		case ARM_t2PLIs:
			break;
		default:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	unsigned addrmode = fieldFromInstruction_4(Insn, 4, 2);
	addrmode |= fieldFromInstruction_4(Insn, 0, 4) << 2;
	addrmode |= fieldFromInstruction_4(Insn, 16, 4) << 6;
	if (!Check(&S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned U = fieldFromInstruction_4(Insn, 9, 1);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
	imm |= (U << 8);
	imm |= (Rn << 9);

	if (Rn == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRi8:
				MCInst_setOpcode(Inst, ARM_t2LDRpci);
				break;
			case ARM_t2LDRBi8:
				MCInst_setOpcode(Inst, ARM_t2LDRBpci);
				break;
			case ARM_t2LDRSBi8:
				MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
				break;
			case ARM_t2LDRHi8:
				MCInst_setOpcode(Inst, ARM_t2LDRHpci);
				break;
			case ARM_t2LDRSHi8:
				MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
				break;
			case ARM_t2PLDi8:
				MCInst_setOpcode(Inst, ARM_t2PLDpci);
				break;
			case ARM_t2PLIi8:
				MCInst_setOpcode(Inst, ARM_t2PLIpci);
				break;
			default:
				return MCDisassembler_Fail;
		}
		return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
	}

	if (Rt == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRSHi8:
				return MCDisassembler_Fail;
			default:
				break;
		}
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2PLDi8:
		case ARM_t2PLIi8:
		case ARM_t2PLDWi8:
			break;
		default:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	return S;
}

static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	imm |= (Rn << 13);

	if (Rn == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRi12:
				MCInst_setOpcode(Inst, ARM_t2LDRpci);
				break;
			case ARM_t2LDRHi12:
				MCInst_setOpcode(Inst, ARM_t2LDRHpci);
				break;
			case ARM_t2LDRSHi12:
				MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
				break;
			case ARM_t2LDRBi12:
				MCInst_setOpcode(Inst, ARM_t2LDRBpci);
				break;
			case ARM_t2LDRSBi12:
				MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
				break;
			case ARM_t2PLDi12:
				MCInst_setOpcode(Inst, ARM_t2PLDpci);
				break;
			case ARM_t2PLIi12:
				MCInst_setOpcode(Inst, ARM_t2PLIpci);
				break;
			default:
				return MCDisassembler_Fail;
		}
		return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
	}

	if (Rt == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRSHi12:
				return MCDisassembler_Fail;
			case ARM_t2LDRHi12:
				MCInst_setOpcode(Inst, ARM_t2PLDi12);
				break;
			default:
				break;
		}
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2PLDi12:
		case ARM_t2PLDWi12:
		case ARM_t2PLIi12:
			break;
		default:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	return S;
}

static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
	imm |= (Rn << 9);

	if (Rn == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRT:
				MCInst_setOpcode(Inst, ARM_t2LDRpci);
				break;
			case ARM_t2LDRBT:
				MCInst_setOpcode(Inst, ARM_t2LDRBpci);
				break;
			case ARM_t2LDRHT:
				MCInst_setOpcode(Inst, ARM_t2LDRHpci);
				break;
			case ARM_t2LDRSBT:
				MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
				break;
			case ARM_t2LDRSHT:
				MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
				break;
			default:
				return MCDisassembler_Fail;
		}
		return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
	}

	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	return S;
}

static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void* Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned U = fieldFromInstruction_4(Insn, 23, 1);
	int imm = fieldFromInstruction_4(Insn, 0, 12);

	if (Rt == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDRBpci:
			case ARM_t2LDRHpci:
				MCInst_setOpcode(Inst, ARM_t2PLDpci);
				break;
			case ARM_t2LDRSBpci:
				MCInst_setOpcode(Inst, ARM_t2PLIpci);
				break;
			case ARM_t2LDRSHpci:
				return MCDisassembler_Fail;
			default:
				break;
		}
	}

	switch(MCInst_getOpcode(Inst)) {
		case ARM_t2PLDpci:
		case ARM_t2PLIpci:
			break;
		default:
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
				return MCDisassembler_Fail;
	}

	if (!U) {
		// Special case for #-0.
		if (imm == 0)
			imm = INT32_MIN;
		else
			imm = -imm;
	}
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return S;
}

static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (Val == 0)
		MCInst_addOperand(Inst, MCOperand_CreateImm(INT32_MIN));
	else {
		int imm = Val & 0xFF;

		if (!(Val & 0x100)) imm *= -1;
		MCInst_addOperand(Inst, MCOperand_CreateImm(imm * 4));
	}

	return MCDisassembler_Success;
}

static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
	unsigned imm = fieldFromInstruction_4(Val, 0, 9);

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 8, 4);
	unsigned imm = fieldFromInstruction_4(Val, 0, 8);

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return S;
}

static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	int imm = Val & 0xFF;
	if (Val == 0)
		imm = INT32_MIN;
	else if (!(Val & 0x100))
		imm *= -1;
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return MCDisassembler_Success;
}

static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
	unsigned imm = fieldFromInstruction_4(Val, 0, 9);

	// Thumb stores cannot use PC as dest register.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2STRT:
		case ARM_t2STRBT:
		case ARM_t2STRHT:
		case ARM_t2STRi8:
		case ARM_t2STRHi8:
		case ARM_t2STRBi8:
			if (Rn == 15)
				return MCDisassembler_Fail;
			break;
		default:
			break;
	}

	// Some instructions always use an additive offset.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2LDRT:
		case ARM_t2LDRBT:
		case ARM_t2LDRHT:
		case ARM_t2LDRSBT:
		case ARM_t2LDRSHT:
		case ARM_t2STRT:
		case ARM_t2STRBT:
		case ARM_t2STRHT:
			imm |= 0x100;
			break;
		default:
			break;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned addr = fieldFromInstruction_4(Insn, 0, 8);
	addr |= fieldFromInstruction_4(Insn, 9, 1) << 8;
	addr |= Rn << 9;
	unsigned load = fieldFromInstruction_4(Insn, 20, 1);

	if (Rn == 15) {
		switch (MCInst_getOpcode(Inst)) {
			case ARM_t2LDR_PRE:
			case ARM_t2LDR_POST:
				MCInst_setOpcode(Inst, ARM_t2LDRpci);
				break;
			case ARM_t2LDRB_PRE:
			case ARM_t2LDRB_POST:
				MCInst_setOpcode(Inst, ARM_t2LDRBpci);
				break;
			case ARM_t2LDRH_PRE:
			case ARM_t2LDRH_POST:
				MCInst_setOpcode(Inst, ARM_t2LDRHpci);
				break;
			case ARM_t2LDRSB_PRE:
			case ARM_t2LDRSB_POST:
				if (Rt == 15)
					MCInst_setOpcode(Inst, ARM_t2PLIpci);
				else
					MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
				break;
			case ARM_t2LDRSH_PRE:
			case ARM_t2LDRSH_POST:
				MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
				break;
			default:
				return MCDisassembler_Fail;
		}
		return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
	}

	if (!load) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;

	if (load) {
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	if (!Check(&S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
	unsigned imm = fieldFromInstruction_4(Val, 0, 12);

	// Thumb stores cannot use PC as dest register.
	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2STRi12:
		case ARM_t2STRBi12:
		case ARM_t2STRHi12:
			if (Rn == 15)
				return MCDisassembler_Fail;
		default:
			break;
	}

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return S;
}

static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned imm = fieldFromInstruction_2(Insn, 0, 7);

	MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
	MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
	MCInst_addOperand(Inst, MCOperand_CreateImm(imm));

	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	if (MCInst_getOpcode(Inst) == ARM_tADDrSP) {
		unsigned Rdm = fieldFromInstruction_2(Insn, 0, 3);
		Rdm |= fieldFromInstruction_2(Insn, 7, 1) << 3;

		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
			return MCDisassembler_Fail;
		MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
			return MCDisassembler_Fail;
	} else if (MCInst_getOpcode(Inst) == ARM_tADDspr) {
		unsigned Rm = fieldFromInstruction_2(Insn, 3, 4);

		MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
		MCInst_addOperand(Inst, MCOperand_CreateReg(ARM_SP));
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
			return MCDisassembler_Fail;
	}

	return S;
}

static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned imod = fieldFromInstruction_2(Insn, 4, 1) | 0x2;
	unsigned flags = fieldFromInstruction_2(Insn, 0, 3);

	MCInst_addOperand(Inst, MCOperand_CreateImm(imod));
	MCInst_addOperand(Inst, MCOperand_CreateImm(flags));

	return MCDisassembler_Success;
}

static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned add = fieldFromInstruction_4(Insn, 4, 1);

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(add));

	return S;
}

static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	// Val is passed in as S:J1:J2:imm10H:imm10L:'0'
	// Note only one trailing zero not two.  Also the J1 and J2 values are from
	// the encoded instruction.  So here change to I1 and I2 values via:
	// I1 = NOT(J1 EOR S);
	// I2 = NOT(J2 EOR S);
	// and build the imm32 with two trailing zeros as documented:
	// imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
	unsigned S = (Val >> 23) & 1;
	unsigned J1 = (Val >> 22) & 1;
	unsigned J2 = (Val >> 21) & 1;
	unsigned I1 = !(J1 ^ S);
	unsigned I2 = !(J2 ^ S);
	unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
	int imm32 = SignExtend32(tmp << 1, 25);

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm32));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (Val == 0xA || Val == 0xB)
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);

	if (Rn == ARM_SP) S = MCDisassembler_SoftFail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	return S;
}

static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned pred = fieldFromInstruction_4(Insn, 22, 4);
	if (pred == 0xE || pred == 0xF) {
		unsigned opc = fieldFromInstruction_4(Insn, 4, 28);
		switch (opc) {
			default:
				return MCDisassembler_Fail;
			case 0xf3bf8f4:
				MCInst_setOpcode(Inst, ARM_t2DSB);
				break;
			case 0xf3bf8f5:
				MCInst_setOpcode(Inst, ARM_t2DMB);
				break;
			case 0xf3bf8f6:
				MCInst_setOpcode(Inst, ARM_t2ISB);
				break;
		}

		unsigned imm = fieldFromInstruction_4(Insn, 0, 4);
		return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
	}

	unsigned brtarget = fieldFromInstruction_4(Insn, 0, 11) << 1;
	brtarget |= fieldFromInstruction_4(Insn, 11, 1) << 19;
	brtarget |= fieldFromInstruction_4(Insn, 13, 1) << 18;
	brtarget |= fieldFromInstruction_4(Insn, 16, 6) << 12;
	brtarget |= fieldFromInstruction_4(Insn, 26, 1) << 20;

	if (!Check(&S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

// 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 DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	unsigned ctrl = fieldFromInstruction_4(Val, 10, 2);
	if (ctrl == 0) {
		unsigned byte = fieldFromInstruction_4(Val, 8, 2);
		unsigned imm = fieldFromInstruction_4(Val, 0, 8);
		switch (byte) {
			case 0:
				MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
				break;
			case 1:
				MCInst_addOperand(Inst, MCOperand_CreateImm((imm << 16) | imm));
				break;
			case 2:
				MCInst_addOperand(Inst, MCOperand_CreateImm((imm << 24) | (imm << 8)));
				break;
			case 3:
				MCInst_addOperand(Inst, MCOperand_CreateImm((imm << 24) | (imm << 16) |
							(imm << 8)  |  imm));
				break;
		}
	} else {
		unsigned unrot = fieldFromInstruction_4(Val, 0, 7) | 0x80;
		unsigned rot = fieldFromInstruction_4(Val, 7, 5);
		unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
		MCInst_addOperand(Inst, MCOperand_CreateImm(imm));
	}

	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Val << 1, 9)));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	// Val is passed in as S:J1:J2:imm10:imm11
	// Note no trailing zero after imm11.  Also the J1 and J2 values are from
	// the encoded instruction.  So here change to I1 and I2 values via:
	// I1 = NOT(J1 EOR S);
	// I2 = NOT(J2 EOR S);
	// and build the imm32 with one trailing zero as documented:
	// imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
	unsigned S = (Val >> 23) & 1;
	unsigned J1 = (Val >> 22) & 1;
	unsigned J2 = (Val >> 21) & 1;
	unsigned I1 = !(J1 ^ S);
	unsigned I2 = !(J2 ^ S);
	unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
	int imm32 = SignExtend32(tmp << 1, 25);

	MCInst_addOperand(Inst, MCOperand_CreateImm(imm32));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (Val & ~0xf)
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (Val & ~0xf)
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	if (!Val) return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
	return MCDisassembler_Success;
}

static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (Rn == 0xF)
		S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;

	if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
		S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
	imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
	imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);

	if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;
	if (Rm == 0xF) S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
	imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
	imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			if (fieldFromInstruction_4(Insn, 4, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 5, 3);
			break;
		case 1:
			if (fieldFromInstruction_4(Insn, 5, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 2;
			break;
		case 2:
			if (fieldFromInstruction_4(Insn, 6, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 7, 1);

			switch (fieldFromInstruction_4(Insn, 4, 2)) {
				case 0 :
					align = 0; break;
				case 3:
					align = 4; break;
				default:
					return MCDisassembler_Fail;
			}
			break;
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			if (fieldFromInstruction_4(Insn, 4, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 5, 3);
			break;
		case 1:
			if (fieldFromInstruction_4(Insn, 5, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 2;
			break;
		case 2:
			if (fieldFromInstruction_4(Insn, 6, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 7, 1);

			switch (fieldFromInstruction_4(Insn, 4, 2)) {
				case 0: 
					align = 0; break;
				case 3:
					align = 4; break;
				default:
					return MCDisassembler_Fail;
			}
			break;
	}

	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	unsigned inc = 1;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			index = fieldFromInstruction_4(Insn, 5, 3);
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 2;
			break;
		case 1:
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 4;
			if (fieldFromInstruction_4(Insn, 5, 1))
				inc = 2;
			break;
		case 2:
			if (fieldFromInstruction_4(Insn, 5, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 7, 1);
			if (fieldFromInstruction_4(Insn, 4, 1) != 0)
				align = 8;
			if (fieldFromInstruction_4(Insn, 6, 1))
				inc = 2;
			break;
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	unsigned inc = 1;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			index = fieldFromInstruction_4(Insn, 5, 3);
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 2;
			break;
		case 1:
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 4;
			if (fieldFromInstruction_4(Insn, 5, 1))
				inc = 2;
			break;
		case 2:
			if (fieldFromInstruction_4(Insn, 5, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 7, 1);
			if (fieldFromInstruction_4(Insn, 4, 1) != 0)
				align = 8;
			if (fieldFromInstruction_4(Insn, 6, 1))
				inc = 2;
			break;
	}

	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	unsigned inc = 1;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			if (fieldFromInstruction_4(Insn, 4, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 5, 3);
			break;
		case 1:
			if (fieldFromInstruction_4(Insn, 4, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 5, 1))
				inc = 2;
			break;
		case 2:
			if (fieldFromInstruction_4(Insn, 4, 2))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 7, 1);
			if (fieldFromInstruction_4(Insn, 6, 1))
				inc = 2;
			break;
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
		return MCDisassembler_Fail;

	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	unsigned inc = 1;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			if (fieldFromInstruction_4(Insn, 4, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 5, 3);
			break;
		case 1:
			if (fieldFromInstruction_4(Insn, 4, 1))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 5, 1))
				inc = 2;
			break;
		case 2:
			if (fieldFromInstruction_4(Insn, 4, 2))
				return MCDisassembler_Fail; // UNDEFINED
			index = fieldFromInstruction_4(Insn, 7, 1);
			if (fieldFromInstruction_4(Insn, 6, 1))
				inc = 2;
			break;
	}

	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	unsigned inc = 1;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 4;
			index = fieldFromInstruction_4(Insn, 5, 3);
			break;
		case 1:
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 8;
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 5, 1))
				inc = 2;
			break;
		case 2:
			switch (fieldFromInstruction_4(Insn, 4, 2)) {
				case 0:
					align = 0; break;
				case 3:
					return MCDisassembler_Fail;
				default:
					align = 4 << fieldFromInstruction_4(Insn, 4, 2); break;
			}

			index = fieldFromInstruction_4(Insn, 7, 1);
			if (fieldFromInstruction_4(Insn, 6, 1))
				inc = 2;
			break;
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
		return MCDisassembler_Fail;

	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	unsigned size = fieldFromInstruction_4(Insn, 10, 2);

	unsigned align = 0;
	unsigned index = 0;
	unsigned inc = 1;
	switch (size) {
		default:
			return MCDisassembler_Fail;
		case 0:
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 4;
			index = fieldFromInstruction_4(Insn, 5, 3);
			break;
		case 1:
			if (fieldFromInstruction_4(Insn, 4, 1))
				align = 8;
			index = fieldFromInstruction_4(Insn, 6, 2);
			if (fieldFromInstruction_4(Insn, 5, 1))
				inc = 2;
			break;
		case 2:
			switch (fieldFromInstruction_4(Insn, 4, 2)) {
				case 0:
					align = 0; break;
				case 3:
					return MCDisassembler_Fail;
				default:
					align = 4 << fieldFromInstruction_4(Insn, 4, 2); break;
			}

			index = fieldFromInstruction_4(Insn, 7, 1);
			if (fieldFromInstruction_4(Insn, 6, 1))
				inc = 2;
			break;
	}

	if (Rm != 0xF) { // Writeback
		if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
			return MCDisassembler_Fail;
	}
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(align));
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCInst_addOperand(Inst, MCOperand_CreateReg(0));
	}

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(index));

	return S;
}

static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned Rt  = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rt2 = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm  = fieldFromInstruction_4(Insn,  5, 1);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	Rm |= fieldFromInstruction_4(Insn, 0, 4) << 1;

	if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
		S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned Rt  = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rt2 = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rm  = fieldFromInstruction_4(Insn,  5, 1);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	Rm |= fieldFromInstruction_4(Insn, 0, 4) << 1;

	if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
		S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeIT(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned pred = fieldFromInstruction_4(Insn, 4, 4);
	unsigned mask = fieldFromInstruction_4(Insn, 0, 4);

	if (pred == 0xF) {
		pred = 0xE;
		S = MCDisassembler_SoftFail;
	}

	if (mask == 0x0)
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(pred));
	MCInst_addOperand(Inst, MCOperand_CreateImm(mask));
	return S;
}

static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rt2 = fieldFromInstruction_4(Insn, 8, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned addr = fieldFromInstruction_4(Insn, 0, 8);
	unsigned W = fieldFromInstruction_4(Insn, 21, 1);
	unsigned U = fieldFromInstruction_4(Insn, 23, 1);
	unsigned P = fieldFromInstruction_4(Insn, 24, 1);
	bool writeback = (W == 1) | (P == 0);

	addr |= (U << 8) | (Rn << 9);

	if (writeback && (Rn == Rt || Rn == Rt2))
		Check(&S, MCDisassembler_SoftFail);
	if (Rt == Rt2)
		Check(&S, MCDisassembler_SoftFail);

	// Rt
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	// Rt2
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
		return MCDisassembler_Fail;
	// Writeback operand
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	// addr
	if (!Check(&S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rt2 = fieldFromInstruction_4(Insn, 8, 4);
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned addr = fieldFromInstruction_4(Insn, 0, 8);
	unsigned W = fieldFromInstruction_4(Insn, 21, 1);
	unsigned U = fieldFromInstruction_4(Insn, 23, 1);
	unsigned P = fieldFromInstruction_4(Insn, 24, 1);
	bool writeback = (W == 1) | (P == 0);

	addr |= (U << 8) | (Rn << 9);

	if (writeback && (Rn == Rt || Rn == Rt2))
		Check(&S, MCDisassembler_SoftFail);

	// Writeback operand
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	// Rt
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	// Rt2
	if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
		return MCDisassembler_Fail;
	// addr
	if (!Check(&S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeT2Adr(MCInst *Inst, uint32_t Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned sign1 = fieldFromInstruction_4(Insn, 21, 1);
	unsigned sign2 = fieldFromInstruction_4(Insn, 23, 1);
	if (sign1 != sign2) return MCDisassembler_Fail;

	unsigned Val = fieldFromInstruction_4(Insn, 0, 8);
	Val |= fieldFromInstruction_4(Insn, 12, 3) << 8;
	Val |= fieldFromInstruction_4(Insn, 26, 1) << 11;
	Val |= sign1 << 12;
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Val, 13)));

	return MCDisassembler_Success;
}

static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	// Shift of "asr #32" is not allowed in Thumb2 mode.
	if (Val == 0x20) S = MCDisassembler_SoftFail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
	return S;
}

static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned Rt   = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rt2  = fieldFromInstruction_4(Insn, 0,  4);
	unsigned Rn   = fieldFromInstruction_4(Insn, 16, 4);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);

	if (pred == 0xF)
		return DecodeCPSInstruction(Inst, Insn, Address, Decoder);

	DecodeStatus S = MCDisassembler_Success;

	if (Rt == Rn || Rn == Rt2)
		S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);
	Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);
	unsigned Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);
	Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);
	unsigned imm = fieldFromInstruction_4(Insn, 16, 6);
	unsigned cmode = fieldFromInstruction_4(Insn, 8, 4);
	unsigned op = fieldFromInstruction_4(Insn, 5, 1);

	DecodeStatus S = MCDisassembler_Success;

	// VMOVv2f32 is ambiguous with these decodings.
	if (!(imm & 0x38) && cmode == 0xF) {
		if (op == 1) return MCDisassembler_Fail;
		MCInst_setOpcode(Inst, ARM_VMOVv2f32);
		return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
	}

	if (!(imm & 0x20)) return MCDisassembler_Fail;

	if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(64 - imm));

	return S;
}

static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);
	Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);
	unsigned Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);
	Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);
	unsigned imm = fieldFromInstruction_4(Insn, 16, 6);
	unsigned cmode = fieldFromInstruction_4(Insn, 8, 4);
	unsigned op = fieldFromInstruction_4(Insn, 5, 1);

	DecodeStatus S = MCDisassembler_Success;

	// VMOVv4f32 is ambiguous with these decodings.
	if (!(imm & 0x38) && cmode == 0xF) {
		if (op == 1) return MCDisassembler_Fail;
		MCInst_setOpcode(Inst, ARM_VMOVv4f32);
		return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
	}

	if (!(imm & 0x20)) return MCDisassembler_Fail;

	if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(64 - imm));

	return S;
}

static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;

	unsigned Rn = fieldFromInstruction_4(Val, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Val, 12, 4);
	unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
	Rm |= (fieldFromInstruction_4(Val, 23, 1) << 4);
	unsigned Cond = fieldFromInstruction_4(Val, 28, 4);

	if (fieldFromInstruction_4(Val, 8, 4) != 0 || Rn == Rt)
		S = MCDisassembler_SoftFail;

	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder))) 
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
		return MCDisassembler_Fail;

	return S;
}

static DecodeStatus DecodeMRRC2(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{

	DecodeStatus S = MCDisassembler_Success;

	unsigned CRm = fieldFromInstruction_4(Val, 0, 4);
	unsigned opc1 = fieldFromInstruction_4(Val, 4, 4);
	unsigned cop = fieldFromInstruction_4(Val, 8, 4);
	unsigned Rt = fieldFromInstruction_4(Val, 12, 4);
	unsigned Rt2 = fieldFromInstruction_4(Val, 16, 4);

	if ((cop & ~0x1) == 0xa)
		return MCDisassembler_Fail;

	if (Rt == Rt2)
		S = MCDisassembler_SoftFail;

	MCInst_addOperand(Inst, MCOperand_CreateImm(cop));
	MCInst_addOperand(Inst, MCOperand_CreateImm(opc1));
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
		return MCDisassembler_Fail;
	if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
		return MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateImm(CRm));

	return S;
}

