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

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

#ifdef CAPSTONE_HAS_ARM

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

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

#include "ARMDisassembler.h"

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

#define GET_SUBTARGETINFO_ENUM
#include "ARMGenSubtargetInfo.inc"

#define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc"

#define GET_INSTRINFO_ENUM
#include "ARMGenInstrInfo.inc"

static bool ITStatus_push_back(ARM_ITStatus *it, char v)
{
	if (it->size >= sizeof(it->ITStates)) {
		// TODO: consider warning user.
		it->size = 0;
	}
	it->ITStates[it->size] = v;
	it->size++;

	return true;
}

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

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

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

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

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

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

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

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

// Forward declare these because the autogenerated code will reference them.
// Definitions are further down.
static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, const void *Decoder);
static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus 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, uint32_t Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,
		uint64_t Address, const void *Decoder);

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

// Hacky: enable all features for disassembler
uint64_t ARM_getFeatureBits(unsigned int mode)
{
	uint64_t Bits = (uint64_t)-1;	// everything by default

	// FIXME: ARM_FeatureVFPOnlySP is conflicting with everything else??
	Bits &= (~ARM_FeatureVFPOnlySP);

	// FIXME: no Armv8 support?
	//Bits -= ARM_HasV7Ops;
	//Bits &= ~ARM_FeatureMP;
	if ((mode & CS_MODE_V8) == 0)
		Bits &= ~ARM_HasV8Ops;
	//Bits &= ~ARM_HasV6Ops;

	if ((mode & CS_MODE_MCLASS) == 0)
		Bits &= (~ARM_FeatureMClass);

	// some features are mutually exclusive
	if (mode & CS_MODE_THUMB) {
		//Bits &= ~ARM_HasV6Ops;
		//Bits &= ~ARM_FeatureCRC;
		//Bits &= ~ARM_HasV5TEOps;
		//Bits &= ~ARM_HasV4TOps;
		//Bits &= ~ARM_HasV6T2Ops;
		//Bits &= ~ARM_FeatureDB;
		//Bits &= ~ARM_FeatureHWDivARM;
		//Bits &= ~ARM_FeatureNaClTrap;
		//Bits &= ~ARM_FeatureMClass;
		// ArmV8
	} else {	// ARM mode
		Bits &= ~ARM_ModeThumb;
		Bits &= ~ARM_FeatureThumb2;
	}

	return Bits;
}

#include "ARMGenDisassemblerTables.inc"

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

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

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

static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
		uint16_t *Size, uint64_t Address)
{
	uint32_t insn, i;
	uint8_t bytes[4];
	DecodeStatus result;

	if (code_len < 4)
		// not enough data
		return MCDisassembler_Fail;

	if (MI->flat_insn->detail) {
		memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
		for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++)
			MI->flat_insn->detail->arm.operands[i].vector_index = -1;
	}

	memcpy(bytes, code, 4);

	if (MODE_IS_BIG_ENDIAN(ud->mode))
		insn = (bytes[3] << 0) |
			(bytes[2] << 8) |
			(bytes[1] <<  16) |
			(((uint32_t) bytes[0]) << 24);
	else
		insn = (((uint32_t) bytes[3]) << 24) |
			(bytes[2] << 16) |
			(bytes[1] <<  8) |
			(bytes[0] <<  0);

	// Calling the auto-generated decoder function.
	result = decodeInstruction_4(DecoderTableARM32, MI, insn, Address, NULL, ud->mode);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

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

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

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

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

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

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

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

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

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

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

	//MI.insert(I, MCOperand_CreateReg0(Inst, InITBlock ? 0 : ARM_CPSR));
	MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));
}

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

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

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

	OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
	NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;

	for (i = 0; i < NumOps; ++i) {
		if (i == MCInst_getNumOperands(MI)) break;
		if (MCOperandInfo_isPredicate(&OpInfo[i])) {
			MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));
			if (CC == ARMCC_AL)
				MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, 0));
			else
				MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, ARM_CPSR));
			return S;
		}
	}

	MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));
	if (CC == ARMCC_AL)
		MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, 0));
	else
		MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, ARM_CPSR));

	return S;
}

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

	CC = ITStatus_getITCC(&(ud->ITBlock));
	if (ITStatus_instrInITBlock(&(ud->ITBlock)))
		ITStatus_advanceITState(&(ud->ITBlock));

	OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
	NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;

	for (i = 0; i < NumOps; ++i) {
		if (MCOperandInfo_isPredicate(&OpInfo[i])) {
			MCOperand_setImm(MCInst_getOperand(MI, i), CC);
			if (CC == ARMCC_AL)
				MCOperand_setReg(MCInst_getOperand(MI, i+1), 0);
			else
				MCOperand_setReg(MCInst_getOperand(MI, i+1), ARM_CPSR);
			return;
		}
	}
}

static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
		uint16_t *Size, uint64_t Address)
{
	uint8_t bytes[4];
	uint16_t insn16;
	DecodeStatus result;
	bool InITBlock;
	unsigned Firstcond, Mask; 
	uint32_t NEONLdStInsn, insn32, NEONDataInsn, NEONCryptoInsn, NEONv8Insn;
	size_t i;

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

	if (MI->flat_insn->detail) {
		memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
		for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++)
			MI->flat_insn->detail->arm.operands[i].vector_index = -1;
	}

	memcpy(bytes, code, 2);

	if (MODE_IS_BIG_ENDIAN(ud->mode))
		insn16 = (bytes[0] << 8) | bytes[1];
	else
		insn16 = (bytes[1] << 8) | bytes[0];

	result = decodeInstruction_2(DecoderTableThumb16, MI, insn16, Address, NULL, ud->mode);
	if (result != MCDisassembler_Fail) {
		*Size = 2;
		Check(&result, AddThumbPredicate(ud, MI));
		return result;
	}

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

	MCInst_clear(MI);
	result = decodeInstruction_2(DecoderTableThumb216, MI, insn16, Address, NULL, ud->mode);
	if (result != MCDisassembler_Fail) {
		*Size = 2;

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

		// If we find an IT instruction, we need to parse its condition
		// code and mask operands so that we can apply them correctly
		// to the subsequent instructions.
		if (MCInst_getOpcode(MI) == ARM_t2IT) {

			Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 0));
			Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 1));
			ITStatus_setITState(&(ud->ITBlock), (char)Firstcond, (char)Mask);
		}

		return result;
	}

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

	memcpy(bytes, code, 4);

	if (MODE_IS_BIG_ENDIAN(ud->mode))
		insn32 = (bytes[3] <<  0) |
			(bytes[2] <<  8) |
			(bytes[1] << 16) |
			(((uint32_t) bytes[0]) << 24);
	else
		insn32 = (bytes[3] <<  8) |
			(bytes[2] <<  0) |
			(((uint32_t) bytes[1]) << 24) |
			(bytes[0] << 16);

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableThumb32, MI, insn32, Address, NULL, ud->mode);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
		Check(&result, AddThumbPredicate(ud, MI));
		AddThumb1SBit(MI, InITBlock);
		return result;
	}

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

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, NULL, ud->mode);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		UpdateThumbVFPPredicate(ud, MI);
		return result;
	}

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

	MCInst_clear(MI);
	result = decodeInstruction_4(DecoderTableVFPV832, MI, insn32, Address, NULL, ud->mode);
	if (result != MCDisassembler_Fail) {
		*Size = 4;
		return result;
	}

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

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

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

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

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

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

bool Thumb_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
		uint16_t *size, uint64_t address, void *info)
{
	DecodeStatus status = _Thumb_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);

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

bool ARM_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
		uint16_t *size, uint64_t address, void *info)
{
	DecodeStatus status = _ARM_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);

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

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

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

	Register = GPRDecoderTable[RegNo];
	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

	if (RegNo == 15) 
		S = MCDisassembler_SoftFail;

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

	return S;
}

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

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

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

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

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

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

	if (RegNo > 13)
		return MCDisassembler_Fail;

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

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

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

	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

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

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

	Register = SPRDecoderTable[RegNo];
	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

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

	Register = DPRDecoderTable[RegNo];
	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

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

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

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

	Register = QPRDecoderTable[RegNo];
	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

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

	Register = DPairDecoderTable[RegNo];
	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

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

	Register = DPairSpacedDecoderTable[RegNo];
	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

static DecodeStatus 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));
	MCOperand_CreateImm0(Inst, rot_imm);
	return MCDisassembler_Success;
}

static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	ARM_AM_ShiftOpc Shift;
	unsigned Op;
	unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
	unsigned type = fieldFromInstruction_4(Val, 5, 2);
	unsigned imm = fieldFromInstruction_4(Val, 7, 5);

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

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

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

	Op = Shift | (imm << 3);
	MCOperand_CreateImm0(Inst, Op);

	return S;
}

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

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

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

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

	MCOperand_CreateImm0(Inst, Shift);

	return S;
}

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

	bool NeedDisjointWriteback = false;
	unsigned WritebackReg = 0;

	opcode = MCInst_getOpcode(Inst);
	switch (opcode) {
		default:
			break;
		case ARM_LDMIA_UPD:
		case ARM_LDMDB_UPD:
		case ARM_LDMIB_UPD:
		case ARM_LDMDA_UPD:
		case ARM_t2LDMIA_UPD:
		case ARM_t2LDMDB_UPD:
		case ARM_t2STMIA_UPD:
		case ARM_t2STMDB_UPD:
			NeedDisjointWriteback = true;
			WritebackReg = MCOperand_getReg(MCInst_getOperand(Inst, 0));
			break;
	}

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

	if (opcode == ARM_t2LDMIA_UPD && WritebackReg == ARM_SP) {
		if (Val & (1 << 13) || ((Val & (1 << 15)) && (Val & (1 << 14)))) {
			// invalid thumb2 pop
			// needs no sp in reglist and not both pc and lr set at the same time
			return MCDisassembler_Fail;
		}
	}

	return S;
}

static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned i;
	unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
	unsigned regs = fieldFromInstruction_4(Val, 0, 8);

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

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

	return S;
}

static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned i;
	unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
	unsigned regs = fieldFromInstruction_4(Val, 1, 7);

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

	return S;
}

static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	ARM_AM_AddrOpc Op;
	ARM_AM_ShiftOpc Opc;
	bool writeback;
	unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
	unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
	unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
	unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
	unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
	unsigned reg = fieldFromInstruction_4(Insn, 25, 1);
	unsigned P = fieldFromInstruction_4(Insn, 24, 1);
	unsigned W = fieldFromInstruction_4(Insn, 21, 1);
	unsigned idx_mode = 0, amt, tmp;

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

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

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

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

	Op = ARM_AM_add;
	if (!fieldFromInstruction_4(Insn, 23, 1))
		Op = ARM_AM_sub;

	writeback = (P == 0) || (W == 1);
	if (P && writeback)
		idx_mode = ARMII_IndexModePre;
	else if (!P && writeback)
		idx_mode = ARMII_IndexModePost;

	if (writeback && (Rn == 15 || Rn == Rt))
		S = MCDisassembler_SoftFail; // UNPREDICTABLE

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

		MCOperand_CreateImm0(Inst, imm);
	} else {
		MCOperand_CreateReg0(Inst, 0);
		tmp = ARM_AM_getAM2Opc(Op, imm, ARM_AM_lsl, idx_mode);
		MCOperand_CreateImm0(Inst, tmp);
	}

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

	return S;
}

static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	ARM_AM_ShiftOpc ShOp;
	unsigned shift;
	unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
	unsigned Rm = fieldFromInstruction_4(Val,  0, 4);
	unsigned type = fieldFromInstruction_4(Val, 5, 2);
	unsigned imm = fieldFromInstruction_4(Val, 7, 5);
	unsigned U = fieldFromInstruction_4(Val, 12, 1);

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

	DecodeStatus S = MCDisassembler_Success;

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

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

	if (imod == 1) return MCDisassembler_Fail;

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

	return S;
}

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

	DecodeStatus S = MCDisassembler_Success;

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

	if (imod == 1) return MCDisassembler_Fail;

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

	return S;
}

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

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

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

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

	MCOperand_CreateImm0(Inst, imm);

	return S;
}

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

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

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

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

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

	MCOperand_CreateImm0(Inst, imm);

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

	return S;
}

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

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

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

	if (U)
		MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_add, (unsigned char)imm));
	else
		MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_sub, (unsigned char)imm));

	return S;
}

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

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

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

	return Status;
}

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

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

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

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

	return S;
}


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

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

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

	return S;
}

static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned wb, Rn, Rm;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	wb = fieldFromInstruction_4(Insn, 16, 4);
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
	Rm = fieldFromInstruction_4(Insn, 0, 4);

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

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

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

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

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

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

	// AddrMode6 Offset (register)
	switch (MCInst_getOpcode(Inst)) {
		default:
			// The below have been updated to have explicit am6offset split
			// between fixed and register offset. For those instructions not
			// 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) {
				MCOperand_CreateReg0(Inst, 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 load;
	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;

	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 type, align, load;
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	if (size == 3) return MCDisassembler_Fail;

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

	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 align, load;
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	if (size == 3) return MCDisassembler_Fail;

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

	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 load;
	unsigned size = fieldFromInstruction_4(Insn, 6, 2);
	if (size == 3) return MCDisassembler_Fail;

	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 wb, Rn, Rm;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	wb = fieldFromInstruction_4(Insn, 16, 4);
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
	Rm = fieldFromInstruction_4(Insn, 0, 4);

	// 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;
			MCOperand_CreateImm0(Inst, 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)
				MCOperand_CreateReg0(Inst, 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 Rn, Rm, align, size;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rm = fieldFromInstruction_4(Insn, 0, 4);
	align = fieldFromInstruction_4(Insn, 4, 1);
	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;
	MCOperand_CreateImm0(Inst, 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 Rn, Rm, align, size;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rm = fieldFromInstruction_4(Insn, 0, 4);
	align = fieldFromInstruction_4(Insn, 4, 1);
	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)
		MCOperand_CreateImm0(Inst, 0);

	if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
		return MCDisassembler_Fail;
	MCOperand_CreateImm0(Inst, 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 Rn, Rm, inc;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rm = fieldFromInstruction_4(Insn, 0, 4);
	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;
	MCOperand_CreateImm0(Inst, 0);

	if (Rm == 0xD)
		MCOperand_CreateReg0(Inst, 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 Rn, Rm, size, inc, align;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rm = fieldFromInstruction_4(Insn, 0, 4);
	size = fieldFromInstruction_4(Insn, 6, 2);
	inc = fieldFromInstruction_4(Insn, 5, 1) + 1;
	align = fieldFromInstruction_4(Insn, 4, 1);

	if (size == 0x3) {
		if (align == 0)
			return MCDisassembler_Fail;
		align = 16;
	} else {
		if (size == 2) {
			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;
	MCOperand_CreateImm0(Inst, align);

	if (Rm == 0xD)
		MCOperand_CreateReg0(Inst, 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 imm, Q;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	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;
	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;
	}

	MCOperand_CreateImm0(Inst, 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 Rm, size;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	Rm = fieldFromInstruction_4(Insn, 0, 4);
	Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;
	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;
	MCOperand_CreateImm0(Inst, 8 << size);

	return S;
}

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

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

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

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

static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned Rn, Rm, op;
	unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
	Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
	Rn = fieldFromInstruction_4(Insn, 16, 4);
	Rn |= fieldFromInstruction_4(Insn, 7, 1) << 4;
	Rm = fieldFromInstruction_4(Insn, 0, 4);
	Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;
	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:
			MCOperand_CreateReg0(Inst, ARM_SP);
			break;
	}

	MCOperand_CreateImm0(Inst, imm);
	return S;
}

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

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

static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCOperand_CreateImm0(Inst, 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;
	MCOperand_CreateImm0(Inst, imm);

	return S;
}

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

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

	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCOperand_CreateReg0(Inst, ARM_SP);
	MCOperand_CreateImm0(Inst, 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;
	MCOperand_CreateImm0(Inst, imm);

	return S;
}

static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned addrmode;
	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;
	}

	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;
	}
	MCOperand_CreateImm0(Inst, imm);

	return S;
}

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

		if (!(Val & 0x100)) imm *= -1;
		MCOperand_CreateImm0(Inst, 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;

	MCOperand_CreateImm0(Inst, 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;
	MCOperand_CreateImm0(Inst, 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 load;
	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;
	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;
	MCOperand_CreateImm0(Inst, imm);

	return S;
}

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

	MCOperand_CreateReg0(Inst, ARM_SP);
	MCOperand_CreateReg0(Inst, ARM_SP);
	MCOperand_CreateImm0(Inst, 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;
		MCOperand_CreateReg0(Inst, 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);

		MCOperand_CreateReg0(Inst, ARM_SP);
		MCOperand_CreateReg0(Inst, 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);

	MCOperand_CreateImm0(Inst, imod);
	MCOperand_CreateImm0(Inst, 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;
	MCOperand_CreateImm0(Inst, 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);

	MCOperand_CreateImm0(Inst, 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;

	MCOperand_CreateImm0(Inst, 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 brtarget;
	unsigned pred = fieldFromInstruction_4(Insn, 22, 4);
	if (pred == 0xE || pred == 0xF) {
		unsigned imm;
		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;
		}

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

	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:
				MCOperand_CreateImm0(Inst, imm);
				break;
			case 1:
				MCOperand_CreateImm0(Inst, (imm << 16) | imm);
				break;
			case 2:
				MCOperand_CreateImm0(Inst, (imm << 24) | (imm << 8));
				break;
			case 3:
				MCOperand_CreateImm0(Inst, (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));
		MCOperand_CreateImm0(Inst, imm);
	}

	return MCDisassembler_Success;
}

static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	MCOperand_CreateImm0(Inst, 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);

	MCOperand_CreateImm0(Inst, imm32);
	return MCDisassembler_Success;
}

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

	MCOperand_CreateImm0(Inst, Val);
	return MCDisassembler_Success;
}

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

	MCOperand_CreateImm0(Inst, Val);
	return MCDisassembler_Success;
}

static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	uint64_t FeatureBits = ARM_getFeatureBits(Inst->csh->mode);
	if (FeatureBits & ARM_FeatureMClass) {
		unsigned ValLow = Val & 0xff;

		// Validate the SYSm value first.
		switch (ValLow) {
			case  0: // apsr
			case  1: // iapsr
			case  2: // eapsr
			case  3: // xpsr
			case  5: // ipsr
			case  6: // epsr
			case  7: // iepsr
			case  8: // msp
			case  9: // psp
			case 16: // primask
			case 20: // control
				break;
			case 17: // basepri
			case 18: // basepri_max
			case 19: // faultmask
				if (!(FeatureBits & ARM_HasV7Ops))
					// Values basepri, basepri_max and faultmask are only valid for v7m.
					return MCDisassembler_Fail;
				break;
			default:
				return MCDisassembler_Fail;
		}

		// The ARMv7-M architecture has an additional 2-bit mask value in the MSR
		// instruction (bits {11,10}). The mask is used only with apsr, iapsr,
		// eapsr and xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates
		// if the NZCVQ bits should be moved by the instruction. Bit mask{0}
		// indicates the move for the GE{3:0} bits, the mask{0} bit can be set
		// only if the processor includes the DSP extension.
		if ((FeatureBits & ARM_HasV7Ops) && MCInst_getOpcode(Inst) == ARM_t2MSR_M) {
			unsigned Mask = (Val >> 10) & 3;
			if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
					(!(FeatureBits & ARM_FeatureDSPThumb2) && Mask == 1))
				return MCDisassembler_Fail;
		}
	} else {
		// A/R class
		if (Val == 0)
			return MCDisassembler_Fail;
	}

	MCOperand_CreateImm0(Inst, 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 pred;
	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;
	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 pred, Rm;
	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;
	pred = fieldFromInstruction_4(Insn, 28, 4);
	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 pred;
	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;
	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 pred;
	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;
	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 size, align = 0, index = 0;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 0);
	}

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

	return S;
}

static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 0);
	}

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

	return S;
}

static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0, inc = 1;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 0);
	}

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

	return S;
}

static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0, inc = 1;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 0);
	}

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

	return S;
}

static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0, inc = 1;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 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;
	MCOperand_CreateImm0(Inst, index);

	return S;
}

static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0, inc = 1;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 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;
	MCOperand_CreateImm0(Inst, index);

	return S;
}

static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0, inc = 1;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 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;
	MCOperand_CreateImm0(Inst, index);

	return S;
}

static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned size, align = 0, index = 0, inc = 1;
	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;
	size = fieldFromInstruction_4(Insn, 10, 2);

	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;
	MCOperand_CreateImm0(Inst, align);
	if (Rm != 0xF) {
		if (Rm != 0xD) {
			if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
				return MCDisassembler_Fail;
		} else
			MCOperand_CreateReg0(Inst, 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;
	MCOperand_CreateImm0(Inst, 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;

	MCOperand_CreateImm0(Inst, pred);
	MCOperand_CreateImm0(Inst, 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 Val;
	unsigned sign1 = fieldFromInstruction_4(Insn, 21, 1);
	unsigned sign2 = fieldFromInstruction_4(Insn, 23, 1);
	if (sign1 != sign2) return MCDisassembler_Fail;

	Val = fieldFromInstruction_4(Insn, 0, 8);
	Val |= fieldFromInstruction_4(Insn, 12, 3) << 8;
	Val |= fieldFromInstruction_4(Insn, 26, 1) << 11;
	Val |= sign1 << 12;
	MCOperand_CreateImm0(Inst, 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;
	MCOperand_CreateImm0(Inst, Val);
	return S;
}

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

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

	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)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned Vm, imm, cmode, op;
	unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);
	Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);
	Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);
	Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);
	imm = fieldFromInstruction_4(Insn, 16, 6);
	cmode = fieldFromInstruction_4(Insn, 8, 4);
	op = fieldFromInstruction_4(Insn, 5, 1);

	// 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;
	MCOperand_CreateImm0(Inst, 64 - imm);

	return S;
}

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

	// 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;
	MCOperand_CreateImm0(Inst, 64 - imm);

	return S;
}

static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,
		uint64_t Address, const void *Decoder)
{
	DecodeStatus S = MCDisassembler_Success;
	unsigned Cond;
	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);
	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;

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

	return S;
}

#endif
