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

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

#ifdef CAPSTONE_HAS_ARM

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../../myinttypes.h"

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

#include "ARMDisassembler.h"

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

#define GET_SUBTARGETINFO_ENUM
#include "ARMGenSubtargetInfo.inc"

#define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc"

#define GET_INSTRINFO_ENUM
#include "ARMGenInstrInfo.inc"

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

	return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return Bits;
}

#include "ARMGenDisassemblerTables.inc"

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

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

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

// Post-decoding checks
static DecodeStatus checkDecodedInstruction(MCInst *MI,
		uint32_t Insn,
		DecodeStatus Result)
{
	switch (MCInst_getOpcode(MI)) {
		case ARM_HVC: {
			  // HVC is undefined if condition = 0xf otherwise upredictable
			  // if condition != 0xe
			  uint32_t Cond = (Insn >> 28) & 0xF;
			  if (Cond == 0xF)
				  return MCDisassembler_Fail;
			  if (Cond != 0xE)
				  return MCDisassembler_SoftFail;
			  return Result;
		  }
		default:
			   return Result;
	}
}

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

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

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

	if (ud->big_endian)
		insn = (code[3] << 0) |
			(code[2] << 8) |
			(code[1] <<  16) |
			(code[0] <<  24);
	else
		insn = (code[3] << 24) |
			(code[2] << 16) |
			(code[1] <<  8) |
			(code[0] <<  0);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

	if (ud->big_endian)
		insn16 = (code[0] << 8) | code[1];
	else
		insn16 = (code[1] << 8) | code[0];

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

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

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

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

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

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

		return result;
	}

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

	if (ud->big_endian)
		insn32 = (code[3] <<  24) |
			(code[2] <<  16) |
			(code[1] << 8) |
			(code[0] << 0);
	else
		insn32 = (code[3] <<  8) |
			(code[2] <<  0) |
			(code[1] << 24) |
			(code[0] << 16);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	if (RegNo == 15) 
		S = MCDisassembler_SoftFail;

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

	return S;
}

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

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

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

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

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

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

	if (RegNo > 13)
		return MCDisassembler_Fail;

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

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

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

	MCOperand_CreateReg0(Inst, Register);
	return MCDisassembler_Success;
}

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

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

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

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

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

static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	unsigned Register;

	//uint64_t featureBits = ARM_getFeatureBits(Inst->csh->mode);
	//bool hasD16 = featureBits & ARM_FeatureD16;

	//if (RegNo > 31 || (hasD16 && RegNo > 15))	// FIXME
	if (RegNo > 31)
		return MCDisassembler_Fail;

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

	return MCDisassembler_Success;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

	MCOperand_CreateImm0(Inst, Shift);

	return S;
}

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

	bool NeedDisjointWriteback = false;
	unsigned WritebackReg = 0;

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

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

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

	return S;
}

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

	DecodeStatus S = MCDisassembler_Success;

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

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

	if (imod == 1) return MCDisassembler_Fail;

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

	return S;
}

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

	DecodeStatus S = MCDisassembler_Success;

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

	if (imod == 1) return MCDisassembler_Fail;

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

	return S;
}

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

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

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

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

	MCOperand_CreateImm0(Inst, imm);

	return S;
}

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

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

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

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

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

	MCOperand_CreateImm0(Inst, imm);

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

	return S;
}

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

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

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

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

	return S;
}

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

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

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

	return Status;
}

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

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

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

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

	return S;
}


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

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

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

	return S;
}

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

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

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

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

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

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

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

	// AddrMode6 Offset (register)
	switch (MCInst_getOpcode(Inst)) {
		default:
			// The below have been updated to have explicit am6offset split
			// between fixed and register offset. For those instructions not
			// 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);
	uint64_t featureBits = ARM_getFeatureBits(Inst->csh->mode);
	bool hasMP = ((featureBits & ARM_FeatureMP) != 0);
	bool hasV7Ops = ((featureBits & ARM_HasV7Ops) != 0);

	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:
				MCInst_setOpcode(Inst, ARM_t2PLDWs);
				break;
			case ARM_t2LDRSBs:
				MCInst_setOpcode(Inst, ARM_t2PLIs);
			default:
				break;
		}
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2PLDs:
			break;
		case ARM_t2PLIs:
			if (!hasV7Ops)
				return MCDisassembler_Fail;
			break;
		case ARM_t2PLDWs:
			if (!hasV7Ops || !hasMP)
				return MCDisassembler_Fail;
			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);
	unsigned add = fieldFromInstruction_4(Insn, 9, 1);

	uint64_t featureBits = ARM_getFeatureBits(Inst->csh->mode);
	bool hasMP = ((featureBits & ARM_FeatureMP) != 0);
	bool hasV7Ops = ((featureBits & ARM_HasV7Ops) != 0);

	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;
			case ARM_t2LDRHi8:
				if (!add)
					MCInst_setOpcode(Inst, ARM_t2PLDWi8);
				break;
			case ARM_t2LDRSBi8:
				MCInst_setOpcode(Inst, ARM_t2PLIi8);
				break;
			default:
				break;
		}
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2PLDi8:
			break;
		case ARM_t2PLIi8:
			if (!hasV7Ops)
				return MCDisassembler_Fail;
			break;
		case ARM_t2PLDWi8:
			if (!hasV7Ops || !hasMP)
				return MCDisassembler_Fail;
			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);
	uint64_t featureBits = ARM_getFeatureBits(Inst->csh->mode);
	bool hasMP = ((featureBits & ARM_FeatureMP) != 0);
	bool hasV7Ops = ((featureBits & ARM_HasV7Ops) != 0);

	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_t2PLDWi12);
				break;
			case ARM_t2LDRSBi12:
				MCInst_setOpcode(Inst, ARM_t2PLIi12);
				break;
			default:
				break;
		}
	}

	switch (MCInst_getOpcode(Inst)) {
		case ARM_t2PLDi12:
			break;
		case ARM_t2PLIi12:
			if (!hasV7Ops)
				return MCDisassembler_Fail;
			break;
		case ARM_t2PLDWi12:
			if (!hasV7Ops || !hasMP)
				return MCDisassembler_Fail;
			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);
	uint64_t featureBits = ARM_getFeatureBits(Inst->csh->mode);
	bool hasV7Ops = ((featureBits & ARM_HasV7Ops) != 0);

	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:
			break;
		case ARM_t2PLIpci:
			if (!hasV7Ops)
				return MCDisassembler_Fail;
			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)
{
	DecodeStatus S = MCDisassembler_Success;
	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;
		}

		if (MCInst_getOpcode(Inst) == ARM_t2MSR_M) {
			unsigned Mask = fieldFromInstruction_4(Val, 10, 2);
			if (!(FeatureBits & ARM_HasV7Ops)) {
				// The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
				// unpredictable.
				if (Mask != 2)
					S = MCDisassembler_SoftFail;
			}
			else {
				// The ARMv7-M architecture stores an additional 2-bit mask value in
				// MSR 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 (Mask == 0 || (Mask != 2 && ValLow > 3) ||
						(!(FeatureBits & ARM_FeatureDSPThumb2) && (Mask & 1)))
					S = MCDisassembler_SoftFail;
			}
		}
	} else {
		// A/R class
		if (Val == 0)
			return MCDisassembler_Fail;
	}

	MCOperand_CreateImm0(Inst, Val);
	return S;
}

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

	unsigned R = fieldFromInstruction_4(Val, 5, 1);
	unsigned SysM = fieldFromInstruction_4(Val, 0, 5);

	// The table of encodings for these banked registers comes from B9.2.3 of the
	// ARM ARM. There are patterns, but nothing regular enough to make this logic
	// neater. So by fiat, these values are UNPREDICTABLE:
	if (!R) {
		if (SysM == 0x7 || SysM == 0xf || SysM == 0x18 || SysM == 0x19 ||
				SysM == 0x1a || SysM == 0x1b)
			return MCDisassembler_SoftFail;
	} else {
		if (SysM != 0xe && SysM != 0x10 && SysM != 0x12 && SysM != 0x14 &&
				SysM != 0x16 && SysM != 0x1c && SysM != 0x1e)
			return MCDisassembler_SoftFail;
	}

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