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

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

#ifdef CAPSTONE_HAS_ARM

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

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

#include "ARMDisassembler.h"

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

#define GET_SUBTARGETINFO_ENUM
#include "ARMGenSubtargetInfo.inc"

#define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc"

#define GET_INSTRINFO_ENUM
#include "ARMGenInstrInfo.inc"

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

	return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return Bits;
}

#include "ARMGenDisassemblerTables.inc"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return S;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		return result;
	}

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

	if (ud->big_endian)
		insn32 = (code[3] <<  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
