Path: blob/master/libs/capstone/arch/ARM/ARMDisassembler.c
4394 views
//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//1//2// The LLVM Compiler Infrastructure3//4// This file is distributed under the University of Illinois Open Source5// License. See LICENSE.TXT for details.6//7//===----------------------------------------------------------------------===//89/* Capstone Disassembly Engine */10/* By Nguyen Anh Quynh <[email protected]>, 2013-2019 */1112#ifdef CAPSTONE_HAS_ARM1314#include <stdio.h>15#include <string.h>16#include <stdlib.h>17#include <capstone/platform.h>1819#include "ARMAddressingModes.h"20#include "ARMBaseInfo.h"21#include "../../MCFixedLenDisassembler.h"22#include "../../MCInst.h"23#include "../../MCInstrDesc.h"24#include "../../MCRegisterInfo.h"25#include "../../LEB128.h"26#include "../../MCDisassembler.h"27#include "../../cs_priv.h"28#include "../../utils.h"2930#include "ARMDisassembler.h"31#include "ARMMapping.h"3233#define GET_SUBTARGETINFO_ENUM34#include "ARMGenSubtargetInfo.inc"3536#define GET_INSTRINFO_MC_DESC37#include "ARMGenInstrInfo.inc"3839#define GET_INSTRINFO_ENUM40#include "ARMGenInstrInfo.inc"4142static bool ITStatus_push_back(ARM_ITStatus *it, char v)43{44if (it->size >= sizeof(it->ITStates)) {45// TODO: consider warning user.46it->size = 0;47}48it->ITStates[it->size] = v;49it->size++;5051return true;52}5354// Returns true if the current instruction is in an IT block55static bool ITStatus_instrInITBlock(ARM_ITStatus *it)56{57//return !ITStates.empty();58return (it->size > 0);59}6061// Returns true if current instruction is the last instruction in an IT block62static bool ITStatus_instrLastInITBlock(ARM_ITStatus *it)63{64return (it->size == 1);65}6667// Handles the condition code status of instructions in IT blocks6869// Returns the condition code for instruction in IT block70static unsigned ITStatus_getITCC(ARM_ITStatus *it)71{72unsigned CC = ARMCC_AL;7374if (ITStatus_instrInITBlock(it))75//CC = ITStates.back();76CC = it->ITStates[it->size-1];7778return CC;79}8081// Advances the IT block state to the next T or E82static void ITStatus_advanceITState(ARM_ITStatus *it)83{84//ITStates.pop_back();85it->size--;86}8788// Called when decoding an IT instruction. Sets the IT state for the following89// instructions that for the IT block. Firstcond and Mask correspond to the90// fields in the IT instruction encoding.91static void ITStatus_setITState(ARM_ITStatus *it, char Firstcond, char Mask)92{93// (3 - the number of trailing zeros) is the number of then / else.94unsigned CondBit0 = Firstcond & 1;95unsigned NumTZ = CountTrailingZeros_32(Mask);96unsigned char CCBits = (unsigned char)Firstcond & 0xf;97unsigned Pos;9899//assert(NumTZ <= 3 && "Invalid IT mask!");100// push condition codes onto the stack the correct order for the pops101for (Pos = NumTZ + 1; Pos <= 3; ++Pos) {102bool T = ((Mask >> Pos) & 1) == (int)CondBit0;103104if (T)105ITStatus_push_back(it, CCBits);106else107ITStatus_push_back(it, CCBits ^ 1);108}109110ITStatus_push_back(it, CCBits);111}112113/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.114115static bool Check(DecodeStatus *Out, DecodeStatus In)116{117switch (In) {118case MCDisassembler_Success:119// Out stays the same.120return true;121case MCDisassembler_SoftFail:122*Out = In;123return true;124case MCDisassembler_Fail:125*Out = In;126return false;127default: // never reached128return false;129}130}131132// Forward declare these because the autogenerated code will reference them.133// Definitions are further down.134static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,135uint64_t Address, const void *Decoder);136static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst,137unsigned RegNo, uint64_t Address, const void *Decoder);138static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst,139unsigned RegNo, uint64_t Address, const void *Decoder);140static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,141uint64_t Address, const void *Decoder);142static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,143uint64_t Address, const void *Decoder);144static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,145uint64_t Address, const void *Decoder);146static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,147uint64_t Address, const void *Decoder);148static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,149uint64_t Address, const void *Decoder);150static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,151uint64_t Address, const void *Decoder);152static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,153uint64_t Address, const void *Decoder);154static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst,155unsigned RegNo, uint64_t Address, const void *Decoder);156static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,157uint64_t Address, const void *Decoder);158static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,159uint64_t Address, const void *Decoder);160static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,161unsigned RegNo, uint64_t Address, const void *Decoder);162static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,163uint64_t Address, const void *Decoder);164static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,165uint64_t Address, const void *Decoder);166static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,167uint64_t Address, const void *Decoder);168static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,169uint64_t Address, const void *Decoder);170static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,171uint64_t Address, const void *Decoder);172static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Insn,173uint64_t Address, const void *Decoder);174static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,175uint64_t Address, const void *Decoder);176static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst,177unsigned Insn, uint64_t Address, const void *Decoder);178static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Insn,179uint64_t Address, const void *Decoder);180static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst,unsigned Insn,181uint64_t Address, const void *Decoder);182static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Insn,183uint64_t Address, const void *Decoder);184static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Insn,185uint64_t Address, const void *Decoder);186static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst * Inst,187unsigned Insn, uint64_t Adddress, const void *Decoder);188static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,189uint64_t Address, const void *Decoder);190static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,191uint64_t Address, const void *Decoder);192static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,193uint64_t Address, const void *Decoder);194static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,195uint64_t Address, const void *Decoder);196static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,197uint64_t Address, const void *Decoder);198static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,199uint64_t Address, const void *Decoder);200static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,201uint64_t Address, const void *Decoder);202static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,203uint64_t Address, const void *Decoder);204static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,205uint64_t Address, const void *Decoder);206static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst,unsigned Insn,207uint64_t Address, const void *Decoder);208static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,209uint64_t Address, const void *Decoder);210static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Val,211uint64_t Address, const void *Decoder);212static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Val,213uint64_t Address, const void *Decoder);214static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Val,215uint64_t Address, const void *Decoder);216static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Val,217uint64_t Address, const void *Decoder);218static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Val,219uint64_t Address, const void *Decoder);220static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Val,221uint64_t Address, const void *Decoder);222static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Val,223uint64_t Address, const void *Decoder);224static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Val,225uint64_t Address, const void *Decoder);226static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Val,227uint64_t Address, const void *Decoder);228static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Val,229uint64_t Address, const void *Decoder);230static DecodeStatus DecodeNEONModImmInstruction(MCInst *Inst,unsigned Val,231uint64_t Address, const void *Decoder);232static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Val,233uint64_t Address, const void *Decoder);234static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,235uint64_t Address, const void *Decoder);236static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,237uint64_t Address, const void *Decoder);238static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,239uint64_t Address, const void *Decoder);240static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,241uint64_t Address, const void *Decoder);242static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,243uint64_t Address, const void *Decoder);244static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,245uint64_t Address, const void *Decoder);246static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Insn,247uint64_t Address, const void *Decoder);248static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Insn,249uint64_t Address, const void *Decoder);250static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Insn,251uint64_t Address, const void *Decoder);252static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Insn,253uint64_t Address, const void *Decoder);254static DecodeStatus DecodeBankedReg(MCInst *Inst, unsigned Insn,255uint64_t Address, const void *Decoder);256static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,257uint64_t Address, const void *Decoder);258static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,259uint64_t Address, const void *Decoder);260static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,261uint64_t Address, const void *Decoder);262static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,263uint64_t Address, const void *Decoder);264static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,265uint64_t Address, const void *Decoder);266static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,267uint64_t Address, const void *Decoder);268static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,269uint64_t Address, const void *Decoder);270static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,271uint64_t Address, const void *Decoder);272static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,273uint64_t Address, const void *Decoder);274static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,275uint64_t Address, const void *Decoder);276static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,277uint64_t Address, const void *Decoder);278static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,279uint64_t Address, const void *Decoder);280static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,281uint64_t Address, const void *Decoder);282static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,283uint64_t Address, const void *Decoder);284static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,285uint64_t Address, const void *Decoder);286static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,287uint64_t Address, const void *Decoder);288static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,289uint64_t Address, const void *Decoder);290static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,291uint64_t Address, const void *Decoder);292static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,293uint64_t Address, const void *Decoder);294static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,295uint64_t Address, const void *Decoder);296static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,297uint64_t Address, const void *Decoder);298static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,299uint64_t Address, const void *Decoder);300static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,301uint64_t Address, const void *Decoder);302static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,303uint64_t Address, const void *Decoder);304static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,305uint64_t Address, const void *Decoder);306static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,307uint64_t Address, const void *Decoder);308static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,309uint64_t Address, const void *Decoder);310static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,311uint64_t Address, const void *Decoder);312static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Val,313uint64_t Address, const void *Decoder);314static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,315uint64_t Address, const void* Decoder);316static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,317uint64_t Address, const void* Decoder);318static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,319uint64_t Address, const void* Decoder);320static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,321uint64_t Address, const void* Decoder);322static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,323uint64_t Address, const void *Decoder);324static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,325uint64_t Address, const void *Decoder);326static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,327uint64_t Address, const void *Decoder);328static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,329uint64_t Address, const void *Decoder);330static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,331uint64_t Address, const void *Decoder);332static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Val,333uint64_t Address, const void *Decoder);334static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,335uint64_t Address, const void *Decoder);336static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,337uint64_t Address, const void *Decoder);338static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,339uint64_t Address, const void *Decoder);340static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Insn,341uint64_t Address, const void *Decoder);342static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,343uint64_t Address, const void *Decoder);344static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Val,345uint64_t Address, const void *Decoder);346static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Val,347uint64_t Address, const void *Decoder);348static DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,349uint64_t Address, const void *Decoder);350static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst,unsigned Val,351uint64_t Address, const void *Decoder);352static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,353uint64_t Address, const void *Decoder);354static DecodeStatus DecodeIT(MCInst *Inst, unsigned Val,355uint64_t Address, const void *Decoder);356static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst,unsigned Insn,357uint64_t Address, const void *Decoder);358static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst,unsigned Insn,359uint64_t Address, const void *Decoder);360static DecodeStatus DecodeT2Adr(MCInst *Inst, uint32_t Val,361uint64_t Address, const void *Decoder);362static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Val,363uint64_t Address, const void *Decoder);364static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,365uint64_t Address, const void *Decoder);366static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,367uint64_t Address, const void *Decoder);368static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst *Inst, unsigned Val,369uint64_t Address, const void *Decoder);370static DecodeStatus DecodeHINTInstruction(MCInst *Inst, unsigned Insn,371uint64_t Address, const void *Decoder);372static DecodeStatus DecodeTSTInstruction(MCInst *Inst, unsigned Insn,373uint64_t Address, const void *Decoder);374static DecodeStatus DecodeSETPANInstruction(MCInst *Inst, unsigned Insn,375uint64_t Address, const void *Decoder);376static DecodeStatus DecodeAddrMode5FP16Operand(MCInst *Inst, unsigned Val,377uint64_t Address, const void *Decoder);378static DecodeStatus DecodeForVMRSandVMSR(MCInst *Inst, unsigned Val,379uint64_t Address, const void *Decoder);380static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst *Inst, unsigned Insn,381uint64_t Address, const void *Decoder);382static DecodeStatus DecodeHPRRegisterClass(MCInst *Inst, unsigned RegNo,383uint64_t Address, const void *Decoder);384385// Hacky: enable all features for disassembler386bool ARM_getFeatureBits(unsigned int mode, unsigned int feature)387{388if ((mode & CS_MODE_V8) == 0) {389// not V8 mode390if (feature == ARM_HasV8Ops || feature == ARM_HasV8_1aOps ||391feature == ARM_HasV8_4aOps || feature == ARM_HasV8_3aOps)392// HasV8MBaselineOps393return false;394}395if (feature == ARM_FeatureVFPOnlySP)396return false;397398if ((mode & CS_MODE_MCLASS) == 0) {399if (feature == ARM_FeatureMClass)400return false;401}402403if ((mode & CS_MODE_THUMB) == 0) {404// not Thumb405if (feature == ARM_FeatureThumb2 || feature == ARM_ModeThumb)406return false;407// FIXME: what mode enables D16?408if (feature == ARM_FeatureD16)409return false;410} else {411// Thumb412if (feature == ARM_FeatureD16)413return false;414}415416if (feature == ARM_FeatureMClass && (mode & CS_MODE_MCLASS) == 0)417return false;418419// we support everything420return true;421}422423#include "ARMGenDisassemblerTables.inc"424425static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,426uint64_t Address, const void *Decoder)427{428if (Val == 0xF) return MCDisassembler_Fail;429430// AL predicate is not allowed on Thumb1 branches.431if (MCInst_getOpcode(Inst) == ARM_tBcc && Val == 0xE)432return MCDisassembler_Fail;433434MCOperand_CreateImm0(Inst, Val);435436if (Val == ARMCC_AL) {437MCOperand_CreateReg0(Inst, 0);438} else439MCOperand_CreateReg0(Inst, ARM_CPSR);440441return MCDisassembler_Success;442}443444#define GET_REGINFO_MC_DESC445#include "ARMGenRegisterInfo.inc"446void ARM_init(MCRegisterInfo *MRI)447{448/*449InitMCRegisterInfo(ARMRegDesc, 289,450RA, PC,451ARMMCRegisterClasses, 103,452ARMRegUnitRoots, 77, ARMRegDiffLists, ARMRegStrings,453ARMSubRegIdxLists, 57,454ARMSubRegIdxRanges, ARMRegEncodingTable);455*/456457MCRegisterInfo_InitMCRegisterInfo(MRI, ARMRegDesc, 289,4580, 0,459ARMMCRegisterClasses, 103,4600, 0, ARMRegDiffLists, 0,461ARMSubRegIdxLists, 57,4620);463}464465// Post-decoding checks466static DecodeStatus checkDecodedInstruction(MCInst *MI,467uint32_t Insn,468DecodeStatus Result)469{470switch (MCInst_getOpcode(MI)) {471case ARM_HVC: {472// HVC is undefined if condition = 0xf otherwise upredictable473// if condition != 0xe474uint32_t Cond = (Insn >> 28) & 0xF;475476if (Cond == 0xF)477return MCDisassembler_Fail;478479if (Cond != 0xE)480return MCDisassembler_SoftFail;481482return Result;483}484default:485return Result;486}487}488489static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,490uint16_t *Size, uint64_t Address)491{492uint32_t insn;493DecodeStatus result;494495*Size = 0;496497if (code_len < 4)498// not enough data499return MCDisassembler_Fail;500501if (MI->flat_insn->detail) {502unsigned int i;503504memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm) + sizeof(cs_arm));505506for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {507MI->flat_insn->detail->arm.operands[i].vector_index = -1;508MI->flat_insn->detail->arm.operands[i].neon_lane = -1;509}510}511512if (MODE_IS_BIG_ENDIAN(ud->mode))513insn = (code[3] << 0) | (code[2] << 8) |514(code[1] << 16) | ((uint32_t) code[0] << 24);515else516insn = ((uint32_t) code[3] << 24) | (code[2] << 16) |517(code[1] << 8) | (code[0] << 0);518519// Calling the auto-generated decoder function.520result = decodeInstruction_4(DecoderTableARM32, MI, insn, Address);521if (result != MCDisassembler_Fail) {522result = checkDecodedInstruction(MI, insn, result);523if (result != MCDisassembler_Fail)524*Size = 4;525526return result;527}528529// VFP and NEON instructions, similarly, are shared between ARM530// and Thumb modes.531MCInst_clear(MI);532result = decodeInstruction_4(DecoderTableVFP32, MI, insn, Address);533if (result != MCDisassembler_Fail) {534*Size = 4;535return result;536}537538MCInst_clear(MI);539result = decodeInstruction_4(DecoderTableVFPV832, MI, insn, Address);540if (result != MCDisassembler_Fail) {541*Size = 4;542return result;543}544545MCInst_clear(MI);546result = decodeInstruction_4(DecoderTableNEONData32, MI, insn, Address);547if (result != MCDisassembler_Fail) {548*Size = 4;549// Add a fake predicate operand, because we share these instruction550// definitions with Thumb2 where these instructions are predicable.551if (!DecodePredicateOperand(MI, 0xE, Address, NULL))552return MCDisassembler_Fail;553return result;554}555556MCInst_clear(MI);557result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, insn, Address);558if (result != MCDisassembler_Fail) {559*Size = 4;560// Add a fake predicate operand, because we share these instruction561// definitions with Thumb2 where these instructions are predicable.562if (!DecodePredicateOperand(MI, 0xE, Address, NULL))563return MCDisassembler_Fail;564return result;565}566567MCInst_clear(MI);568result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn, Address);569if (result != MCDisassembler_Fail) {570*Size = 4;571// Add a fake predicate operand, because we share these instruction572// definitions with Thumb2 where these instructions are predicable.573if (!DecodePredicateOperand(MI, 0xE, Address, NULL))574return MCDisassembler_Fail;575return result;576}577578MCInst_clear(MI);579result = decodeInstruction_4(DecoderTablev8NEON32, MI, insn, Address);580if (result != MCDisassembler_Fail) {581*Size = 4;582return result;583}584585MCInst_clear(MI);586result = decodeInstruction_4(DecoderTablev8Crypto32, MI, insn, Address);587if (result != MCDisassembler_Fail) {588*Size = 4;589return result;590}591592result = decodeInstruction_4(DecoderTableCoProc32, MI, insn, Address);593if (result != MCDisassembler_Fail) {594result = checkDecodedInstruction(MI, insn, result);595if (result != MCDisassembler_Fail)596*Size = 4;597598return result;599}600601MCInst_clear(MI);602*Size = 0;603return MCDisassembler_Fail;604}605606// Thumb1 instructions don't have explicit S bits. Rather, they607// implicitly set CPSR. Since it's not represented in the encoding, the608// auto-generated decoder won't inject the CPSR operand. We need to fix609// that as a post-pass.610static void AddThumb1SBit(MCInst *MI, bool InITBlock)611{612const MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;613unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;614unsigned i;615616for (i = 0; i < NumOps; ++i) {617if (i == MCInst_getNumOperands(MI)) break;618619if (MCOperandInfo_isOptionalDef(&OpInfo[i]) && OpInfo[i].RegClass == ARM_CCRRegClassID) {620if (i > 0 && MCOperandInfo_isPredicate(&OpInfo[i - 1])) continue;621MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));622return;623}624}625626//MI.insert(I, MCOperand_CreateReg0(Inst, InITBlock ? 0 : ARM_CPSR));627MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));628}629630// Most Thumb instructions don't have explicit predicates in the631// encoding, but rather get their predicates from IT context. We need632// to fix up the predicate operands using this context information as a633// post-pass.634static DecodeStatus AddThumbPredicate(cs_struct *ud, MCInst *MI)635{636DecodeStatus S = MCDisassembler_Success;637const MCOperandInfo *OpInfo;638unsigned short NumOps;639unsigned int i;640unsigned CC;641642// A few instructions actually have predicates encoded in them. Don't643// try to overwrite it if we're seeing one of those.644switch (MCInst_getOpcode(MI)) {645case ARM_tBcc:646case ARM_t2Bcc:647case ARM_tCBZ:648case ARM_tCBNZ:649case ARM_tCPS:650case ARM_t2CPS3p:651case ARM_t2CPS2p:652case ARM_t2CPS1p:653case ARM_tMOVSr:654case ARM_tSETEND:655// Some instructions (mostly conditional branches) are not656// allowed in IT blocks.657if (ITStatus_instrInITBlock(&(ud->ITBlock)))658S = MCDisassembler_SoftFail;659else660return MCDisassembler_Success;661break;662663case ARM_t2HINT:664if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 0x10)665S = MCDisassembler_SoftFail;666break;667668case ARM_tB:669case ARM_t2B:670case ARM_t2TBB:671case ARM_t2TBH:672// Some instructions (mostly unconditional branches) can673// only appears at the end of, or outside of, an IT.674// if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())675if (ITStatus_instrInITBlock(&(ud->ITBlock)) && !ITStatus_instrLastInITBlock(&(ud->ITBlock)))676S = MCDisassembler_SoftFail;677break;678default:679break;680}681682// If we're in an IT block, base the predicate on that. Otherwise,683// assume a predicate of AL.684CC = ITStatus_getITCC(&(ud->ITBlock));685if (CC == 0xF)686CC = ARMCC_AL;687688if (ITStatus_instrInITBlock(&(ud->ITBlock)))689ITStatus_advanceITState(&(ud->ITBlock));690691OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;692NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;693694for (i = 0; i < NumOps; ++i) {695if (i == MCInst_getNumOperands(MI)) break;696697if (MCOperandInfo_isPredicate(&OpInfo[i])) {698MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));699700if (CC == ARMCC_AL)701MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, 0));702else703MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, ARM_CPSR));704705return S;706}707}708709MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));710711if (CC == ARMCC_AL)712MCInst_insert0(MI, i + 1, MCOperand_CreateReg1(MI, 0));713else714MCInst_insert0(MI, i + 1, MCOperand_CreateReg1(MI, ARM_CPSR));715716return S;717}718719// Thumb VFP instructions are a special case. Because we share their720// encodings between ARM and Thumb modes, and they are predicable in ARM721// mode, the auto-generated decoder will give them an (incorrect)722// predicate operand. We need to rewrite these operands based on the IT723// context as a post-pass.724static void UpdateThumbVFPPredicate(cs_struct *ud, MCInst *MI)725{726unsigned CC;727unsigned short NumOps;728const MCOperandInfo *OpInfo;729unsigned i;730731CC = ITStatus_getITCC(&(ud->ITBlock));732if (ITStatus_instrInITBlock(&(ud->ITBlock)))733ITStatus_advanceITState(&(ud->ITBlock));734735OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;736NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;737738for (i = 0; i < NumOps; ++i) {739if (MCOperandInfo_isPredicate(&OpInfo[i])) {740MCOperand_setImm(MCInst_getOperand(MI, i), CC);741742if (CC == ARMCC_AL)743MCOperand_setReg(MCInst_getOperand(MI, i + 1), 0);744else745MCOperand_setReg(MCInst_getOperand(MI, i + 1), ARM_CPSR);746747return;748}749}750}751752static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,753uint16_t *Size, uint64_t Address)754{755uint16_t insn16;756DecodeStatus result;757bool InITBlock;758unsigned Firstcond, Mask;759uint32_t NEONLdStInsn, insn32, NEONDataInsn, NEONCryptoInsn, NEONv8Insn;760size_t i;761762// We want to read exactly 2 bytes of data.763if (code_len < 2)764// not enough data765return MCDisassembler_Fail;766767if (MI->flat_insn->detail) {768memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm)+sizeof(cs_arm));769for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {770MI->flat_insn->detail->arm.operands[i].vector_index = -1;771MI->flat_insn->detail->arm.operands[i].neon_lane = -1;772}773}774775if (MODE_IS_BIG_ENDIAN(ud->mode))776insn16 = (code[0] << 8) | code[1];777else778insn16 = (code[1] << 8) | code[0];779780result = decodeInstruction_2(DecoderTableThumb16, MI, insn16, Address);781if (result != MCDisassembler_Fail) {782*Size = 2;783Check(&result, AddThumbPredicate(ud, MI));784return result;785}786787MCInst_clear(MI);788result = decodeInstruction_2(DecoderTableThumbSBit16, MI, insn16, Address);789if (result) {790*Size = 2;791InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));792Check(&result, AddThumbPredicate(ud, MI));793AddThumb1SBit(MI, InITBlock);794return result;795}796797MCInst_clear(MI);798result = decodeInstruction_2(DecoderTableThumb216, MI, insn16, Address);799if (result != MCDisassembler_Fail) {800*Size = 2;801802// Nested IT blocks are UNPREDICTABLE. Must be checked before we add803// the Thumb predicate.804if (MCInst_getOpcode(MI) == ARM_t2IT && ITStatus_instrInITBlock(&(ud->ITBlock)))805return MCDisassembler_SoftFail;806807Check(&result, AddThumbPredicate(ud, MI));808809// If we find an IT instruction, we need to parse its condition810// code and mask operands so that we can apply them correctly811// to the subsequent instructions.812if (MCInst_getOpcode(MI) == ARM_t2IT) {813Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 0));814Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 1));815ITStatus_setITState(&(ud->ITBlock), (char)Firstcond, (char)Mask);816817// An IT instruction that would give a 'NV' predicate is unpredictable.818// if (Firstcond == ARMCC_AL && !isPowerOf2_32(Mask))819// CS << "unpredictable IT predicate sequence";820}821822return result;823}824825// We want to read exactly 4 bytes of data.826if (code_len < 4)827// not enough data828return MCDisassembler_Fail;829830if (MODE_IS_BIG_ENDIAN(ud->mode))831insn32 = (code[3] << 0) | (code[2] << 8) |832(code[1] << 16) | ((uint32_t) code[0] << 24);833else834insn32 = (code[3] << 8) | (code[2] << 0) |835((uint32_t) code[1] << 24) | (code[0] << 16);836837MCInst_clear(MI);838result = decodeInstruction_4(DecoderTableThumb32, MI, insn32, Address);839if (result != MCDisassembler_Fail) {840*Size = 4;841InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));842Check(&result, AddThumbPredicate(ud, MI));843AddThumb1SBit(MI, InITBlock);844845return result;846}847848MCInst_clear(MI);849result = decodeInstruction_4(DecoderTableThumb232, MI, insn32, Address);850if (result != MCDisassembler_Fail) {851*Size = 4;852Check(&result, AddThumbPredicate(ud, MI));853return result;854}855856if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {857MCInst_clear(MI);858result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address);859if (result != MCDisassembler_Fail) {860*Size = 4;861UpdateThumbVFPPredicate(ud, MI);862return result;863}864}865866MCInst_clear(MI);867result = decodeInstruction_4(DecoderTableVFPV832, MI, insn32, Address);868if (result != MCDisassembler_Fail) {869*Size = 4;870return result;871}872873if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {874MCInst_clear(MI);875result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn32, Address);876if (result != MCDisassembler_Fail) {877*Size = 4;878Check(&result, AddThumbPredicate(ud, MI));879return result;880}881}882883if (fieldFromInstruction_4(insn32, 24, 8) == 0xF9) {884MCInst_clear(MI);885NEONLdStInsn = insn32;886NEONLdStInsn &= 0xF0FFFFFF;887NEONLdStInsn |= 0x04000000;888result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, Address);889if (result != MCDisassembler_Fail) {890*Size = 4;891Check(&result, AddThumbPredicate(ud, MI));892return result;893}894}895896if (fieldFromInstruction_4(insn32, 24, 4) == 0xF) {897MCInst_clear(MI);898NEONDataInsn = insn32;899NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24900NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24901NEONDataInsn |= 0x12000000; // Set bits 28 and 25902result = decodeInstruction_4(DecoderTableNEONData32, MI, NEONDataInsn, Address);903if (result != MCDisassembler_Fail) {904*Size = 4;905Check(&result, AddThumbPredicate(ud, MI));906return result;907}908}909910MCInst_clear(MI);911NEONCryptoInsn = insn32;912NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24913NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24914NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25915result = decodeInstruction_4(DecoderTablev8Crypto32, MI, NEONCryptoInsn, Address);916if (result != MCDisassembler_Fail) {917*Size = 4;918return result;919}920921MCInst_clear(MI);922NEONv8Insn = insn32;923NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26924result = decodeInstruction_4(DecoderTablev8NEON32, MI, NEONv8Insn, Address);925if (result != MCDisassembler_Fail) {926*Size = 4;927return result;928}929930MCInst_clear(MI);931result = decodeInstruction_4(DecoderTableThumb2CoProc32, MI, insn32, Address);932if (result != MCDisassembler_Fail) {933*Size = 4;934Check(&result, AddThumbPredicate(ud, MI));935return result;936}937938MCInst_clear(MI);939*Size = 0;940941return MCDisassembler_Fail;942}943944bool Thumb_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,945uint16_t *size, uint64_t address, void *info)946{947DecodeStatus status = _Thumb_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);948949// TODO: fix table gen to eliminate these special cases950if (instr->Opcode == ARM_t__brkdiv0)951return false;952953//return status == MCDisassembler_Success;954return status != MCDisassembler_Fail;955}956957bool ARM_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,958uint16_t *size, uint64_t address, void *info)959{960DecodeStatus status = _ARM_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);961962//return status == MCDisassembler_Success;963return status != MCDisassembler_Fail;964}965966static const uint16_t GPRDecoderTable[] = {967ARM_R0, ARM_R1, ARM_R2, ARM_R3,968ARM_R4, ARM_R5, ARM_R6, ARM_R7,969ARM_R8, ARM_R9, ARM_R10, ARM_R11,970ARM_R12, ARM_SP, ARM_LR, ARM_PC971};972973static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,974uint64_t Address, const void *Decoder)975{976unsigned Register;977978if (RegNo > 15)979return MCDisassembler_Fail;980981Register = GPRDecoderTable[RegNo];982MCOperand_CreateReg0(Inst, Register);983984return MCDisassembler_Success;985}986987static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst, unsigned RegNo,988uint64_t Address, const void *Decoder)989{990DecodeStatus S = MCDisassembler_Success;991992if (RegNo == 15)993S = MCDisassembler_SoftFail;994995Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));996997return S;998}9991000static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst, unsigned RegNo,1001uint64_t Address, const void *Decoder)1002{1003DecodeStatus S = MCDisassembler_Success;10041005if (RegNo == 15) {1006MCOperand_CreateReg0(Inst, ARM_APSR_NZCV);10071008return MCDisassembler_Success;1009}10101011Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));1012return S;1013}10141015static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,1016uint64_t Address, const void *Decoder)1017{1018if (RegNo > 7)1019return MCDisassembler_Fail;10201021return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);1022}10231024static const uint16_t GPRPairDecoderTable[] = {1025ARM_R0_R1, ARM_R2_R3, ARM_R4_R5, ARM_R6_R7,1026ARM_R8_R9, ARM_R10_R11, ARM_R12_SP1027};10281029static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,1030uint64_t Address, const void *Decoder)1031{1032unsigned RegisterPair;1033DecodeStatus S = MCDisassembler_Success;10341035if (RegNo > 13)1036return MCDisassembler_Fail;10371038if ((RegNo & 1) || RegNo == 0xe)1039S = MCDisassembler_SoftFail;10401041RegisterPair = GPRPairDecoderTable[RegNo / 2];1042MCOperand_CreateReg0(Inst, RegisterPair);10431044return S;1045}10461047static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,1048uint64_t Address, const void *Decoder)1049{1050unsigned Register = 0;10511052switch (RegNo) {1053case 0:1054Register = ARM_R0;1055break;1056case 1:1057Register = ARM_R1;1058break;1059case 2:1060Register = ARM_R2;1061break;1062case 3:1063Register = ARM_R3;1064break;1065case 9:1066Register = ARM_R9;1067break;1068case 12:1069Register = ARM_R12;1070break;1071default:1072return MCDisassembler_Fail;1073}10741075MCOperand_CreateReg0(Inst, Register);10761077return MCDisassembler_Success;1078}10791080static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,1081uint64_t Address, const void *Decoder)1082{1083DecodeStatus S = MCDisassembler_Success;10841085if ((RegNo == 13 && !ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops)) || RegNo == 15)1086S = MCDisassembler_SoftFail;10871088Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));10891090return S;1091}10921093static const uint16_t SPRDecoderTable[] = {1094ARM_S0, ARM_S1, ARM_S2, ARM_S3,1095ARM_S4, ARM_S5, ARM_S6, ARM_S7,1096ARM_S8, ARM_S9, ARM_S10, ARM_S11,1097ARM_S12, ARM_S13, ARM_S14, ARM_S15,1098ARM_S16, ARM_S17, ARM_S18, ARM_S19,1099ARM_S20, ARM_S21, ARM_S22, ARM_S23,1100ARM_S24, ARM_S25, ARM_S26, ARM_S27,1101ARM_S28, ARM_S29, ARM_S30, ARM_S311102};11031104static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,1105uint64_t Address, const void *Decoder)1106{1107unsigned Register;11081109if (RegNo > 31)1110return MCDisassembler_Fail;11111112Register = SPRDecoderTable[RegNo];1113MCOperand_CreateReg0(Inst, Register);11141115return MCDisassembler_Success;1116}11171118static DecodeStatus DecodeHPRRegisterClass(MCInst *Inst, unsigned RegNo,1119uint64_t Address, const void *Decoder)1120{1121return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);1122}11231124static const uint16_t DPRDecoderTable[] = {1125ARM_D0, ARM_D1, ARM_D2, ARM_D3,1126ARM_D4, ARM_D5, ARM_D6, ARM_D7,1127ARM_D8, ARM_D9, ARM_D10, ARM_D11,1128ARM_D12, ARM_D13, ARM_D14, ARM_D15,1129ARM_D16, ARM_D17, ARM_D18, ARM_D19,1130ARM_D20, ARM_D21, ARM_D22, ARM_D23,1131ARM_D24, ARM_D25, ARM_D26, ARM_D27,1132ARM_D28, ARM_D29, ARM_D30, ARM_D311133};11341135static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,1136uint64_t Address, const void *Decoder)1137{1138unsigned Register;11391140if (RegNo > 31 || (ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureD16) && RegNo > 15))1141return MCDisassembler_Fail;11421143Register = DPRDecoderTable[RegNo];1144MCOperand_CreateReg0(Inst, Register);11451146return MCDisassembler_Success;1147}11481149static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,1150uint64_t Address, const void *Decoder)1151{1152if (RegNo > 7)1153return MCDisassembler_Fail;11541155return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);1156}11571158static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst, unsigned RegNo,1159uint64_t Address, const void *Decoder)1160{1161if (RegNo > 15)1162return MCDisassembler_Fail;11631164return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);1165}11661167static const uint16_t QPRDecoderTable[] = {1168ARM_Q0, ARM_Q1, ARM_Q2, ARM_Q3,1169ARM_Q4, ARM_Q5, ARM_Q6, ARM_Q7,1170ARM_Q8, ARM_Q9, ARM_Q10, ARM_Q11,1171ARM_Q12, ARM_Q13, ARM_Q14, ARM_Q151172};11731174static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,1175uint64_t Address, const void *Decoder)1176{1177unsigned Register;11781179if (RegNo > 31 || (RegNo & 1) != 0)1180return MCDisassembler_Fail;11811182RegNo >>= 1;11831184Register = QPRDecoderTable[RegNo];1185MCOperand_CreateReg0(Inst, Register);11861187return MCDisassembler_Success;1188}11891190static const uint16_t DPairDecoderTable[] = {1191ARM_Q0, ARM_D1_D2, ARM_Q1, ARM_D3_D4, ARM_Q2, ARM_D5_D6,1192ARM_Q3, ARM_D7_D8, ARM_Q4, ARM_D9_D10, ARM_Q5, ARM_D11_D12,1193ARM_Q6, ARM_D13_D14, ARM_Q7, ARM_D15_D16, ARM_Q8, ARM_D17_D18,1194ARM_Q9, ARM_D19_D20, ARM_Q10, ARM_D21_D22, ARM_Q11, ARM_D23_D24,1195ARM_Q12, ARM_D25_D26, ARM_Q13, ARM_D27_D28, ARM_Q14, ARM_D29_D30,1196ARM_Q151197};11981199static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,1200uint64_t Address, const void *Decoder)1201{1202unsigned Register;12031204if (RegNo > 30)1205return MCDisassembler_Fail;12061207Register = DPairDecoderTable[RegNo];1208MCOperand_CreateReg0(Inst, Register);12091210return MCDisassembler_Success;1211}12121213static const uint16_t DPairSpacedDecoderTable[] = {1214ARM_D0_D2, ARM_D1_D3, ARM_D2_D4, ARM_D3_D5,1215ARM_D4_D6, ARM_D5_D7, ARM_D6_D8, ARM_D7_D9,1216ARM_D8_D10, ARM_D9_D11, ARM_D10_D12, ARM_D11_D13,1217ARM_D12_D14, ARM_D13_D15, ARM_D14_D16, ARM_D15_D17,1218ARM_D16_D18, ARM_D17_D19, ARM_D18_D20, ARM_D19_D21,1219ARM_D20_D22, ARM_D21_D23, ARM_D22_D24, ARM_D23_D25,1220ARM_D24_D26, ARM_D25_D27, ARM_D26_D28, ARM_D27_D29,1221ARM_D28_D30, ARM_D29_D311222};12231224static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,1225unsigned RegNo, uint64_t Address, const void *Decoder)1226{1227unsigned Register;12281229if (RegNo > 29)1230return MCDisassembler_Fail;12311232Register = DPairSpacedDecoderTable[RegNo];1233MCOperand_CreateReg0(Inst, Register);12341235return MCDisassembler_Success;1236}12371238static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,1239uint64_t Address, const void *Decoder)1240{1241if (Val)1242MCOperand_CreateReg0(Inst, ARM_CPSR);1243else1244MCOperand_CreateReg0(Inst, 0);12451246return MCDisassembler_Success;1247}12481249static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Val,1250uint64_t Address, const void *Decoder)1251{1252DecodeStatus S = MCDisassembler_Success;1253ARM_AM_ShiftOpc Shift;1254unsigned Op;1255unsigned Rm = fieldFromInstruction_4(Val, 0, 4);1256unsigned type = fieldFromInstruction_4(Val, 5, 2);1257unsigned imm = fieldFromInstruction_4(Val, 7, 5);12581259// Register-immediate1260if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))1261return MCDisassembler_Fail;12621263Shift = ARM_AM_lsl;1264switch (type) {1265case 0:1266Shift = ARM_AM_lsl;1267break;1268case 1:1269Shift = ARM_AM_lsr;1270break;1271case 2:1272Shift = ARM_AM_asr;1273break;1274case 3:1275Shift = ARM_AM_ror;1276break;1277}12781279if (Shift == ARM_AM_ror && imm == 0)1280Shift = ARM_AM_rrx;12811282Op = Shift | (imm << 3);1283MCOperand_CreateImm0(Inst, Op);12841285return S;1286}12871288static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Val,1289uint64_t Address, const void *Decoder)1290{1291DecodeStatus S = MCDisassembler_Success;1292ARM_AM_ShiftOpc Shift;12931294unsigned Rm = fieldFromInstruction_4(Val, 0, 4);1295unsigned type = fieldFromInstruction_4(Val, 5, 2);1296unsigned Rs = fieldFromInstruction_4(Val, 8, 4);12971298// Register-register1299if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))1300return MCDisassembler_Fail;1301if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))1302return MCDisassembler_Fail;13031304Shift = ARM_AM_lsl;1305switch (type) {1306case 0:1307Shift = ARM_AM_lsl;1308break;1309case 1:1310Shift = ARM_AM_lsr;1311break;1312case 2:1313Shift = ARM_AM_asr;1314break;1315case 3:1316Shift = ARM_AM_ror;1317break;1318}13191320MCOperand_CreateImm0(Inst, Shift);13211322return S;1323}13241325static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,1326uint64_t Address, const void *Decoder)1327{1328unsigned i;1329DecodeStatus S = MCDisassembler_Success;1330unsigned opcode;1331bool NeedDisjointWriteback = false;1332unsigned WritebackReg = 0;13331334opcode = MCInst_getOpcode(Inst);1335switch (opcode) {1336default:1337break;13381339case ARM_LDMIA_UPD:1340case ARM_LDMDB_UPD:1341case ARM_LDMIB_UPD:1342case ARM_LDMDA_UPD:1343case ARM_t2LDMIA_UPD:1344case ARM_t2LDMDB_UPD:1345case ARM_t2STMIA_UPD:1346case ARM_t2STMDB_UPD:1347NeedDisjointWriteback = true;1348WritebackReg = MCOperand_getReg(MCInst_getOperand(Inst, 0));1349break;1350}13511352// Empty register lists are not allowed.1353if (Val == 0) return MCDisassembler_Fail;13541355for (i = 0; i < 16; ++i) {1356if (Val & (1 << i)) {1357if (!Check(&S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))1358return MCDisassembler_Fail;13591360// Writeback not allowed if Rn is in the target list.1361if (NeedDisjointWriteback && WritebackReg == MCOperand_getReg(&(Inst->Operands[Inst->size - 1])))1362Check(&S, MCDisassembler_SoftFail);1363}1364}13651366return S;1367}13681369static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,1370uint64_t Address, const void *Decoder)1371{1372DecodeStatus S = MCDisassembler_Success;1373unsigned i;1374unsigned Vd = fieldFromInstruction_4(Val, 8, 5);1375unsigned regs = fieldFromInstruction_4(Val, 0, 8);13761377// In case of unpredictable encoding, tweak the operands.1378if (regs == 0 || (Vd + regs) > 32) {1379regs = Vd + regs > 32 ? 32 - Vd : regs;1380regs = (1u > regs? 1u : regs);1381S = MCDisassembler_SoftFail;1382}13831384if (!Check(&S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))1385return MCDisassembler_Fail;13861387for (i = 0; i < (regs - 1); ++i) {1388if (!Check(&S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))1389return MCDisassembler_Fail;1390}13911392return S;1393}13941395static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,1396uint64_t Address, const void *Decoder)1397{1398DecodeStatus S = MCDisassembler_Success;1399unsigned i;1400unsigned Vd = fieldFromInstruction_4(Val, 8, 5);1401unsigned regs = fieldFromInstruction_4(Val, 1, 7);14021403// In case of unpredictable encoding, tweak the operands.1404if (regs == 0 || regs > 16 || (Vd + regs) > 32) {1405regs = Vd + regs > 32 ? 32 - Vd : regs;1406regs = (1u > regs? 1u : regs);1407regs = (16u > regs? regs : 16u);1408S = MCDisassembler_SoftFail;1409}14101411if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))1412return MCDisassembler_Fail;14131414for (i = 0; i < (regs - 1); ++i) {1415if (!Check(&S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))1416return MCDisassembler_Fail;1417}14181419return S;1420}14211422static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Val,1423uint64_t Address, const void *Decoder)1424{1425// This operand encodes a mask of contiguous zeros between a specified MSB1426// and LSB. To decode it, we create the mask of all bits MSB-and-lower,1427// the mask of all bits LSB-and-lower, and then xor them to create1428// the mask of that's all ones on [msb, lsb]. Finally we not it to1429// create the final mask.1430unsigned msb = fieldFromInstruction_4(Val, 5, 5);1431unsigned lsb = fieldFromInstruction_4(Val, 0, 5);1432uint32_t lsb_mask, msb_mask;14331434DecodeStatus S = MCDisassembler_Success;1435if (lsb > msb) {1436Check(&S, MCDisassembler_SoftFail);1437// The check above will cause the warning for the "potentially undefined1438// instruction encoding" but we can't build a bad MCOperand value here1439// with a lsb > msb or else printing the MCInst will cause a crash.1440lsb = msb;1441}14421443msb_mask = 0xFFFFFFFF;1444if (msb != 31) msb_mask = (1U << (msb + 1)) - 1;1445lsb_mask = (1U << lsb) - 1;14461447MCOperand_CreateImm0(Inst, ~(msb_mask ^ lsb_mask));1448return S;1449}14501451static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,1452uint64_t Address, const void *Decoder)1453{1454DecodeStatus S = MCDisassembler_Success;14551456unsigned pred = fieldFromInstruction_4(Insn, 28, 4);1457unsigned CRd = fieldFromInstruction_4(Insn, 12, 4);1458unsigned coproc = fieldFromInstruction_4(Insn, 8, 4);1459unsigned imm = fieldFromInstruction_4(Insn, 0, 8);1460unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);1461unsigned U = fieldFromInstruction_4(Insn, 23, 1);14621463switch (MCInst_getOpcode(Inst)) {1464case ARM_LDC_OFFSET:1465case ARM_LDC_PRE:1466case ARM_LDC_POST:1467case ARM_LDC_OPTION:1468case ARM_LDCL_OFFSET:1469case ARM_LDCL_PRE:1470case ARM_LDCL_POST:1471case ARM_LDCL_OPTION:1472case ARM_STC_OFFSET:1473case ARM_STC_PRE:1474case ARM_STC_POST:1475case ARM_STC_OPTION:1476case ARM_STCL_OFFSET:1477case ARM_STCL_PRE:1478case ARM_STCL_POST:1479case ARM_STCL_OPTION:1480case ARM_t2LDC_OFFSET:1481case ARM_t2LDC_PRE:1482case ARM_t2LDC_POST:1483case ARM_t2LDC_OPTION:1484case ARM_t2LDCL_OFFSET:1485case ARM_t2LDCL_PRE:1486case ARM_t2LDCL_POST:1487case ARM_t2LDCL_OPTION:1488case ARM_t2STC_OFFSET:1489case ARM_t2STC_PRE:1490case ARM_t2STC_POST:1491case ARM_t2STC_OPTION:1492case ARM_t2STCL_OFFSET:1493case ARM_t2STCL_PRE:1494case ARM_t2STCL_POST:1495case ARM_t2STCL_OPTION:1496if (coproc == 0xA || coproc == 0xB)1497return MCDisassembler_Fail;1498break;1499default:1500break;1501}15021503if (ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops) && (coproc != 14))1504return MCDisassembler_Fail;15051506MCOperand_CreateImm0(Inst, coproc);1507MCOperand_CreateImm0(Inst, CRd);1508if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1509return MCDisassembler_Fail;15101511switch (MCInst_getOpcode(Inst)) {1512case ARM_t2LDC2_OFFSET:1513case ARM_t2LDC2L_OFFSET:1514case ARM_t2LDC2_PRE:1515case ARM_t2LDC2L_PRE:1516case ARM_t2STC2_OFFSET:1517case ARM_t2STC2L_OFFSET:1518case ARM_t2STC2_PRE:1519case ARM_t2STC2L_PRE:1520case ARM_LDC2_OFFSET:1521case ARM_LDC2L_OFFSET:1522case ARM_LDC2_PRE:1523case ARM_LDC2L_PRE:1524case ARM_STC2_OFFSET:1525case ARM_STC2L_OFFSET:1526case ARM_STC2_PRE:1527case ARM_STC2L_PRE:1528case ARM_t2LDC_OFFSET:1529case ARM_t2LDCL_OFFSET:1530case ARM_t2LDC_PRE:1531case ARM_t2LDCL_PRE:1532case ARM_t2STC_OFFSET:1533case ARM_t2STCL_OFFSET:1534case ARM_t2STC_PRE:1535case ARM_t2STCL_PRE:1536case ARM_LDC_OFFSET:1537case ARM_LDCL_OFFSET:1538case ARM_LDC_PRE:1539case ARM_LDCL_PRE:1540case ARM_STC_OFFSET:1541case ARM_STCL_OFFSET:1542case ARM_STC_PRE:1543case ARM_STCL_PRE:1544imm = ARM_AM_getAM5Opc(U ? ARM_AM_add : ARM_AM_sub, (unsigned char)imm);1545MCOperand_CreateImm0(Inst, imm);1546break;1547case ARM_t2LDC2_POST:1548case ARM_t2LDC2L_POST:1549case ARM_t2STC2_POST:1550case ARM_t2STC2L_POST:1551case ARM_LDC2_POST:1552case ARM_LDC2L_POST:1553case ARM_STC2_POST:1554case ARM_STC2L_POST:1555case ARM_t2LDC_POST:1556case ARM_t2LDCL_POST:1557case ARM_t2STC_POST:1558case ARM_t2STCL_POST:1559case ARM_LDC_POST:1560case ARM_LDCL_POST:1561case ARM_STC_POST:1562case ARM_STCL_POST:1563imm |= U << 8;1564// fall through.1565default:1566// The 'option' variant doesn't encode 'U' in the immediate since1567// the immediate is unsigned [0,255].1568MCOperand_CreateImm0(Inst, imm);1569break;1570}15711572switch (MCInst_getOpcode(Inst)) {1573case ARM_LDC_OFFSET:1574case ARM_LDC_PRE:1575case ARM_LDC_POST:1576case ARM_LDC_OPTION:1577case ARM_LDCL_OFFSET:1578case ARM_LDCL_PRE:1579case ARM_LDCL_POST:1580case ARM_LDCL_OPTION:1581case ARM_STC_OFFSET:1582case ARM_STC_PRE:1583case ARM_STC_POST:1584case ARM_STC_OPTION:1585case ARM_STCL_OFFSET:1586case ARM_STCL_PRE:1587case ARM_STCL_POST:1588case ARM_STCL_OPTION:1589if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))1590return MCDisassembler_Fail;1591break;1592default:1593break;1594}15951596return S;1597}15981599static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst, unsigned Insn,1600uint64_t Address, const void *Decoder)1601{1602DecodeStatus S = MCDisassembler_Success;1603ARM_AM_AddrOpc Op;1604ARM_AM_ShiftOpc Opc;1605bool writeback;1606unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);1607unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);1608unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);1609unsigned imm = fieldFromInstruction_4(Insn, 0, 12);1610unsigned pred = fieldFromInstruction_4(Insn, 28, 4);1611unsigned reg = fieldFromInstruction_4(Insn, 25, 1);1612unsigned P = fieldFromInstruction_4(Insn, 24, 1);1613unsigned W = fieldFromInstruction_4(Insn, 21, 1);1614unsigned idx_mode = 0, amt, tmp;16151616// On stores, the writeback operand precedes Rt.1617switch (MCInst_getOpcode(Inst)) {1618case ARM_STR_POST_IMM:1619case ARM_STR_POST_REG:1620case ARM_STRB_POST_IMM:1621case ARM_STRB_POST_REG:1622case ARM_STRT_POST_REG:1623case ARM_STRT_POST_IMM:1624case ARM_STRBT_POST_REG:1625case ARM_STRBT_POST_IMM:1626if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1627return MCDisassembler_Fail;1628break;1629default:1630break;1631}16321633if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))1634return MCDisassembler_Fail;16351636// On loads, the writeback operand comes after Rt.1637switch (MCInst_getOpcode(Inst)) {1638case ARM_LDR_POST_IMM:1639case ARM_LDR_POST_REG:1640case ARM_LDRB_POST_IMM:1641case ARM_LDRB_POST_REG:1642case ARM_LDRBT_POST_REG:1643case ARM_LDRBT_POST_IMM:1644case ARM_LDRT_POST_REG:1645case ARM_LDRT_POST_IMM:1646if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1647return MCDisassembler_Fail;1648break;1649default:1650break;1651}16521653if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1654return MCDisassembler_Fail;16551656Op = ARM_AM_add;1657if (!fieldFromInstruction_4(Insn, 23, 1))1658Op = ARM_AM_sub;16591660writeback = (P == 0) || (W == 1);1661if (P && writeback)1662idx_mode = ARMII_IndexModePre;1663else if (!P && writeback)1664idx_mode = ARMII_IndexModePost;16651666if (writeback && (Rn == 15 || Rn == Rt))1667S = MCDisassembler_SoftFail; // UNPREDICTABLE16681669if (reg) {1670if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))1671return MCDisassembler_Fail;16721673Opc = ARM_AM_lsl;1674switch(fieldFromInstruction_4(Insn, 5, 2)) {1675case 0:1676Opc = ARM_AM_lsl;1677break;1678case 1:1679Opc = ARM_AM_lsr;1680break;1681case 2:1682Opc = ARM_AM_asr;1683break;1684case 3:1685Opc = ARM_AM_ror;1686break;1687default:1688return MCDisassembler_Fail;1689}16901691amt = fieldFromInstruction_4(Insn, 7, 5);1692if (Opc == ARM_AM_ror && amt == 0)1693Opc = ARM_AM_rrx;16941695imm = ARM_AM_getAM2Opc(Op, amt, Opc, idx_mode);16961697MCOperand_CreateImm0(Inst, imm);1698} else {1699MCOperand_CreateReg0(Inst, 0);1700tmp = ARM_AM_getAM2Opc(Op, imm, ARM_AM_lsl, idx_mode);1701MCOperand_CreateImm0(Inst, tmp);1702}17031704if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))1705return MCDisassembler_Fail;17061707return S;1708}17091710static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Val,1711uint64_t Address, const void *Decoder)1712{1713DecodeStatus S = MCDisassembler_Success;1714ARM_AM_ShiftOpc ShOp;1715unsigned shift;1716unsigned Rn = fieldFromInstruction_4(Val, 13, 4);1717unsigned Rm = fieldFromInstruction_4(Val, 0, 4);1718unsigned type = fieldFromInstruction_4(Val, 5, 2);1719unsigned imm = fieldFromInstruction_4(Val, 7, 5);1720unsigned U = fieldFromInstruction_4(Val, 12, 1);17211722ShOp = ARM_AM_lsl;1723switch (type) {1724case 0:1725ShOp = ARM_AM_lsl;1726break;1727case 1:1728ShOp = ARM_AM_lsr;1729break;1730case 2:1731ShOp = ARM_AM_asr;1732break;1733case 3:1734ShOp = ARM_AM_ror;1735break;1736}17371738if (ShOp == ARM_AM_ror && imm == 0)1739ShOp = ARM_AM_rrx;17401741if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1742return MCDisassembler_Fail;17431744if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))1745return MCDisassembler_Fail;17461747if (U)1748shift = ARM_AM_getAM2Opc(ARM_AM_add, imm, ShOp, 0);1749else1750shift = ARM_AM_getAM2Opc(ARM_AM_sub, imm, ShOp, 0);17511752MCOperand_CreateImm0(Inst, shift);17531754return S;1755}17561757static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst, unsigned Insn,1758uint64_t Address, const void *Decoder)1759{1760DecodeStatus S = MCDisassembler_Success;17611762unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);1763unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);1764unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);1765unsigned type = fieldFromInstruction_4(Insn, 22, 1);1766unsigned imm = fieldFromInstruction_4(Insn, 8, 4);1767unsigned U = ((~fieldFromInstruction_4(Insn, 23, 1)) & 1) << 8;1768unsigned pred = fieldFromInstruction_4(Insn, 28, 4);1769unsigned W = fieldFromInstruction_4(Insn, 21, 1);1770unsigned P = fieldFromInstruction_4(Insn, 24, 1);1771unsigned Rt2 = Rt + 1;17721773bool writeback = (W == 1) | (P == 0);17741775// For {LD,ST}RD, Rt must be even, else undefined.1776switch (MCInst_getOpcode(Inst)) {1777case ARM_STRD:1778case ARM_STRD_PRE:1779case ARM_STRD_POST:1780case ARM_LDRD:1781case ARM_LDRD_PRE:1782case ARM_LDRD_POST:1783if (Rt & 0x1)1784S = MCDisassembler_SoftFail;1785break;1786default:1787break;1788}17891790switch (MCInst_getOpcode(Inst)) {1791case ARM_STRD:1792case ARM_STRD_PRE:1793case ARM_STRD_POST:1794if (P == 0 && W == 1)1795S = MCDisassembler_SoftFail;17961797if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))1798S = MCDisassembler_SoftFail;17991800if (type && Rm == 15)1801S = MCDisassembler_SoftFail;18021803if (Rt2 == 15)1804S = MCDisassembler_SoftFail;18051806if (!type && fieldFromInstruction_4(Insn, 8, 4))1807S = MCDisassembler_SoftFail;18081809break;18101811case ARM_STRH:1812case ARM_STRH_PRE:1813case ARM_STRH_POST:1814if (Rt == 15)1815S = MCDisassembler_SoftFail;18161817if (writeback && (Rn == 15 || Rn == Rt))1818S = MCDisassembler_SoftFail;18191820if (!type && Rm == 15)1821S = MCDisassembler_SoftFail;18221823break;18241825case ARM_LDRD:1826case ARM_LDRD_PRE:1827case ARM_LDRD_POST:1828if (type && Rn == 15) {1829if (Rt2 == 15)1830S = MCDisassembler_SoftFail;1831break;1832}18331834if (P == 0 && W == 1)1835S = MCDisassembler_SoftFail;18361837if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))1838S = MCDisassembler_SoftFail;18391840if (!type && writeback && Rn == 15)1841S = MCDisassembler_SoftFail;18421843if (writeback && (Rn == Rt || Rn == Rt2))1844S = MCDisassembler_SoftFail;18451846break;18471848case ARM_LDRH:1849case ARM_LDRH_PRE:1850case ARM_LDRH_POST:1851if (type && Rn == 15) {1852if (Rt == 15)1853S = MCDisassembler_SoftFail;1854break;1855}18561857if (Rt == 15)1858S = MCDisassembler_SoftFail;18591860if (!type && Rm == 15)1861S = MCDisassembler_SoftFail;18621863if (!type && writeback && (Rn == 15 || Rn == Rt))1864S = MCDisassembler_SoftFail;1865break;18661867case ARM_LDRSH:1868case ARM_LDRSH_PRE:1869case ARM_LDRSH_POST:1870case ARM_LDRSB:1871case ARM_LDRSB_PRE:1872case ARM_LDRSB_POST:1873if (type && Rn == 15){1874if (Rt == 15)1875S = MCDisassembler_SoftFail;1876break;1877}18781879if (type && (Rt == 15 || (writeback && Rn == Rt)))1880S = MCDisassembler_SoftFail;18811882if (!type && (Rt == 15 || Rm == 15))1883S = MCDisassembler_SoftFail;18841885if (!type && writeback && (Rn == 15 || Rn == Rt))1886S = MCDisassembler_SoftFail;18871888break;18891890default:1891break;1892}18931894if (writeback) { // Writeback1895Inst->writeback = true;18961897if (P)1898U |= ARMII_IndexModePre << 9;1899else1900U |= ARMII_IndexModePost << 9;19011902// On stores, the writeback operand precedes Rt.1903switch (MCInst_getOpcode(Inst)) {1904case ARM_STRD:1905case ARM_STRD_PRE:1906case ARM_STRD_POST:1907case ARM_STRH:1908case ARM_STRH_PRE:1909case ARM_STRH_POST:1910if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1911return MCDisassembler_Fail;1912break;1913default:1914break;1915}1916}19171918if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))1919return MCDisassembler_Fail;19201921switch (MCInst_getOpcode(Inst)) {1922case ARM_STRD:1923case ARM_STRD_PRE:1924case ARM_STRD_POST:1925case ARM_LDRD:1926case ARM_LDRD_PRE:1927case ARM_LDRD_POST:1928if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt + 1, Address, Decoder)))1929return MCDisassembler_Fail;1930break;1931default:1932break;1933}19341935if (writeback) {1936// On loads, the writeback operand comes after Rt.1937switch (MCInst_getOpcode(Inst)) {1938case ARM_LDRD:1939case ARM_LDRD_PRE:1940case ARM_LDRD_POST:1941case ARM_LDRH:1942case ARM_LDRH_PRE:1943case ARM_LDRH_POST:1944case ARM_LDRSH:1945case ARM_LDRSH_PRE:1946case ARM_LDRSH_POST:1947case ARM_LDRSB:1948case ARM_LDRSB_PRE:1949case ARM_LDRSB_POST:1950case ARM_LDRHTr:1951case ARM_LDRSBTr:1952if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1953return MCDisassembler_Fail;1954break;1955default:1956break;1957}1958}19591960if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))1961return MCDisassembler_Fail;19621963if (type) {1964MCOperand_CreateReg0(Inst, 0);1965MCOperand_CreateImm0(Inst, U | (imm << 4) | Rm);1966} else {1967if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))1968return MCDisassembler_Fail;19691970MCOperand_CreateImm0(Inst, U);1971}19721973if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))1974return MCDisassembler_Fail;19751976return S;1977}19781979static DecodeStatus DecodeRFEInstruction(MCInst *Inst, unsigned Insn,1980uint64_t Address, const void *Decoder)1981{1982DecodeStatus S = MCDisassembler_Success;19831984unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);1985unsigned mode = fieldFromInstruction_4(Insn, 23, 2);19861987switch (mode) {1988case 0:1989mode = ARM_AM_da;1990break;1991case 1:1992mode = ARM_AM_ia;1993break;1994case 2:1995mode = ARM_AM_db;1996break;1997case 3:1998mode = ARM_AM_ib;1999break;2000}20012002MCOperand_CreateImm0(Inst, mode);20032004if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2005return MCDisassembler_Fail;20062007return S;2008}20092010static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,2011uint64_t Address, const void *Decoder)2012{2013DecodeStatus S = MCDisassembler_Success;20142015unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);2016unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);2017unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);2018unsigned pred = fieldFromInstruction_4(Insn, 28, 4);20192020if (pred == 0xF)2021return DecodeCPSInstruction(Inst, Insn, Address, Decoder);20222023if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))2024return MCDisassembler_Fail;20252026if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))2027return MCDisassembler_Fail;20282029if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))2030return MCDisassembler_Fail;20312032if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))2033return MCDisassembler_Fail;20342035return S;2036}20372038static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst *Inst,2039unsigned Insn, uint64_t Address, const void *Decoder)2040{2041DecodeStatus S = MCDisassembler_Success;20422043unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);2044unsigned pred = fieldFromInstruction_4(Insn, 28, 4);2045unsigned reglist = fieldFromInstruction_4(Insn, 0, 16);20462047if (pred == 0xF) {2048// Ambiguous with RFE and SRS2049switch (MCInst_getOpcode(Inst)) {2050case ARM_LDMDA:2051MCInst_setOpcode(Inst, ARM_RFEDA);2052break;2053case ARM_LDMDA_UPD:2054MCInst_setOpcode(Inst, ARM_RFEDA_UPD);2055break;2056case ARM_LDMDB:2057MCInst_setOpcode(Inst, ARM_RFEDB);2058break;2059case ARM_LDMDB_UPD:2060MCInst_setOpcode(Inst, ARM_RFEDB_UPD);2061break;2062case ARM_LDMIA:2063MCInst_setOpcode(Inst, ARM_RFEIA);2064break;2065case ARM_LDMIA_UPD:2066MCInst_setOpcode(Inst, ARM_RFEIA_UPD);2067break;2068case ARM_LDMIB:2069MCInst_setOpcode(Inst, ARM_RFEIB);2070break;2071case ARM_LDMIB_UPD:2072MCInst_setOpcode(Inst, ARM_RFEIB_UPD);2073break;2074case ARM_STMDA:2075MCInst_setOpcode(Inst, ARM_SRSDA);2076break;2077case ARM_STMDA_UPD:2078MCInst_setOpcode(Inst, ARM_SRSDA_UPD);2079break;2080case ARM_STMDB:2081MCInst_setOpcode(Inst, ARM_SRSDB);2082break;2083case ARM_STMDB_UPD:2084MCInst_setOpcode(Inst, ARM_SRSDB_UPD);2085break;2086case ARM_STMIA:2087MCInst_setOpcode(Inst, ARM_SRSIA);2088break;2089case ARM_STMIA_UPD:2090MCInst_setOpcode(Inst, ARM_SRSIA_UPD);2091break;2092case ARM_STMIB:2093MCInst_setOpcode(Inst, ARM_SRSIB);2094break;2095case ARM_STMIB_UPD:2096MCInst_setOpcode(Inst, ARM_SRSIB_UPD);2097break;2098default:2099return MCDisassembler_Fail;2100}21012102// For stores (which become SRS's, the only operand is the mode.2103if (fieldFromInstruction_4(Insn, 20, 1) == 0) {2104// Check SRS encoding constraints2105if (!(fieldFromInstruction_4(Insn, 22, 1) == 1 &&2106fieldFromInstruction_4(Insn, 20, 1) == 0))2107return MCDisassembler_Fail;21082109MCOperand_CreateImm0(Inst, fieldFromInstruction_4(Insn, 0, 4));2110return S;2111}21122113return DecodeRFEInstruction(Inst, Insn, Address, Decoder);2114}21152116if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2117return MCDisassembler_Fail;21182119if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2120return MCDisassembler_Fail; // Tied21212122if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))2123return MCDisassembler_Fail;21242125if (!Check(&S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))2126return MCDisassembler_Fail;21272128return S;2129}21302131// Check for UNPREDICTABLE predicated ESB instruction2132static DecodeStatus DecodeHINTInstruction(MCInst *Inst, unsigned Insn,2133uint64_t Address, const void *Decoder)2134{2135unsigned pred = fieldFromInstruction_4(Insn, 28, 4);2136unsigned imm8 = fieldFromInstruction_4(Insn, 0, 8);2137DecodeStatus result = MCDisassembler_Success;21382139MCOperand_CreateImm0(Inst, imm8);21402141if (!Check(&result, DecodePredicateOperand(Inst, pred, Address, Decoder)))2142return MCDisassembler_Fail;21432144// ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,2145// so all predicates should be allowed.2146if (imm8 == 0x10 && pred != 0xe && ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureRAS))2147result = MCDisassembler_SoftFail;21482149return result;2150}21512152static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,2153uint64_t Address, const void *Decoder)2154{2155unsigned imod = fieldFromInstruction_4(Insn, 18, 2);2156unsigned M = fieldFromInstruction_4(Insn, 17, 1);2157unsigned iflags = fieldFromInstruction_4(Insn, 6, 3);2158unsigned mode = fieldFromInstruction_4(Insn, 0, 5);21592160DecodeStatus S = MCDisassembler_Success;21612162// This decoder is called from multiple location that do not check2163// the full encoding is valid before they do.2164if (fieldFromInstruction_4(Insn, 5, 1) != 0 ||2165fieldFromInstruction_4(Insn, 16, 1) != 0 ||2166fieldFromInstruction_4(Insn, 20, 8) != 0x10)2167return MCDisassembler_Fail;21682169// imod == '01' --> UNPREDICTABLE2170// NOTE: Even though this is technically UNPREDICTABLE, we choose to2171// return failure here. The '01' imod value is unprintable, so there's2172// nothing useful we could do even if we returned UNPREDICTABLE.21732174if (imod == 1) return MCDisassembler_Fail;21752176if (imod && M) {2177MCInst_setOpcode(Inst, ARM_CPS3p);2178MCOperand_CreateImm0(Inst, imod);2179MCOperand_CreateImm0(Inst, iflags);2180MCOperand_CreateImm0(Inst, mode);2181} else if (imod && !M) {2182MCInst_setOpcode(Inst, ARM_CPS2p);2183MCOperand_CreateImm0(Inst, imod);2184MCOperand_CreateImm0(Inst, iflags);2185if (mode) S = MCDisassembler_SoftFail;2186} else if (!imod && M) {2187MCInst_setOpcode(Inst, ARM_CPS1p);2188MCOperand_CreateImm0(Inst, mode);2189if (iflags) S = MCDisassembler_SoftFail;2190} else {2191// imod == '00' && M == '0' --> UNPREDICTABLE2192MCInst_setOpcode(Inst, ARM_CPS1p);2193MCOperand_CreateImm0(Inst, mode);2194S = MCDisassembler_SoftFail;2195}21962197return S;2198}21992200static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,2201uint64_t Address, const void *Decoder)2202{2203unsigned imod = fieldFromInstruction_4(Insn, 9, 2);2204unsigned M = fieldFromInstruction_4(Insn, 8, 1);2205unsigned iflags = fieldFromInstruction_4(Insn, 5, 3);2206unsigned mode = fieldFromInstruction_4(Insn, 0, 5);22072208DecodeStatus S = MCDisassembler_Success;22092210// imod == '01' --> UNPREDICTABLE2211// NOTE: Even though this is technically UNPREDICTABLE, we choose to2212// return failure here. The '01' imod value is unprintable, so there's2213// nothing useful we could do even if we returned UNPREDICTABLE.22142215if (imod == 1) return MCDisassembler_Fail;22162217if (imod && M) {2218MCInst_setOpcode(Inst, ARM_t2CPS3p);2219MCOperand_CreateImm0(Inst, imod);2220MCOperand_CreateImm0(Inst, iflags);2221MCOperand_CreateImm0(Inst, mode);2222} else if (imod && !M) {2223MCInst_setOpcode(Inst, ARM_t2CPS2p);2224MCOperand_CreateImm0(Inst, imod);2225MCOperand_CreateImm0(Inst, iflags);2226if (mode) S = MCDisassembler_SoftFail;2227} else if (!imod && M) {2228MCInst_setOpcode(Inst, ARM_t2CPS1p);2229MCOperand_CreateImm0(Inst, mode);2230if (iflags) S = MCDisassembler_SoftFail;2231} else {2232// imod == '00' && M == '0' --> this is a HINT instruction2233int imm = fieldFromInstruction_4(Insn, 0, 8);2234// HINT are defined only for immediate in [0..4]2235if (imm > 4) return MCDisassembler_Fail;22362237MCInst_setOpcode(Inst, ARM_t2HINT);2238MCOperand_CreateImm0(Inst, imm);2239}22402241return S;2242}22432244static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,2245uint64_t Address, const void *Decoder)2246{2247DecodeStatus S = MCDisassembler_Success;22482249unsigned Rd = fieldFromInstruction_4(Insn, 8, 4);2250unsigned imm = 0;22512252imm |= (fieldFromInstruction_4(Insn, 0, 8) << 0);2253imm |= (fieldFromInstruction_4(Insn, 12, 3) << 8);2254imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);2255imm |= (fieldFromInstruction_4(Insn, 26, 1) << 11);22562257if (MCInst_getOpcode(Inst) == ARM_t2MOVTi16)2258if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))2259return MCDisassembler_Fail;22602261if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))2262return MCDisassembler_Fail;22632264MCOperand_CreateImm0(Inst, imm);22652266return S;2267}22682269static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,2270uint64_t Address, const void *Decoder)2271{2272DecodeStatus S = MCDisassembler_Success;22732274unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);2275unsigned pred = fieldFromInstruction_4(Insn, 28, 4);2276unsigned imm = 0;22772278imm |= (fieldFromInstruction_4(Insn, 0, 12) << 0);2279imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);22802281if (MCInst_getOpcode(Inst) == ARM_MOVTi16)2282if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))2283return MCDisassembler_Fail;22842285if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))2286return MCDisassembler_Fail;22872288MCOperand_CreateImm0(Inst, imm);22892290if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))2291return MCDisassembler_Fail;22922293return S;2294}22952296static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,2297uint64_t Address, const void *Decoder)2298{2299DecodeStatus S = MCDisassembler_Success;23002301unsigned Rd = fieldFromInstruction_4(Insn, 16, 4);2302unsigned Rn = fieldFromInstruction_4(Insn, 0, 4);2303unsigned Rm = fieldFromInstruction_4(Insn, 8, 4);2304unsigned Ra = fieldFromInstruction_4(Insn, 12, 4);2305unsigned pred = fieldFromInstruction_4(Insn, 28, 4);23062307if (pred == 0xF)2308return DecodeCPSInstruction(Inst, Insn, Address, Decoder);23092310if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))2311return MCDisassembler_Fail;23122313if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))2314return MCDisassembler_Fail;23152316if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))2317return MCDisassembler_Fail;23182319if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))2320return MCDisassembler_Fail;23212322if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))2323return MCDisassembler_Fail;23242325return S;2326}23272328static DecodeStatus DecodeTSTInstruction(MCInst *Inst, unsigned Insn,2329uint64_t Address, const void *Decoder)2330{2331DecodeStatus S = MCDisassembler_Success;2332unsigned Pred = fieldFromInstruction_4(Insn, 28, 4);2333unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);2334unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);23352336if (Pred == 0xF)2337return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);23382339if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2340return MCDisassembler_Fail;23412342if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))2343return MCDisassembler_Fail;23442345if (!Check(&S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))2346return MCDisassembler_Fail;23472348return S;2349}23502351static DecodeStatus DecodeSETPANInstruction(MCInst *Inst, unsigned Insn,2352uint64_t Address, const void *Decoder)2353{2354DecodeStatus S = MCDisassembler_Success;2355unsigned Imm = fieldFromInstruction_4(Insn, 9, 1);23562357if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8_1aOps) || !ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops))2358return MCDisassembler_Fail;23592360// Decoder can be called from DecodeTST, which does not check the full2361// encoding is valid.2362if (fieldFromInstruction_4(Insn, 20, 12) != 0xf11 ||2363fieldFromInstruction_4(Insn, 4, 4) != 0)2364return MCDisassembler_Fail;23652366if (fieldFromInstruction_4(Insn, 10, 10) != 0 ||2367fieldFromInstruction_4(Insn, 0, 4) != 0)2368S = MCDisassembler_SoftFail;23692370MCInst_setOpcode(Inst, ARM_SETPAN);2371MCOperand_CreateImm0(Inst, Imm);23722373return S;2374}23752376static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,2377uint64_t Address, const void *Decoder)2378{2379DecodeStatus S = MCDisassembler_Success;2380unsigned add = fieldFromInstruction_4(Val, 12, 1);2381unsigned imm = fieldFromInstruction_4(Val, 0, 12);2382unsigned Rn = fieldFromInstruction_4(Val, 13, 4);23832384if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2385return MCDisassembler_Fail;23862387if (!add) imm *= (unsigned int)-1;2388if (imm == 0 && !add) imm = (unsigned int)INT32_MIN;23892390MCOperand_CreateImm0(Inst, imm);2391//if (Rn == 15)2392// tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);23932394return S;2395}23962397static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,2398uint64_t Address, const void *Decoder)2399{2400DecodeStatus S = MCDisassembler_Success;2401unsigned Rn = fieldFromInstruction_4(Val, 9, 4);2402// U == 1 to add imm, 0 to subtract it.2403unsigned U = fieldFromInstruction_4(Val, 8, 1);2404unsigned imm = fieldFromInstruction_4(Val, 0, 8);24052406if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2407return MCDisassembler_Fail;24082409if (U)2410MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_add, (unsigned char)imm));2411else2412MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_sub, (unsigned char)imm));24132414return S;2415}24162417static DecodeStatus DecodeAddrMode5FP16Operand(MCInst *Inst, unsigned Val,2418uint64_t Address, const void *Decoder)2419{2420DecodeStatus S = MCDisassembler_Success;2421unsigned Rn = fieldFromInstruction_4(Val, 9, 4);2422// U == 1 to add imm, 0 to subtract it.2423unsigned U = fieldFromInstruction_4(Val, 8, 1);2424unsigned imm = fieldFromInstruction_4(Val, 0, 8);24252426if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))2427return MCDisassembler_Fail;24282429if (U)2430MCOperand_CreateImm0(Inst, getAM5FP16Opc(ARM_AM_add, imm));2431else2432MCOperand_CreateImm0(Inst, getAM5FP16Opc(ARM_AM_sub, imm));24332434return S;2435}24362437static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,2438uint64_t Address, const void *Decoder)2439{2440return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);2441}24422443static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,2444uint64_t Address, const void *Decoder)2445{2446DecodeStatus Status = MCDisassembler_Success;24472448// Note the J1 and J2 values are from the encoded instruction. So here2449// change them to I1 and I2 values via as documented:2450// I1 = NOT(J1 EOR S);2451// I2 = NOT(J2 EOR S);2452// and build the imm32 with one trailing zero as documented:2453// imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);2454unsigned S = fieldFromInstruction_4(Insn, 26, 1);2455unsigned J1 = fieldFromInstruction_4(Insn, 13, 1);2456unsigned J2 = fieldFromInstruction_4(Insn, 11, 1);2457unsigned I1 = !(J1 ^ S);2458unsigned I2 = !(J2 ^ S);2459unsigned imm10 = fieldFromInstruction_4(Insn, 16, 10);2460unsigned imm11 = fieldFromInstruction_4(Insn, 0, 11);2461unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;2462int imm32 = SignExtend32(tmp << 1, 25);24632464MCOperand_CreateImm0(Inst, imm32);24652466return Status;2467}24682469static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst, unsigned Insn,2470uint64_t Address, const void *Decoder)2471{2472DecodeStatus S = MCDisassembler_Success;24732474unsigned pred = fieldFromInstruction_4(Insn, 28, 4);2475unsigned imm = fieldFromInstruction_4(Insn, 0, 24) << 2;24762477if (pred == 0xF) {2478MCInst_setOpcode(Inst, ARM_BLXi);2479imm |= fieldFromInstruction_4(Insn, 24, 1) << 1;2480MCOperand_CreateImm0(Inst, SignExtend32(imm, 26));2481return S;2482}24832484MCOperand_CreateImm0(Inst, SignExtend32(imm, 26));24852486if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))2487return MCDisassembler_Fail;24882489return S;2490}249124922493static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,2494uint64_t Address, const void *Decoder)2495{2496DecodeStatus S = MCDisassembler_Success;24972498unsigned Rm = fieldFromInstruction_4(Val, 0, 4);2499unsigned align = fieldFromInstruction_4(Val, 4, 2);25002501if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))2502return MCDisassembler_Fail;25032504if (!align)2505MCOperand_CreateImm0(Inst, 0);2506else2507MCOperand_CreateImm0(Inst, 4 << align);25082509return S;2510}25112512static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Insn,2513uint64_t Address, const void *Decoder)2514{2515DecodeStatus S = MCDisassembler_Success;2516unsigned wb, Rn, Rm;2517unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);2518Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;2519wb = fieldFromInstruction_4(Insn, 16, 4);2520Rn = fieldFromInstruction_4(Insn, 16, 4);2521Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;2522Rm = fieldFromInstruction_4(Insn, 0, 4);25232524// First output register2525switch (MCInst_getOpcode(Inst)) {2526case ARM_VLD1q16: case ARM_VLD1q32: case ARM_VLD1q64: case ARM_VLD1q8:2527case ARM_VLD1q16wb_fixed: case ARM_VLD1q16wb_register:2528case ARM_VLD1q32wb_fixed: case ARM_VLD1q32wb_register:2529case ARM_VLD1q64wb_fixed: case ARM_VLD1q64wb_register:2530case ARM_VLD1q8wb_fixed: case ARM_VLD1q8wb_register:2531case ARM_VLD2d16: case ARM_VLD2d32: case ARM_VLD2d8:2532case ARM_VLD2d16wb_fixed: case ARM_VLD2d16wb_register:2533case ARM_VLD2d32wb_fixed: case ARM_VLD2d32wb_register:2534case ARM_VLD2d8wb_fixed: case ARM_VLD2d8wb_register:2535if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))2536return MCDisassembler_Fail;2537break;25382539case ARM_VLD2b16:2540case ARM_VLD2b32:2541case ARM_VLD2b8:2542case ARM_VLD2b16wb_fixed:2543case ARM_VLD2b16wb_register:2544case ARM_VLD2b32wb_fixed:2545case ARM_VLD2b32wb_register:2546case ARM_VLD2b8wb_fixed:2547case ARM_VLD2b8wb_register:2548if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))2549return MCDisassembler_Fail;2550break;25512552default:2553if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))2554return MCDisassembler_Fail;2555}25562557// Second output register2558switch (MCInst_getOpcode(Inst)) {2559case ARM_VLD3d8:2560case ARM_VLD3d16:2561case ARM_VLD3d32:2562case ARM_VLD3d8_UPD:2563case ARM_VLD3d16_UPD:2564case ARM_VLD3d32_UPD:2565case ARM_VLD4d8:2566case ARM_VLD4d16:2567case ARM_VLD4d32:2568case ARM_VLD4d8_UPD:2569case ARM_VLD4d16_UPD:2570case ARM_VLD4d32_UPD:2571if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 1) % 32, Address, Decoder)))2572return MCDisassembler_Fail;2573break;25742575case ARM_VLD3q8:2576case ARM_VLD3q16:2577case ARM_VLD3q32:2578case ARM_VLD3q8_UPD:2579case ARM_VLD3q16_UPD:2580case ARM_VLD3q32_UPD:2581case ARM_VLD4q8:2582case ARM_VLD4q16:2583case ARM_VLD4q32:2584case ARM_VLD4q8_UPD:2585case ARM_VLD4q16_UPD:2586case ARM_VLD4q32_UPD:2587if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))2588return MCDisassembler_Fail;25892590default:2591break;2592}25932594// Third output register2595switch(MCInst_getOpcode(Inst)) {2596case ARM_VLD3d8:2597case ARM_VLD3d16:2598case ARM_VLD3d32:2599case ARM_VLD3d8_UPD:2600case ARM_VLD3d16_UPD:2601case ARM_VLD3d32_UPD:2602case ARM_VLD4d8:2603case ARM_VLD4d16:2604case ARM_VLD4d32:2605case ARM_VLD4d8_UPD:2606case ARM_VLD4d16_UPD:2607case ARM_VLD4d32_UPD:2608if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))2609return MCDisassembler_Fail;2610break;2611case ARM_VLD3q8:2612case ARM_VLD3q16:2613case ARM_VLD3q32:2614case ARM_VLD3q8_UPD:2615case ARM_VLD3q16_UPD:2616case ARM_VLD3q32_UPD:2617case ARM_VLD4q8:2618case ARM_VLD4q16:2619case ARM_VLD4q32:2620case ARM_VLD4q8_UPD:2621case ARM_VLD4q16_UPD:2622case ARM_VLD4q32_UPD:2623if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 4) % 32, Address, Decoder)))2624return MCDisassembler_Fail;2625break;2626default:2627break;2628}26292630// Fourth output register2631switch (MCInst_getOpcode(Inst)) {2632case ARM_VLD4d8:2633case ARM_VLD4d16:2634case ARM_VLD4d32:2635case ARM_VLD4d8_UPD:2636case ARM_VLD4d16_UPD:2637case ARM_VLD4d32_UPD:2638if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 3) % 32, Address, Decoder)))2639return MCDisassembler_Fail;2640break;2641case ARM_VLD4q8:2642case ARM_VLD4q16:2643case ARM_VLD4q32:2644case ARM_VLD4q8_UPD:2645case ARM_VLD4q16_UPD:2646case ARM_VLD4q32_UPD:2647if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 6) % 32, Address, Decoder)))2648return MCDisassembler_Fail;2649break;2650default:2651break;2652}26532654// Writeback operand2655switch (MCInst_getOpcode(Inst)) {2656case ARM_VLD1d8wb_fixed:2657case ARM_VLD1d16wb_fixed:2658case ARM_VLD1d32wb_fixed:2659case ARM_VLD1d64wb_fixed:2660case ARM_VLD1d8wb_register:2661case ARM_VLD1d16wb_register:2662case ARM_VLD1d32wb_register:2663case ARM_VLD1d64wb_register:2664case ARM_VLD1q8wb_fixed:2665case ARM_VLD1q16wb_fixed:2666case ARM_VLD1q32wb_fixed:2667case ARM_VLD1q64wb_fixed:2668case ARM_VLD1q8wb_register:2669case ARM_VLD1q16wb_register:2670case ARM_VLD1q32wb_register:2671case ARM_VLD1q64wb_register:2672case ARM_VLD1d8Twb_fixed:2673case ARM_VLD1d8Twb_register:2674case ARM_VLD1d16Twb_fixed:2675case ARM_VLD1d16Twb_register:2676case ARM_VLD1d32Twb_fixed:2677case ARM_VLD1d32Twb_register:2678case ARM_VLD1d64Twb_fixed:2679case ARM_VLD1d64Twb_register:2680case ARM_VLD1d8Qwb_fixed:2681case ARM_VLD1d8Qwb_register:2682case ARM_VLD1d16Qwb_fixed:2683case ARM_VLD1d16Qwb_register:2684case ARM_VLD1d32Qwb_fixed:2685case ARM_VLD1d32Qwb_register:2686case ARM_VLD1d64Qwb_fixed:2687case ARM_VLD1d64Qwb_register:2688case ARM_VLD2d8wb_fixed:2689case ARM_VLD2d16wb_fixed:2690case ARM_VLD2d32wb_fixed:2691case ARM_VLD2q8wb_fixed:2692case ARM_VLD2q16wb_fixed:2693case ARM_VLD2q32wb_fixed:2694case ARM_VLD2d8wb_register:2695case ARM_VLD2d16wb_register:2696case ARM_VLD2d32wb_register:2697case ARM_VLD2q8wb_register:2698case ARM_VLD2q16wb_register:2699case ARM_VLD2q32wb_register:2700case ARM_VLD2b8wb_fixed:2701case ARM_VLD2b16wb_fixed:2702case ARM_VLD2b32wb_fixed:2703case ARM_VLD2b8wb_register:2704case ARM_VLD2b16wb_register:2705case ARM_VLD2b32wb_register:2706MCOperand_CreateImm0(Inst, 0);2707break;27082709case ARM_VLD3d8_UPD:2710case ARM_VLD3d16_UPD:2711case ARM_VLD3d32_UPD:2712case ARM_VLD3q8_UPD:2713case ARM_VLD3q16_UPD:2714case ARM_VLD3q32_UPD:2715case ARM_VLD4d8_UPD:2716case ARM_VLD4d16_UPD:2717case ARM_VLD4d32_UPD:2718case ARM_VLD4q8_UPD:2719case ARM_VLD4q16_UPD:2720case ARM_VLD4q32_UPD:2721if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))2722return MCDisassembler_Fail;2723break;27242725default:2726break;2727}27282729// AddrMode6 Base (register+alignment)2730if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))2731return MCDisassembler_Fail;27322733// AddrMode6 Offset (register)2734switch (MCInst_getOpcode(Inst)) {2735default:2736// The below have been updated to have explicit am6offset split2737// between fixed and register offset. For those instructions not2738// yet updated, we need to add an additional reg0 operand for the2739// fixed variant.2740//2741// The fixed offset encodes as Rm == 0xd, so we check for that.2742if (Rm == 0xd) {2743MCOperand_CreateReg0(Inst, 0);2744break;2745}2746// Fall through to handle the register offset variant.27472748case ARM_VLD1d8wb_fixed:2749case ARM_VLD1d16wb_fixed:2750case ARM_VLD1d32wb_fixed:2751case ARM_VLD1d64wb_fixed:2752case ARM_VLD1d8Twb_fixed:2753case ARM_VLD1d16Twb_fixed:2754case ARM_VLD1d32Twb_fixed:2755case ARM_VLD1d64Twb_fixed:2756case ARM_VLD1d8Qwb_fixed:2757case ARM_VLD1d16Qwb_fixed:2758case ARM_VLD1d32Qwb_fixed:2759case ARM_VLD1d64Qwb_fixed:2760case ARM_VLD1d8wb_register:2761case ARM_VLD1d16wb_register:2762case ARM_VLD1d32wb_register:2763case ARM_VLD1d64wb_register:2764case ARM_VLD1q8wb_fixed:2765case ARM_VLD1q16wb_fixed:2766case ARM_VLD1q32wb_fixed:2767case ARM_VLD1q64wb_fixed:2768case ARM_VLD1q8wb_register:2769case ARM_VLD1q16wb_register:2770case ARM_VLD1q32wb_register:2771case ARM_VLD1q64wb_register:2772// The fixed offset post-increment encodes Rm == 0xd. The no-writeback2773// variant encodes Rm == 0xf. Anything else is a register offset post-2774// increment and we need to add the register operand to the instruction.2775if (Rm != 0xD && Rm != 0xF &&2776!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))2777return MCDisassembler_Fail;2778break;27792780case ARM_VLD2d8wb_fixed:2781case ARM_VLD2d16wb_fixed:2782case ARM_VLD2d32wb_fixed:2783case ARM_VLD2b8wb_fixed:2784case ARM_VLD2b16wb_fixed:2785case ARM_VLD2b32wb_fixed:2786case ARM_VLD2q8wb_fixed:2787case ARM_VLD2q16wb_fixed:2788case ARM_VLD2q32wb_fixed:2789break;2790}27912792return S;2793}27942795static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Insn,2796uint64_t Address, const void *Decoder)2797{2798unsigned load;2799unsigned type = fieldFromInstruction_4(Insn, 8, 4);2800unsigned align = fieldFromInstruction_4(Insn, 4, 2);2801if (type == 6 && (align & 2)) return MCDisassembler_Fail;2802if (type == 7 && (align & 2)) return MCDisassembler_Fail;2803if (type == 10 && align == 3) return MCDisassembler_Fail;28042805load = fieldFromInstruction_4(Insn, 21, 1);28062807return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)2808: DecodeVSTInstruction(Inst, Insn, Address, Decoder);2809}28102811static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Insn,2812uint64_t Address, const void *Decoder)2813{2814unsigned type, align, load;2815unsigned size = fieldFromInstruction_4(Insn, 6, 2);2816if (size == 3) return MCDisassembler_Fail;28172818type = fieldFromInstruction_4(Insn, 8, 4);2819align = fieldFromInstruction_4(Insn, 4, 2);2820if (type == 8 && align == 3) return MCDisassembler_Fail;2821if (type == 9 && align == 3) return MCDisassembler_Fail;28222823load = fieldFromInstruction_4(Insn, 21, 1);28242825return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)2826: DecodeVSTInstruction(Inst, Insn, Address, Decoder);2827}28282829static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Insn,2830uint64_t Address, const void *Decoder)2831{2832unsigned align, load;2833unsigned size = fieldFromInstruction_4(Insn, 6, 2);2834if (size == 3) return MCDisassembler_Fail;28352836align = fieldFromInstruction_4(Insn, 4, 2);2837if (align & 2) return MCDisassembler_Fail;28382839load = fieldFromInstruction_4(Insn, 21, 1);28402841return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)2842: DecodeVSTInstruction(Inst, Insn, Address, Decoder);2843}28442845static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Insn,2846uint64_t Address, const void *Decoder)2847{2848unsigned load;2849unsigned size = fieldFromInstruction_4(Insn, 6, 2);2850if (size == 3) return MCDisassembler_Fail;28512852load = fieldFromInstruction_4(Insn, 21, 1);28532854return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)2855: DecodeVSTInstruction(Inst, Insn, Address, Decoder);2856}28572858static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Insn,2859uint64_t Address, const void *Decoder)2860{2861DecodeStatus S = MCDisassembler_Success;2862unsigned wb, Rn, Rm;2863unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);2864Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;2865wb = fieldFromInstruction_4(Insn, 16, 4);2866Rn = fieldFromInstruction_4(Insn, 16, 4);2867Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;2868Rm = fieldFromInstruction_4(Insn, 0, 4);28692870// Writeback Operand2871switch (MCInst_getOpcode(Inst)) {2872case ARM_VST1d8wb_fixed:2873case ARM_VST1d16wb_fixed:2874case ARM_VST1d32wb_fixed:2875case ARM_VST1d64wb_fixed:2876case ARM_VST1d8wb_register:2877case ARM_VST1d16wb_register:2878case ARM_VST1d32wb_register:2879case ARM_VST1d64wb_register:2880case ARM_VST1q8wb_fixed:2881case ARM_VST1q16wb_fixed:2882case ARM_VST1q32wb_fixed:2883case ARM_VST1q64wb_fixed:2884case ARM_VST1q8wb_register:2885case ARM_VST1q16wb_register:2886case ARM_VST1q32wb_register:2887case ARM_VST1q64wb_register:2888case ARM_VST1d8Twb_fixed:2889case ARM_VST1d16Twb_fixed:2890case ARM_VST1d32Twb_fixed:2891case ARM_VST1d64Twb_fixed:2892case ARM_VST1d8Twb_register:2893case ARM_VST1d16Twb_register:2894case ARM_VST1d32Twb_register:2895case ARM_VST1d64Twb_register:2896case ARM_VST1d8Qwb_fixed:2897case ARM_VST1d16Qwb_fixed:2898case ARM_VST1d32Qwb_fixed:2899case ARM_VST1d64Qwb_fixed:2900case ARM_VST1d8Qwb_register:2901case ARM_VST1d16Qwb_register:2902case ARM_VST1d32Qwb_register:2903case ARM_VST1d64Qwb_register:2904case ARM_VST2d8wb_fixed:2905case ARM_VST2d16wb_fixed:2906case ARM_VST2d32wb_fixed:2907case ARM_VST2d8wb_register:2908case ARM_VST2d16wb_register:2909case ARM_VST2d32wb_register:2910case ARM_VST2q8wb_fixed:2911case ARM_VST2q16wb_fixed:2912case ARM_VST2q32wb_fixed:2913case ARM_VST2q8wb_register:2914case ARM_VST2q16wb_register:2915case ARM_VST2q32wb_register:2916case ARM_VST2b8wb_fixed:2917case ARM_VST2b16wb_fixed:2918case ARM_VST2b32wb_fixed:2919case ARM_VST2b8wb_register:2920case ARM_VST2b16wb_register:2921case ARM_VST2b32wb_register:2922if (Rm == 0xF)2923return MCDisassembler_Fail;2924MCOperand_CreateImm0(Inst, 0);2925break;2926case ARM_VST3d8_UPD:2927case ARM_VST3d16_UPD:2928case ARM_VST3d32_UPD:2929case ARM_VST3q8_UPD:2930case ARM_VST3q16_UPD:2931case ARM_VST3q32_UPD:2932case ARM_VST4d8_UPD:2933case ARM_VST4d16_UPD:2934case ARM_VST4d32_UPD:2935case ARM_VST4q8_UPD:2936case ARM_VST4q16_UPD:2937case ARM_VST4q32_UPD:2938if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))2939return MCDisassembler_Fail;2940break;2941default:2942break;2943}29442945// AddrMode6 Base (register+alignment)2946if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))2947return MCDisassembler_Fail;29482949// AddrMode6 Offset (register)2950switch (MCInst_getOpcode(Inst)) {2951default:2952if (Rm == 0xD)2953MCOperand_CreateReg0(Inst, 0);2954else if (Rm != 0xF) {2955if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))2956return MCDisassembler_Fail;2957}2958break;29592960case ARM_VST1d8wb_fixed:2961case ARM_VST1d16wb_fixed:2962case ARM_VST1d32wb_fixed:2963case ARM_VST1d64wb_fixed:2964case ARM_VST1q8wb_fixed:2965case ARM_VST1q16wb_fixed:2966case ARM_VST1q32wb_fixed:2967case ARM_VST1q64wb_fixed:2968case ARM_VST1d8Twb_fixed:2969case ARM_VST1d16Twb_fixed:2970case ARM_VST1d32Twb_fixed:2971case ARM_VST1d64Twb_fixed:2972case ARM_VST1d8Qwb_fixed:2973case ARM_VST1d16Qwb_fixed:2974case ARM_VST1d32Qwb_fixed:2975case ARM_VST1d64Qwb_fixed:2976case ARM_VST2d8wb_fixed:2977case ARM_VST2d16wb_fixed:2978case ARM_VST2d32wb_fixed:2979case ARM_VST2q8wb_fixed:2980case ARM_VST2q16wb_fixed:2981case ARM_VST2q32wb_fixed:2982case ARM_VST2b8wb_fixed:2983case ARM_VST2b16wb_fixed:2984case ARM_VST2b32wb_fixed:2985break;2986}298729882989// First input register2990switch (MCInst_getOpcode(Inst)) {2991case ARM_VST1q16:2992case ARM_VST1q32:2993case ARM_VST1q64:2994case ARM_VST1q8:2995case ARM_VST1q16wb_fixed:2996case ARM_VST1q16wb_register:2997case ARM_VST1q32wb_fixed:2998case ARM_VST1q32wb_register:2999case ARM_VST1q64wb_fixed:3000case ARM_VST1q64wb_register:3001case ARM_VST1q8wb_fixed:3002case ARM_VST1q8wb_register:3003case ARM_VST2d16:3004case ARM_VST2d32:3005case ARM_VST2d8:3006case ARM_VST2d16wb_fixed:3007case ARM_VST2d16wb_register:3008case ARM_VST2d32wb_fixed:3009case ARM_VST2d32wb_register:3010case ARM_VST2d8wb_fixed:3011case ARM_VST2d8wb_register:3012if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))3013return MCDisassembler_Fail;3014break;30153016case ARM_VST2b16:3017case ARM_VST2b32:3018case ARM_VST2b8:3019case ARM_VST2b16wb_fixed:3020case ARM_VST2b16wb_register:3021case ARM_VST2b32wb_fixed:3022case ARM_VST2b32wb_register:3023case ARM_VST2b8wb_fixed:3024case ARM_VST2b8wb_register:3025if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))3026return MCDisassembler_Fail;3027break;30283029default:3030if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3031return MCDisassembler_Fail;3032}30333034// Second input register3035switch (MCInst_getOpcode(Inst)) {3036case ARM_VST3d8:3037case ARM_VST3d16:3038case ARM_VST3d32:3039case ARM_VST3d8_UPD:3040case ARM_VST3d16_UPD:3041case ARM_VST3d32_UPD:3042case ARM_VST4d8:3043case ARM_VST4d16:3044case ARM_VST4d32:3045case ARM_VST4d8_UPD:3046case ARM_VST4d16_UPD:3047case ARM_VST4d32_UPD:3048if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 1) % 32, Address, Decoder)))3049return MCDisassembler_Fail;3050break;30513052case ARM_VST3q8:3053case ARM_VST3q16:3054case ARM_VST3q32:3055case ARM_VST3q8_UPD:3056case ARM_VST3q16_UPD:3057case ARM_VST3q32_UPD:3058case ARM_VST4q8:3059case ARM_VST4q16:3060case ARM_VST4q32:3061case ARM_VST4q8_UPD:3062case ARM_VST4q16_UPD:3063case ARM_VST4q32_UPD:3064if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))3065return MCDisassembler_Fail;3066break;3067default:3068break;3069}30703071// Third input register3072switch (MCInst_getOpcode(Inst)) {3073case ARM_VST3d8:3074case ARM_VST3d16:3075case ARM_VST3d32:3076case ARM_VST3d8_UPD:3077case ARM_VST3d16_UPD:3078case ARM_VST3d32_UPD:3079case ARM_VST4d8:3080case ARM_VST4d16:3081case ARM_VST4d32:3082case ARM_VST4d8_UPD:3083case ARM_VST4d16_UPD:3084case ARM_VST4d32_UPD:3085if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))3086return MCDisassembler_Fail;3087break;30883089case ARM_VST3q8:3090case ARM_VST3q16:3091case ARM_VST3q32:3092case ARM_VST3q8_UPD:3093case ARM_VST3q16_UPD:3094case ARM_VST3q32_UPD:3095case ARM_VST4q8:3096case ARM_VST4q16:3097case ARM_VST4q32:3098case ARM_VST4q8_UPD:3099case ARM_VST4q16_UPD:3100case ARM_VST4q32_UPD:3101if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 4) % 32, Address, Decoder)))3102return MCDisassembler_Fail;3103break;3104default:3105break;3106}31073108// Fourth input register3109switch (MCInst_getOpcode(Inst)) {3110case ARM_VST4d8:3111case ARM_VST4d16:3112case ARM_VST4d32:3113case ARM_VST4d8_UPD:3114case ARM_VST4d16_UPD:3115case ARM_VST4d32_UPD:3116if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 3) % 32, Address, Decoder)))3117return MCDisassembler_Fail;3118break;31193120case ARM_VST4q8:3121case ARM_VST4q16:3122case ARM_VST4q32:3123case ARM_VST4q8_UPD:3124case ARM_VST4q16_UPD:3125case ARM_VST4q32_UPD:3126if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 6) % 32, Address, Decoder)))3127return MCDisassembler_Fail;3128break;3129default:3130break;3131}31323133return S;3134}31353136static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Insn,3137uint64_t Address, const void *Decoder)3138{3139DecodeStatus S = MCDisassembler_Success;3140unsigned Rn, Rm, align, size;3141unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3142Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3143Rn = fieldFromInstruction_4(Insn, 16, 4);3144Rm = fieldFromInstruction_4(Insn, 0, 4);3145align = fieldFromInstruction_4(Insn, 4, 1);3146size = fieldFromInstruction_4(Insn, 6, 2);31473148if (size == 0 && align == 1)3149return MCDisassembler_Fail;31503151align *= (1 << size);31523153switch (MCInst_getOpcode(Inst)) {3154case ARM_VLD1DUPq16: case ARM_VLD1DUPq32: case ARM_VLD1DUPq8:3155case ARM_VLD1DUPq16wb_fixed: case ARM_VLD1DUPq16wb_register:3156case ARM_VLD1DUPq32wb_fixed: case ARM_VLD1DUPq32wb_register:3157case ARM_VLD1DUPq8wb_fixed: case ARM_VLD1DUPq8wb_register:3158if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))3159return MCDisassembler_Fail;3160break;31613162default:3163if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3164return MCDisassembler_Fail;3165break;3166}31673168if (Rm != 0xF) {3169if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3170return MCDisassembler_Fail;3171}31723173if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3174return MCDisassembler_Fail;31753176MCOperand_CreateImm0(Inst, align);31773178// The fixed offset post-increment encodes Rm == 0xd. The no-writeback3179// variant encodes Rm == 0xf. Anything else is a register offset post-3180// increment and we need to add the register operand to the instruction.3181if (Rm != 0xD && Rm != 0xF &&3182!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))3183return MCDisassembler_Fail;31843185return S;3186}31873188static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Insn,3189uint64_t Address, const void *Decoder)3190{3191DecodeStatus S = MCDisassembler_Success;3192unsigned Rn, Rm, align, size;3193unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3194Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3195Rn = fieldFromInstruction_4(Insn, 16, 4);3196Rm = fieldFromInstruction_4(Insn, 0, 4);3197align = fieldFromInstruction_4(Insn, 4, 1);3198size = 1 << fieldFromInstruction_4(Insn, 6, 2);3199align *= 2 * size;32003201switch (MCInst_getOpcode(Inst)) {3202case ARM_VLD2DUPd16: case ARM_VLD2DUPd32: case ARM_VLD2DUPd8:3203case ARM_VLD2DUPd16wb_fixed: case ARM_VLD2DUPd16wb_register:3204case ARM_VLD2DUPd32wb_fixed: case ARM_VLD2DUPd32wb_register:3205case ARM_VLD2DUPd8wb_fixed: case ARM_VLD2DUPd8wb_register:3206if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))3207return MCDisassembler_Fail;3208break;32093210case ARM_VLD2DUPd16x2: case ARM_VLD2DUPd32x2: case ARM_VLD2DUPd8x2:3211case ARM_VLD2DUPd16x2wb_fixed: case ARM_VLD2DUPd16x2wb_register:3212case ARM_VLD2DUPd32x2wb_fixed: case ARM_VLD2DUPd32x2wb_register:3213case ARM_VLD2DUPd8x2wb_fixed: case ARM_VLD2DUPd8x2wb_register:3214if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))3215return MCDisassembler_Fail;3216break;32173218default:3219if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3220return MCDisassembler_Fail;3221break;3222}32233224if (Rm != 0xF)3225MCOperand_CreateImm0(Inst, 0);32263227if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3228return MCDisassembler_Fail;32293230MCOperand_CreateImm0(Inst, align);32313232if (Rm != 0xD && Rm != 0xF) {3233if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))3234return MCDisassembler_Fail;3235}32363237return S;3238}32393240static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Insn,3241uint64_t Address, const void *Decoder)3242{3243DecodeStatus S = MCDisassembler_Success;3244unsigned Rn, Rm, inc;3245unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3246Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3247Rn = fieldFromInstruction_4(Insn, 16, 4);3248Rm = fieldFromInstruction_4(Insn, 0, 4);3249inc = fieldFromInstruction_4(Insn, 5, 1) + 1;32503251if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3252return MCDisassembler_Fail;32533254if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + inc) % 32, Address, Decoder)))3255return MCDisassembler_Fail;32563257if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2*inc) % 32, Address, Decoder)))3258return MCDisassembler_Fail;32593260if (Rm != 0xF) {3261if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3262return MCDisassembler_Fail;3263}32643265if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3266return MCDisassembler_Fail;32673268MCOperand_CreateImm0(Inst, 0);32693270if (Rm == 0xD)3271MCOperand_CreateReg0(Inst, 0);3272else if (Rm != 0xF) {3273if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))3274return MCDisassembler_Fail;3275}32763277return S;3278}32793280static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Insn,3281uint64_t Address, const void *Decoder)3282{3283DecodeStatus S = MCDisassembler_Success;3284unsigned Rn, Rm, size, inc, align;3285unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3286Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3287Rn = fieldFromInstruction_4(Insn, 16, 4);3288Rm = fieldFromInstruction_4(Insn, 0, 4);3289size = fieldFromInstruction_4(Insn, 6, 2);3290inc = fieldFromInstruction_4(Insn, 5, 1) + 1;3291align = fieldFromInstruction_4(Insn, 4, 1);32923293if (size == 0x3) {3294if (align == 0)3295return MCDisassembler_Fail;3296align = 16;3297} else {3298if (size == 2) {3299align *= 8;3300} else {3301size = 1 << size;3302align *= 4 * size;3303}3304}33053306if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3307return MCDisassembler_Fail;33083309if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + inc) % 32, Address, Decoder)))3310return MCDisassembler_Fail;33113312if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2*inc) % 32, Address, Decoder)))3313return MCDisassembler_Fail;33143315if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 3*inc) % 32, Address, Decoder)))3316return MCDisassembler_Fail;33173318if (Rm != 0xF) {3319if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3320return MCDisassembler_Fail;3321}33223323if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3324return MCDisassembler_Fail;33253326MCOperand_CreateImm0(Inst, align);33273328if (Rm == 0xD)3329MCOperand_CreateReg0(Inst, 0);3330else if (Rm != 0xF) {3331if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))3332return MCDisassembler_Fail;3333}33343335return S;3336}33373338static DecodeStatus DecodeNEONModImmInstruction(MCInst *Inst, unsigned Insn,3339uint64_t Address, const void *Decoder)3340{3341DecodeStatus S = MCDisassembler_Success;3342unsigned imm, Q;3343unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3344Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3345imm = fieldFromInstruction_4(Insn, 0, 4);3346imm |= fieldFromInstruction_4(Insn, 16, 3) << 4;3347imm |= fieldFromInstruction_4(Insn, 24, 1) << 7;3348imm |= fieldFromInstruction_4(Insn, 8, 4) << 8;3349imm |= fieldFromInstruction_4(Insn, 5, 1) << 12;3350Q = fieldFromInstruction_4(Insn, 6, 1);33513352if (Q) {3353if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))3354return MCDisassembler_Fail;3355} else {3356if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3357return MCDisassembler_Fail;3358}33593360MCOperand_CreateImm0(Inst, imm);33613362switch (MCInst_getOpcode(Inst)) {3363case ARM_VORRiv4i16:3364case ARM_VORRiv2i32:3365case ARM_VBICiv4i16:3366case ARM_VBICiv2i32:3367if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3368return MCDisassembler_Fail;3369break;3370case ARM_VORRiv8i16:3371case ARM_VORRiv4i32:3372case ARM_VBICiv8i16:3373case ARM_VBICiv4i32:3374if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))3375return MCDisassembler_Fail;3376break;3377default:3378break;3379}33803381return S;3382}33833384static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Insn,3385uint64_t Address, const void *Decoder)3386{3387DecodeStatus S = MCDisassembler_Success;3388unsigned Rm, size;3389unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3390Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3391Rm = fieldFromInstruction_4(Insn, 0, 4);3392Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;3393size = fieldFromInstruction_4(Insn, 18, 2);33943395if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))3396return MCDisassembler_Fail;33973398if (!Check(&S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))3399return MCDisassembler_Fail;34003401MCOperand_CreateImm0(Inst, 8 << size);34023403return S;3404}34053406static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,3407uint64_t Address, const void *Decoder)3408{3409MCOperand_CreateImm0(Inst, 8 - Val);34103411return MCDisassembler_Success;3412}34133414static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,3415uint64_t Address, const void *Decoder)3416{3417MCOperand_CreateImm0(Inst, 16 - Val);34183419return MCDisassembler_Success;3420}34213422static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,3423uint64_t Address, const void *Decoder)3424{3425MCOperand_CreateImm0(Inst, 32 - Val);34263427return MCDisassembler_Success;3428}34293430static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,3431uint64_t Address, const void *Decoder)3432{3433MCOperand_CreateImm0(Inst, 64 - Val);34343435return MCDisassembler_Success;3436}34373438static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,3439uint64_t Address, const void *Decoder)3440{3441DecodeStatus S = MCDisassembler_Success;3442unsigned Rn, Rm, op;3443unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);3444Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;3445Rn = fieldFromInstruction_4(Insn, 16, 4);3446Rn |= fieldFromInstruction_4(Insn, 7, 1) << 4;3447Rm = fieldFromInstruction_4(Insn, 0, 4);3448Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;3449op = fieldFromInstruction_4(Insn, 6, 1);34503451if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3452return MCDisassembler_Fail;34533454if (op) {3455if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))3456return MCDisassembler_Fail; // Writeback3457}34583459switch (MCInst_getOpcode(Inst)) {3460case ARM_VTBL2:3461case ARM_VTBX2:3462if (!Check(&S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))3463return MCDisassembler_Fail;3464break;3465default:3466if (!Check(&S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))3467return MCDisassembler_Fail;3468}34693470if (!Check(&S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))3471return MCDisassembler_Fail;34723473return S;3474}34753476static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,3477uint64_t Address, const void *Decoder)3478{3479DecodeStatus S = MCDisassembler_Success;3480unsigned dst = fieldFromInstruction_2(Insn, 8, 3);3481unsigned imm = fieldFromInstruction_2(Insn, 0, 8);34823483if (!Check(&S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))3484return MCDisassembler_Fail;34853486switch(MCInst_getOpcode(Inst)) {3487default:3488return MCDisassembler_Fail;3489case ARM_tADR:3490break; // tADR does not explicitly represent the PC as an operand.3491case ARM_tADDrSPi:3492MCOperand_CreateReg0(Inst, ARM_SP);3493break;3494}34953496MCOperand_CreateImm0(Inst, imm);34973498return S;3499}35003501static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,3502uint64_t Address, const void *Decoder)3503{3504MCOperand_CreateImm0(Inst, SignExtend32(Val << 1, 12));35053506return MCDisassembler_Success;3507}35083509static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,3510uint64_t Address, const void *Decoder)3511{3512MCOperand_CreateImm0(Inst, SignExtend32(Val, 21));35133514return MCDisassembler_Success;3515}35163517static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,3518uint64_t Address, const void *Decoder)3519{3520MCOperand_CreateImm0(Inst, Val << 1);35213522return MCDisassembler_Success;3523}35243525static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,3526uint64_t Address, const void *Decoder)3527{3528DecodeStatus S = MCDisassembler_Success;3529unsigned Rn = fieldFromInstruction_4(Val, 0, 3);3530unsigned Rm = fieldFromInstruction_4(Val, 3, 3);35313532if (!Check(&S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))3533return MCDisassembler_Fail;35343535if (!Check(&S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))3536return MCDisassembler_Fail;35373538return S;3539}35403541static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,3542uint64_t Address, const void *Decoder)3543{3544DecodeStatus S = MCDisassembler_Success;3545unsigned Rn = fieldFromInstruction_4(Val, 0, 3);3546unsigned imm = fieldFromInstruction_4(Val, 3, 5);35473548if (!Check(&S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))3549return MCDisassembler_Fail;35503551MCOperand_CreateImm0(Inst, imm);35523553return S;3554}35553556static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,3557uint64_t Address, const void *Decoder)3558{3559unsigned imm = Val << 2;35603561MCOperand_CreateImm0(Inst, imm);3562//tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);35633564return MCDisassembler_Success;3565}35663567static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,3568uint64_t Address, const void *Decoder)3569{3570MCOperand_CreateReg0(Inst, ARM_SP);3571MCOperand_CreateImm0(Inst, Val);35723573return MCDisassembler_Success;3574}35753576static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,3577uint64_t Address, const void *Decoder)3578{3579DecodeStatus S = MCDisassembler_Success;3580unsigned Rn = fieldFromInstruction_4(Val, 6, 4);3581unsigned Rm = fieldFromInstruction_4(Val, 2, 4);3582unsigned imm = fieldFromInstruction_4(Val, 0, 2);35833584// Thumb stores cannot use PC as dest register.3585switch (MCInst_getOpcode(Inst)) {3586case ARM_t2STRHs:3587case ARM_t2STRBs:3588case ARM_t2STRs:3589if (Rn == 15)3590return MCDisassembler_Fail;3591default:3592break;3593}35943595if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3596return MCDisassembler_Fail;35973598if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))3599return MCDisassembler_Fail;36003601MCOperand_CreateImm0(Inst, imm);36023603return S;3604}36053606static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Insn,3607uint64_t Address, const void *Decoder)3608{3609DecodeStatus S = MCDisassembler_Success;3610unsigned addrmode;3611unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);3612unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);3613bool hasMP = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMP);3614bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);36153616if (Rn == 15) {3617switch (MCInst_getOpcode(Inst)) {3618case ARM_t2LDRBs:3619MCInst_setOpcode(Inst, ARM_t2LDRBpci);3620break;3621case ARM_t2LDRHs:3622MCInst_setOpcode(Inst, ARM_t2LDRHpci);3623break;3624case ARM_t2LDRSHs:3625MCInst_setOpcode(Inst, ARM_t2LDRSHpci);3626break;3627case ARM_t2LDRSBs:3628MCInst_setOpcode(Inst, ARM_t2LDRSBpci);3629break;3630case ARM_t2LDRs:3631MCInst_setOpcode(Inst, ARM_t2LDRpci);3632break;3633case ARM_t2PLDs:3634MCInst_setOpcode(Inst, ARM_t2PLDpci);3635break;3636case ARM_t2PLIs:3637MCInst_setOpcode(Inst, ARM_t2PLIpci);3638break;3639default:3640return MCDisassembler_Fail;3641}36423643return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);3644}36453646if (Rt == 15) {3647switch (MCInst_getOpcode(Inst)) {3648case ARM_t2LDRSHs:3649return MCDisassembler_Fail;3650case ARM_t2LDRHs:3651MCInst_setOpcode(Inst, ARM_t2PLDWs);3652break;3653case ARM_t2LDRSBs:3654MCInst_setOpcode(Inst, ARM_t2PLIs);3655default:3656break;3657}3658}36593660switch (MCInst_getOpcode(Inst)) {3661case ARM_t2PLDs:3662break;3663case ARM_t2PLIs:3664if (!hasV7Ops)3665return MCDisassembler_Fail;3666break;3667case ARM_t2PLDWs:3668if (!hasV7Ops || !hasMP)3669return MCDisassembler_Fail;3670break;3671default:3672if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))3673return MCDisassembler_Fail;3674}36753676addrmode = fieldFromInstruction_4(Insn, 4, 2);3677addrmode |= fieldFromInstruction_4(Insn, 0, 4) << 2;3678addrmode |= fieldFromInstruction_4(Insn, 16, 4) << 6;36793680if (!Check(&S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))3681return MCDisassembler_Fail;36823683return S;3684}36853686static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,3687uint64_t Address, const void* Decoder)3688{3689DecodeStatus S = MCDisassembler_Success;3690unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);3691unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);3692unsigned U = fieldFromInstruction_4(Insn, 9, 1);3693unsigned imm = fieldFromInstruction_4(Insn, 0, 8);3694unsigned add = fieldFromInstruction_4(Insn, 9, 1);3695bool hasMP = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMP);3696bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);36973698imm |= (U << 8);3699imm |= (Rn << 9);37003701if (Rn == 15) {3702switch (MCInst_getOpcode(Inst)) {3703case ARM_t2LDRi8:3704MCInst_setOpcode(Inst, ARM_t2LDRpci);3705break;3706case ARM_t2LDRBi8:3707MCInst_setOpcode(Inst, ARM_t2LDRBpci);3708break;3709case ARM_t2LDRSBi8:3710MCInst_setOpcode(Inst, ARM_t2LDRSBpci);3711break;3712case ARM_t2LDRHi8:3713MCInst_setOpcode(Inst, ARM_t2LDRHpci);3714break;3715case ARM_t2LDRSHi8:3716MCInst_setOpcode(Inst, ARM_t2LDRSHpci);3717break;3718case ARM_t2PLDi8:3719MCInst_setOpcode(Inst, ARM_t2PLDpci);3720break;3721case ARM_t2PLIi8:3722MCInst_setOpcode(Inst, ARM_t2PLIpci);3723break;3724default:3725return MCDisassembler_Fail;3726}37273728return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);3729}37303731if (Rt == 15) {3732switch (MCInst_getOpcode(Inst)) {3733case ARM_t2LDRSHi8:3734return MCDisassembler_Fail;3735case ARM_t2LDRHi8:3736if (!add)3737MCInst_setOpcode(Inst, ARM_t2PLDWi8);3738break;3739case ARM_t2LDRSBi8:3740MCInst_setOpcode(Inst, ARM_t2PLIi8);3741break;3742default:3743break;3744}3745}37463747switch (MCInst_getOpcode(Inst)) {3748case ARM_t2PLDi8:3749break;3750case ARM_t2PLIi8:3751if (!hasV7Ops)3752return MCDisassembler_Fail;3753break;3754case ARM_t2PLDWi8:3755if (!hasV7Ops || !hasMP)3756return MCDisassembler_Fail;3757break;3758default:3759if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))3760return MCDisassembler_Fail;3761}37623763if (!Check(&S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))3764return MCDisassembler_Fail;37653766return S;3767}37683769static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,3770uint64_t Address, const void* Decoder)3771{3772DecodeStatus S = MCDisassembler_Success;3773unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);3774unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);3775unsigned imm = fieldFromInstruction_4(Insn, 0, 12);3776bool hasMP = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMP);3777bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);37783779imm |= (Rn << 13);37803781if (Rn == 15) {3782switch (MCInst_getOpcode(Inst)) {3783case ARM_t2LDRi12:3784MCInst_setOpcode(Inst, ARM_t2LDRpci);3785break;3786case ARM_t2LDRHi12:3787MCInst_setOpcode(Inst, ARM_t2LDRHpci);3788break;3789case ARM_t2LDRSHi12:3790MCInst_setOpcode(Inst, ARM_t2LDRSHpci);3791break;3792case ARM_t2LDRBi12:3793MCInst_setOpcode(Inst, ARM_t2LDRBpci);3794break;3795case ARM_t2LDRSBi12:3796MCInst_setOpcode(Inst, ARM_t2LDRSBpci);3797break;3798case ARM_t2PLDi12:3799MCInst_setOpcode(Inst, ARM_t2PLDpci);3800break;3801case ARM_t2PLIi12:3802MCInst_setOpcode(Inst, ARM_t2PLIpci);3803break;3804default:3805return MCDisassembler_Fail;3806}3807return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);3808}38093810if (Rt == 15) {3811switch (MCInst_getOpcode(Inst)) {3812case ARM_t2LDRSHi12:3813return MCDisassembler_Fail;3814case ARM_t2LDRHi12:3815MCInst_setOpcode(Inst, ARM_t2PLDWi12);3816break;3817case ARM_t2LDRSBi12:3818MCInst_setOpcode(Inst, ARM_t2PLIi12);3819break;3820default:3821break;3822}3823}38243825switch (MCInst_getOpcode(Inst)) {3826case ARM_t2PLDi12:3827break;3828case ARM_t2PLIi12:3829if (!hasV7Ops)3830return MCDisassembler_Fail;3831break;3832case ARM_t2PLDWi12:3833if (!hasV7Ops || !hasMP)3834return MCDisassembler_Fail;3835break;3836default:3837if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))3838return MCDisassembler_Fail;3839}38403841if (!Check(&S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))3842return MCDisassembler_Fail;38433844return S;3845}38463847static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,3848uint64_t Address, const void* Decoder)3849{3850DecodeStatus S = MCDisassembler_Success;38513852unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);3853unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);3854unsigned imm = fieldFromInstruction_4(Insn, 0, 8);3855imm |= (Rn << 9);38563857if (Rn == 15) {3858switch (MCInst_getOpcode(Inst)) {3859case ARM_t2LDRT:3860MCInst_setOpcode(Inst, ARM_t2LDRpci);3861break;3862case ARM_t2LDRBT:3863MCInst_setOpcode(Inst, ARM_t2LDRBpci);3864break;3865case ARM_t2LDRHT:3866MCInst_setOpcode(Inst, ARM_t2LDRHpci);3867break;3868case ARM_t2LDRSBT:3869MCInst_setOpcode(Inst, ARM_t2LDRSBpci);3870break;3871case ARM_t2LDRSHT:3872MCInst_setOpcode(Inst, ARM_t2LDRSHpci);3873break;3874default:3875return MCDisassembler_Fail;3876}38773878return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);3879}38803881if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))3882return MCDisassembler_Fail;38833884if (!Check(&S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))3885return MCDisassembler_Fail;38863887return S;3888}38893890static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,3891uint64_t Address, const void* Decoder)3892{3893DecodeStatus S = MCDisassembler_Success;3894unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);3895unsigned U = fieldFromInstruction_4(Insn, 23, 1);3896int imm = fieldFromInstruction_4(Insn, 0, 12);3897bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);38983899if (Rt == 15) {3900switch (MCInst_getOpcode(Inst)) {3901case ARM_t2LDRBpci:3902case ARM_t2LDRHpci:3903MCInst_setOpcode(Inst, ARM_t2PLDpci);3904break;3905case ARM_t2LDRSBpci:3906MCInst_setOpcode(Inst, ARM_t2PLIpci);3907break;3908case ARM_t2LDRSHpci:3909return MCDisassembler_Fail;3910default:3911break;3912}3913}39143915switch(MCInst_getOpcode(Inst)) {3916case ARM_t2PLDpci:3917break;3918case ARM_t2PLIpci:3919if (!hasV7Ops)3920return MCDisassembler_Fail;3921break;3922default:3923if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))3924return MCDisassembler_Fail;3925}39263927if (!U) {3928// Special case for #-0.3929if (imm == 0)3930imm = INT32_MIN;3931else3932imm = -imm;3933}39343935MCOperand_CreateImm0(Inst, imm);39363937return S;3938}39393940static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,3941uint64_t Address, const void *Decoder)3942{3943if (Val == 0)3944MCOperand_CreateImm0(Inst, INT32_MIN);3945else {3946int imm = Val & 0xFF;39473948if (!(Val & 0x100)) imm *= -1;39493950MCOperand_CreateImm0(Inst, imm * 4);3951}39523953return MCDisassembler_Success;3954}39553956static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,3957uint64_t Address, const void *Decoder)3958{3959DecodeStatus S = MCDisassembler_Success;3960unsigned Rn = fieldFromInstruction_4(Val, 9, 4);3961unsigned imm = fieldFromInstruction_4(Val, 0, 9);39623963if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))3964return MCDisassembler_Fail;39653966if (!Check(&S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))3967return MCDisassembler_Fail;39683969return S;3970}39713972static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,3973uint64_t Address, const void *Decoder)3974{3975DecodeStatus S = MCDisassembler_Success;3976unsigned Rn = fieldFromInstruction_4(Val, 8, 4);3977unsigned imm = fieldFromInstruction_4(Val, 0, 8);39783979if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))3980return MCDisassembler_Fail;39813982MCOperand_CreateImm0(Inst, imm);39833984return S;3985}39863987static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,3988uint64_t Address, const void *Decoder)3989{3990int imm = Val & 0xFF;39913992if (Val == 0)3993imm = INT32_MIN;3994else if (!(Val & 0x100))3995imm *= -1;39963997MCOperand_CreateImm0(Inst, imm);39983999return MCDisassembler_Success;4000}40014002static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,4003uint64_t Address, const void *Decoder)4004{4005DecodeStatus S = MCDisassembler_Success;40064007unsigned Rn = fieldFromInstruction_4(Val, 9, 4);4008unsigned imm = fieldFromInstruction_4(Val, 0, 9);40094010// Thumb stores cannot use PC as dest register.4011switch (MCInst_getOpcode(Inst)) {4012case ARM_t2STRT:4013case ARM_t2STRBT:4014case ARM_t2STRHT:4015case ARM_t2STRi8:4016case ARM_t2STRHi8:4017case ARM_t2STRBi8:4018if (Rn == 15)4019return MCDisassembler_Fail;4020break;4021default:4022break;4023}40244025// Some instructions always use an additive offset.4026switch (MCInst_getOpcode(Inst)) {4027case ARM_t2LDRT:4028case ARM_t2LDRBT:4029case ARM_t2LDRHT:4030case ARM_t2LDRSBT:4031case ARM_t2LDRSHT:4032case ARM_t2STRT:4033case ARM_t2STRBT:4034case ARM_t2STRHT:4035imm |= 0x100;4036break;4037default:4038break;4039}40404041if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4042return MCDisassembler_Fail;40434044if (!Check(&S, DecodeT2Imm8(Inst, imm, Address, Decoder)))4045return MCDisassembler_Fail;40464047return S;4048}40494050static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Insn,4051uint64_t Address, const void *Decoder)4052{4053DecodeStatus S = MCDisassembler_Success;4054unsigned load;4055unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);4056unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4057unsigned addr = fieldFromInstruction_4(Insn, 0, 8);4058addr |= fieldFromInstruction_4(Insn, 9, 1) << 8;4059addr |= Rn << 9;4060load = fieldFromInstruction_4(Insn, 20, 1);40614062if (Rn == 15) {4063switch (MCInst_getOpcode(Inst)) {4064case ARM_t2LDR_PRE:4065case ARM_t2LDR_POST:4066MCInst_setOpcode(Inst, ARM_t2LDRpci);4067break;4068case ARM_t2LDRB_PRE:4069case ARM_t2LDRB_POST:4070MCInst_setOpcode(Inst, ARM_t2LDRBpci);4071break;4072case ARM_t2LDRH_PRE:4073case ARM_t2LDRH_POST:4074MCInst_setOpcode(Inst, ARM_t2LDRHpci);4075break;4076case ARM_t2LDRSB_PRE:4077case ARM_t2LDRSB_POST:4078if (Rt == 15)4079MCInst_setOpcode(Inst, ARM_t2PLIpci);4080else4081MCInst_setOpcode(Inst, ARM_t2LDRSBpci);4082break;4083case ARM_t2LDRSH_PRE:4084case ARM_t2LDRSH_POST:4085MCInst_setOpcode(Inst, ARM_t2LDRSHpci);4086break;4087default:4088return MCDisassembler_Fail;4089}40904091return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);4092}40934094if (!load) {4095if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4096return MCDisassembler_Fail;4097}40984099if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))4100return MCDisassembler_Fail;41014102if (load) {4103if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4104return MCDisassembler_Fail;4105}41064107if (!Check(&S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))4108return MCDisassembler_Fail;41094110return S;4111}41124113static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,4114uint64_t Address, const void *Decoder)4115{4116DecodeStatus S = MCDisassembler_Success;4117unsigned Rn = fieldFromInstruction_4(Val, 13, 4);4118unsigned imm = fieldFromInstruction_4(Val, 0, 12);41194120// Thumb stores cannot use PC as dest register.4121switch (MCInst_getOpcode(Inst)) {4122case ARM_t2STRi12:4123case ARM_t2STRBi12:4124case ARM_t2STRHi12:4125if (Rn == 15)4126return MCDisassembler_Fail;4127default:4128break;4129}41304131if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4132return MCDisassembler_Fail;41334134MCOperand_CreateImm0(Inst, imm);41354136return S;4137}41384139static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Insn,4140uint64_t Address, const void *Decoder)4141{4142unsigned imm = fieldFromInstruction_2(Insn, 0, 7);41434144MCOperand_CreateReg0(Inst, ARM_SP);4145MCOperand_CreateReg0(Inst, ARM_SP);4146MCOperand_CreateImm0(Inst, imm);41474148return MCDisassembler_Success;4149}41504151static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,4152uint64_t Address, const void *Decoder)4153{4154DecodeStatus S = MCDisassembler_Success;41554156if (MCInst_getOpcode(Inst) == ARM_tADDrSP) {4157unsigned Rdm = fieldFromInstruction_2(Insn, 0, 3);4158Rdm |= fieldFromInstruction_2(Insn, 7, 1) << 3;41594160if (!Check(&S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))4161return MCDisassembler_Fail;41624163MCOperand_CreateReg0(Inst, ARM_SP);41644165if (!Check(&S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))4166return MCDisassembler_Fail;4167} else if (MCInst_getOpcode(Inst) == ARM_tADDspr) {4168unsigned Rm = fieldFromInstruction_2(Insn, 3, 4);41694170MCOperand_CreateReg0(Inst, ARM_SP);4171MCOperand_CreateReg0(Inst, ARM_SP);41724173if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))4174return MCDisassembler_Fail;4175}41764177return S;4178}41794180static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,4181uint64_t Address, const void *Decoder)4182{4183unsigned imod = fieldFromInstruction_2(Insn, 4, 1) | 0x2;4184unsigned flags = fieldFromInstruction_2(Insn, 0, 3);41854186MCOperand_CreateImm0(Inst, imod);4187MCOperand_CreateImm0(Inst, flags);41884189return MCDisassembler_Success;4190}41914192static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,4193uint64_t Address, const void *Decoder)4194{4195DecodeStatus S = MCDisassembler_Success;4196unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);4197unsigned add = fieldFromInstruction_4(Insn, 4, 1);41984199if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))4200return MCDisassembler_Fail;42014202MCOperand_CreateImm0(Inst, add);42034204return S;4205}42064207static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Val,4208uint64_t Address, const void *Decoder)4209{4210// Val is passed in as S:J1:J2:imm10H:imm10L:'0'4211// Note only one trailing zero not two. Also the J1 and J2 values are from4212// the encoded instruction. So here change to I1 and I2 values via:4213// I1 = NOT(J1 EOR S);4214// I2 = NOT(J2 EOR S);4215// and build the imm32 with two trailing zeros as documented:4216// imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);4217unsigned S = (Val >> 23) & 1;4218unsigned J1 = (Val >> 22) & 1;4219unsigned J2 = (Val >> 21) & 1;4220unsigned I1 = !(J1 ^ S);4221unsigned I2 = !(J2 ^ S);4222unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);4223int imm32 = SignExtend32(tmp << 1, 25);42244225MCOperand_CreateImm0(Inst, imm32);42264227return MCDisassembler_Success;4228}42294230static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Val,4231uint64_t Address, const void *Decoder)4232{4233if (Val == 0xA || Val == 0xB)4234return MCDisassembler_Fail;42354236if (ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops) && !(Val == 14 || Val == 15))4237return MCDisassembler_Fail;42384239MCOperand_CreateImm0(Inst, Val);42404241return MCDisassembler_Success;4242}42434244static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Insn,4245uint64_t Address, const void *Decoder)4246{4247DecodeStatus S = MCDisassembler_Success;4248unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4249unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);42504251if (Rn == ARM_SP) S = MCDisassembler_SoftFail;42524253if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4254return MCDisassembler_Fail;42554256if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))4257return MCDisassembler_Fail;42584259return S;4260}42614262static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Insn,4263uint64_t Address, const void *Decoder)4264{4265DecodeStatus S = MCDisassembler_Success;4266unsigned brtarget;4267unsigned pred = fieldFromInstruction_4(Insn, 22, 4);42684269if (pred == 0xE || pred == 0xF) {4270unsigned imm;4271unsigned opc = fieldFromInstruction_4(Insn, 4, 28);4272switch (opc) {4273default:4274return MCDisassembler_Fail;4275case 0xf3bf8f4:4276MCInst_setOpcode(Inst, ARM_t2DSB);4277break;4278case 0xf3bf8f5:4279MCInst_setOpcode(Inst, ARM_t2DMB);4280break;4281case 0xf3bf8f6:4282MCInst_setOpcode(Inst, ARM_t2ISB);4283break;4284}42854286imm = fieldFromInstruction_4(Insn, 0, 4);4287return DecodeMemBarrierOption(Inst, imm, Address, Decoder);4288}42894290brtarget = fieldFromInstruction_4(Insn, 0, 11) << 1;4291brtarget |= fieldFromInstruction_4(Insn, 11, 1) << 19;4292brtarget |= fieldFromInstruction_4(Insn, 13, 1) << 18;4293brtarget |= fieldFromInstruction_4(Insn, 16, 6) << 12;4294brtarget |= fieldFromInstruction_4(Insn, 26, 1) << 20;42954296if (!Check(&S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))4297return MCDisassembler_Fail;42984299if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4300return MCDisassembler_Fail;43014302return S;4303}43044305// Decode a shifted immediate operand. These basically consist4306// of an 8-bit value, and a 4-bit directive that specifies either4307// a splat operation or a rotation.4308static DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,4309uint64_t Address, const void *Decoder)4310{4311unsigned ctrl = fieldFromInstruction_4(Val, 10, 2);43124313if (ctrl == 0) {4314unsigned byte = fieldFromInstruction_4(Val, 8, 2);4315unsigned imm = fieldFromInstruction_4(Val, 0, 8);43164317switch (byte) {4318case 0:4319MCOperand_CreateImm0(Inst, imm);4320break;4321case 1:4322MCOperand_CreateImm0(Inst, (imm << 16) | imm);4323break;4324case 2:4325MCOperand_CreateImm0(Inst, (imm << 24) | (imm << 8));4326break;4327case 3:4328MCOperand_CreateImm0(Inst, (imm << 24) | (imm << 16) | (imm << 8) | imm);4329break;4330}4331} else {4332unsigned unrot = fieldFromInstruction_4(Val, 0, 7) | 0x80;4333unsigned rot = fieldFromInstruction_4(Val, 7, 5);4334unsigned imm = (unrot >> rot) | (unrot << ((32 - rot) & 31));43354336MCOperand_CreateImm0(Inst, imm);4337}43384339return MCDisassembler_Success;4340}43414342static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst, unsigned Val,4343uint64_t Address, const void *Decoder)4344{4345MCOperand_CreateImm0(Inst, SignExtend32(Val << 1, 9));43464347return MCDisassembler_Success;4348}43494350static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,4351uint64_t Address, const void *Decoder)4352{4353// Val is passed in as S:J1:J2:imm10:imm114354// Note no trailing zero after imm11. Also the J1 and J2 values are from4355// the encoded instruction. So here change to I1 and I2 values via:4356// I1 = NOT(J1 EOR S);4357// I2 = NOT(J2 EOR S);4358// and build the imm32 with one trailing zero as documented:4359// imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);4360unsigned S = (Val >> 23) & 1;4361unsigned J1 = (Val >> 22) & 1;4362unsigned J2 = (Val >> 21) & 1;4363unsigned I1 = !(J1 ^ S);4364unsigned I2 = !(J2 ^ S);4365unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);4366int imm32 = SignExtend32(tmp << 1, 25);43674368MCOperand_CreateImm0(Inst, imm32);43694370return MCDisassembler_Success;4371}43724373static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Val,4374uint64_t Address, const void *Decoder)4375{4376if (Val & ~0xf)4377return MCDisassembler_Fail;43784379MCOperand_CreateImm0(Inst, Val);43804381return MCDisassembler_Success;4382}43834384static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Val,4385uint64_t Address, const void *Decoder)4386{4387if (Val & ~0xf)4388return MCDisassembler_Fail;43894390MCOperand_CreateImm0(Inst, Val);43914392return MCDisassembler_Success;4393}43944395static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Val,4396uint64_t Address, const void *Decoder)4397{4398DecodeStatus S = MCDisassembler_Success;43994400if (ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMClass)) {4401unsigned ValLow = Val & 0xff;44024403// Validate the SYSm value first.4404switch (ValLow) {4405case 0: // apsr4406case 1: // iapsr4407case 2: // eapsr4408case 3: // xpsr4409case 5: // ipsr4410case 6: // epsr4411case 7: // iepsr4412case 8: // msp4413case 9: // psp4414case 16: // primask4415case 20: // control4416break;4417case 17: // basepri4418case 18: // basepri_max4419case 19: // faultmask4420if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops))4421// Values basepri, basepri_max and faultmask are only valid for v7m.4422return MCDisassembler_Fail;4423break;4424case 0x8a: // msplim_ns4425case 0x8b: // psplim_ns4426case 0x91: // basepri_ns4427case 0x93: // faultmask_ns4428if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8MMainlineOps))4429return MCDisassembler_Fail;4430// LLVM_FALLTHROUGH;4431case 10: // msplim4432case 11: // psplim4433case 0x88: // msp_ns4434case 0x89: // psp_ns4435case 0x90: // primask_ns4436case 0x94: // control_ns4437case 0x98: // sp_ns4438if (!ARM_getFeatureBits(Inst->csh->mode, ARM_Feature8MSecExt))4439return MCDisassembler_Fail;4440break;4441default:4442return MCDisassembler_SoftFail;4443}44444445if (MCInst_getOpcode(Inst) == ARM_t2MSR_M) {4446unsigned Mask = fieldFromInstruction_4(Val, 10, 2);4447if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops)) {4448// The ARMv6-M MSR bits {11-10} can be only 0b10, other values are4449// unpredictable.4450if (Mask != 2)4451S = MCDisassembler_SoftFail;4452} else {4453// The ARMv7-M architecture stores an additional 2-bit mask value in4454// MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and4455// xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if4456// the NZCVQ bits should be moved by the instruction. Bit mask{0}4457// indicates the move for the GE{3:0} bits, the mask{0} bit can be set4458// only if the processor includes the DSP extension.4459if (Mask == 0 || (Mask != 2 && ValLow > 3) ||4460(!ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureDSP) && (Mask & 1)))4461S = MCDisassembler_SoftFail;4462}4463}4464} else {4465// A/R class4466if (Val == 0)4467return MCDisassembler_Fail;4468}44694470MCOperand_CreateImm0(Inst, Val);4471return S;4472}44734474static DecodeStatus DecodeBankedReg(MCInst *Inst, unsigned Val,4475uint64_t Address, const void *Decoder)4476{4477unsigned R = fieldFromInstruction_4(Val, 5, 1);4478unsigned SysM = fieldFromInstruction_4(Val, 0, 5);44794480// The table of encodings for these banked registers comes from B9.2.3 of the4481// ARM ARM. There are patterns, but nothing regular enough to make this logic4482// neater. So by fiat, these values are UNPREDICTABLE:4483if (!lookupBankedRegByEncoding((R << 5) | SysM))4484return MCDisassembler_Fail;44854486MCOperand_CreateImm0(Inst, Val);44874488return MCDisassembler_Success;4489}44904491static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,4492uint64_t Address, const void *Decoder)4493{4494DecodeStatus S = MCDisassembler_Success;4495unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);4496unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4497unsigned pred = fieldFromInstruction_4(Insn, 28, 4);44984499if (Rn == 0xF)4500S = MCDisassembler_SoftFail;45014502if (!Check(&S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))4503return MCDisassembler_Fail;45044505if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4506return MCDisassembler_Fail;45074508if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4509return MCDisassembler_Fail;45104511return S;4512}45134514static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,4515uint64_t Address, const void *Decoder)4516{4517DecodeStatus S = MCDisassembler_Success;4518unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);4519unsigned Rt = fieldFromInstruction_4(Insn, 0, 4);4520unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4521unsigned pred = fieldFromInstruction_4(Insn, 28, 4);45224523if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))4524return MCDisassembler_Fail;45254526if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt + 1)4527S = MCDisassembler_SoftFail;45284529if (!Check(&S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))4530return MCDisassembler_Fail;45314532if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4533return MCDisassembler_Fail;45344535if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4536return MCDisassembler_Fail;45374538return S;4539}45404541static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,4542uint64_t Address, const void *Decoder)4543{4544DecodeStatus S = MCDisassembler_Success;4545unsigned pred;4546unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4547unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);4548unsigned imm = fieldFromInstruction_4(Insn, 0, 12);4549imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;4550imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;4551pred = fieldFromInstruction_4(Insn, 28, 4);45524553if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;45544555if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))4556return MCDisassembler_Fail;45574558if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4559return MCDisassembler_Fail;45604561if (!Check(&S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))4562return MCDisassembler_Fail;45634564if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4565return MCDisassembler_Fail;45664567return S;4568}45694570static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,4571uint64_t Address, const void *Decoder)4572{4573DecodeStatus S = MCDisassembler_Success;4574unsigned pred, Rm;4575unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4576unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);4577unsigned imm = fieldFromInstruction_4(Insn, 0, 12);4578imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;4579imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;4580pred = fieldFromInstruction_4(Insn, 28, 4);4581Rm = fieldFromInstruction_4(Insn, 0, 4);45824583if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;4584if (Rm == 0xF) S = MCDisassembler_SoftFail;45854586if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))4587return MCDisassembler_Fail;45884589if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4590return MCDisassembler_Fail;45914592if (!Check(&S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))4593return MCDisassembler_Fail;45944595if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4596return MCDisassembler_Fail;45974598return S;4599}46004601static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,4602uint64_t Address, const void *Decoder)4603{4604DecodeStatus S = MCDisassembler_Success;4605unsigned pred;4606unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4607unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);4608unsigned imm = fieldFromInstruction_4(Insn, 0, 12);4609imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;4610imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;4611pred = fieldFromInstruction_4(Insn, 28, 4);46124613if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;46144615if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4616return MCDisassembler_Fail;46174618if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))4619return MCDisassembler_Fail;46204621if (!Check(&S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))4622return MCDisassembler_Fail;46234624if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4625return MCDisassembler_Fail;46264627return S;4628}46294630static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,4631uint64_t Address, const void *Decoder)4632{4633DecodeStatus S = MCDisassembler_Success;4634unsigned pred;4635unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4636unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);4637unsigned imm = fieldFromInstruction_4(Insn, 0, 12);4638imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;4639imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;4640pred = fieldFromInstruction_4(Insn, 28, 4);46414642if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;46434644if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4645return MCDisassembler_Fail;46464647if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))4648return MCDisassembler_Fail;46494650if (!Check(&S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))4651return MCDisassembler_Fail;46524653if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))4654return MCDisassembler_Fail;46554656return S;4657}46584659static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,4660uint64_t Address, const void *Decoder)4661{4662DecodeStatus S = MCDisassembler_Success;4663unsigned size, align = 0, index = 0;4664unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4665unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);4666unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);4667Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;4668size = fieldFromInstruction_4(Insn, 10, 2);46694670switch (size) {4671default:4672return MCDisassembler_Fail;4673case 0:4674if (fieldFromInstruction_4(Insn, 4, 1))4675return MCDisassembler_Fail; // UNDEFINED4676index = fieldFromInstruction_4(Insn, 5, 3);4677break;4678case 1:4679if (fieldFromInstruction_4(Insn, 5, 1))4680return MCDisassembler_Fail; // UNDEFINED4681index = fieldFromInstruction_4(Insn, 6, 2);4682if (fieldFromInstruction_4(Insn, 4, 1))4683align = 2;4684break;4685case 2:4686if (fieldFromInstruction_4(Insn, 6, 1))4687return MCDisassembler_Fail; // UNDEFINED46884689index = fieldFromInstruction_4(Insn, 7, 1);46904691switch (fieldFromInstruction_4(Insn, 4, 2)) {4692case 0 :4693align = 0; break;4694case 3:4695align = 4; break;4696default:4697return MCDisassembler_Fail;4698}4699break;4700}47014702if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4703return MCDisassembler_Fail;47044705if (Rm != 0xF) { // Writeback4706if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4707return MCDisassembler_Fail;4708}47094710if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4711return MCDisassembler_Fail;47124713MCOperand_CreateImm0(Inst, align);47144715if (Rm != 0xF) {4716if (Rm != 0xD) {4717if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))4718return MCDisassembler_Fail;4719} else4720MCOperand_CreateReg0(Inst, 0);4721}47224723if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4724return MCDisassembler_Fail;47254726MCOperand_CreateImm0(Inst, index);47274728return S;4729}47304731static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,4732uint64_t Address, const void *Decoder)4733{4734DecodeStatus S = MCDisassembler_Success;4735unsigned size, align = 0, index = 0;4736unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4737unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);4738unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);4739Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;4740size = fieldFromInstruction_4(Insn, 10, 2);47414742switch (size) {4743default:4744return MCDisassembler_Fail;4745case 0:4746if (fieldFromInstruction_4(Insn, 4, 1))4747return MCDisassembler_Fail; // UNDEFINED47484749index = fieldFromInstruction_4(Insn, 5, 3);4750break;4751case 1:4752if (fieldFromInstruction_4(Insn, 5, 1))4753return MCDisassembler_Fail; // UNDEFINED47544755index = fieldFromInstruction_4(Insn, 6, 2);4756if (fieldFromInstruction_4(Insn, 4, 1))4757align = 2;4758break;4759case 2:4760if (fieldFromInstruction_4(Insn, 6, 1))4761return MCDisassembler_Fail; // UNDEFINED47624763index = fieldFromInstruction_4(Insn, 7, 1);47644765switch (fieldFromInstruction_4(Insn, 4, 2)) {4766case 0:4767align = 0; break;4768case 3:4769align = 4; break;4770default:4771return MCDisassembler_Fail;4772}4773break;4774}47754776if (Rm != 0xF) { // Writeback4777if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4778return MCDisassembler_Fail;4779}47804781if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4782return MCDisassembler_Fail;47834784MCOperand_CreateImm0(Inst, align);47854786if (Rm != 0xF) {4787if (Rm != 0xD) {4788if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))4789return MCDisassembler_Fail;4790} else4791MCOperand_CreateReg0(Inst, 0);4792}47934794if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4795return MCDisassembler_Fail;47964797MCOperand_CreateImm0(Inst, index);47984799return S;4800}48014802static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,4803uint64_t Address, const void *Decoder)4804{4805DecodeStatus S = MCDisassembler_Success;4806unsigned size, align = 0, index = 0, inc = 1;4807unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4808unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);4809unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);4810Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;4811size = fieldFromInstruction_4(Insn, 10, 2);48124813switch (size) {4814default:4815return MCDisassembler_Fail;4816case 0:4817index = fieldFromInstruction_4(Insn, 5, 3);4818if (fieldFromInstruction_4(Insn, 4, 1))4819align = 2;4820break;4821case 1:4822index = fieldFromInstruction_4(Insn, 6, 2);4823if (fieldFromInstruction_4(Insn, 4, 1))4824align = 4;4825if (fieldFromInstruction_4(Insn, 5, 1))4826inc = 2;4827break;4828case 2:4829if (fieldFromInstruction_4(Insn, 5, 1))4830return MCDisassembler_Fail; // UNDEFINED48314832index = fieldFromInstruction_4(Insn, 7, 1);4833if (fieldFromInstruction_4(Insn, 4, 1) != 0)4834align = 8;4835if (fieldFromInstruction_4(Insn, 6, 1))4836inc = 2;4837break;4838}48394840if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4841return MCDisassembler_Fail;48424843if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))4844return MCDisassembler_Fail;48454846if (Rm != 0xF) { // Writeback4847if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4848return MCDisassembler_Fail;4849}48504851if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4852return MCDisassembler_Fail;48534854MCOperand_CreateImm0(Inst, align);48554856if (Rm != 0xF) {4857if (Rm != 0xD) {4858if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))4859return MCDisassembler_Fail;4860} else4861MCOperand_CreateReg0(Inst, 0);4862}48634864if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4865return MCDisassembler_Fail;48664867if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))4868return MCDisassembler_Fail;48694870MCOperand_CreateImm0(Inst, index);48714872return S;4873}48744875static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,4876uint64_t Address, const void *Decoder)4877{4878DecodeStatus S = MCDisassembler_Success;4879unsigned size, align = 0, index = 0, inc = 1;4880unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4881unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);4882unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);4883Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;4884size = fieldFromInstruction_4(Insn, 10, 2);48854886switch (size) {4887default:4888return MCDisassembler_Fail;4889case 0:4890index = fieldFromInstruction_4(Insn, 5, 3);4891if (fieldFromInstruction_4(Insn, 4, 1))4892align = 2;4893break;4894case 1:4895index = fieldFromInstruction_4(Insn, 6, 2);4896if (fieldFromInstruction_4(Insn, 4, 1))4897align = 4;4898if (fieldFromInstruction_4(Insn, 5, 1))4899inc = 2;4900break;4901case 2:4902if (fieldFromInstruction_4(Insn, 5, 1))4903return MCDisassembler_Fail; // UNDEFINED49044905index = fieldFromInstruction_4(Insn, 7, 1);4906if (fieldFromInstruction_4(Insn, 4, 1) != 0)4907align = 8;4908if (fieldFromInstruction_4(Insn, 6, 1))4909inc = 2;4910break;4911}49124913if (Rm != 0xF) { // Writeback4914if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4915return MCDisassembler_Fail;4916}49174918if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4919return MCDisassembler_Fail;49204921MCOperand_CreateImm0(Inst, align);49224923if (Rm != 0xF) {4924if (Rm != 0xD) {4925if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))4926return MCDisassembler_Fail;4927} else4928MCOperand_CreateReg0(Inst, 0);4929}49304931if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4932return MCDisassembler_Fail;49334934if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))4935return MCDisassembler_Fail;49364937MCOperand_CreateImm0(Inst, index);49384939return S;4940}49414942static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,4943uint64_t Address, const void *Decoder)4944{4945DecodeStatus S = MCDisassembler_Success;4946unsigned size, align = 0, index = 0, inc = 1;4947unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);4948unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);4949unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);4950Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;4951size = fieldFromInstruction_4(Insn, 10, 2);49524953switch (size) {4954default:4955return MCDisassembler_Fail;4956case 0:4957if (fieldFromInstruction_4(Insn, 4, 1))4958return MCDisassembler_Fail; // UNDEFINED4959index = fieldFromInstruction_4(Insn, 5, 3);4960break;4961case 1:4962if (fieldFromInstruction_4(Insn, 4, 1))4963return MCDisassembler_Fail; // UNDEFINED4964index = fieldFromInstruction_4(Insn, 6, 2);4965if (fieldFromInstruction_4(Insn, 5, 1))4966inc = 2;4967break;4968case 2:4969if (fieldFromInstruction_4(Insn, 4, 2))4970return MCDisassembler_Fail; // UNDEFINED4971index = fieldFromInstruction_4(Insn, 7, 1);4972if (fieldFromInstruction_4(Insn, 6, 1))4973inc = 2;4974break;4975}49764977if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))4978return MCDisassembler_Fail;4979if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))4980return MCDisassembler_Fail;4981if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))4982return MCDisassembler_Fail;49834984if (Rm != 0xF) { // Writeback4985if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4986return MCDisassembler_Fail;4987}49884989if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))4990return MCDisassembler_Fail;49914992MCOperand_CreateImm0(Inst, align);49934994if (Rm != 0xF) {4995if (Rm != 0xD) {4996if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))4997return MCDisassembler_Fail;4998} else4999MCOperand_CreateReg0(Inst, 0);5000}50015002if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))5003return MCDisassembler_Fail;50045005if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))5006return MCDisassembler_Fail;50075008if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))5009return MCDisassembler_Fail;50105011MCOperand_CreateImm0(Inst, index);50125013return S;5014}50155016static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,5017uint64_t Address, const void *Decoder)5018{5019DecodeStatus S = MCDisassembler_Success;5020unsigned size, align = 0, index = 0, inc = 1;5021unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);5022unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);5023unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);5024Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;5025size = fieldFromInstruction_4(Insn, 10, 2);50265027switch (size) {5028default:5029return MCDisassembler_Fail;5030case 0:5031if (fieldFromInstruction_4(Insn, 4, 1))5032return MCDisassembler_Fail; // UNDEFINED5033index = fieldFromInstruction_4(Insn, 5, 3);5034break;5035case 1:5036if (fieldFromInstruction_4(Insn, 4, 1))5037return MCDisassembler_Fail; // UNDEFINED5038index = fieldFromInstruction_4(Insn, 6, 2);5039if (fieldFromInstruction_4(Insn, 5, 1))5040inc = 2;5041break;5042case 2:5043if (fieldFromInstruction_4(Insn, 4, 2))5044return MCDisassembler_Fail; // UNDEFINED5045index = fieldFromInstruction_4(Insn, 7, 1);5046if (fieldFromInstruction_4(Insn, 6, 1))5047inc = 2;5048break;5049}50505051if (Rm != 0xF) { // Writeback5052if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))5053return MCDisassembler_Fail;5054}50555056if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))5057return MCDisassembler_Fail;50585059MCOperand_CreateImm0(Inst, align);50605061if (Rm != 0xF) {5062if (Rm != 0xD) {5063if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))5064return MCDisassembler_Fail;5065} else5066MCOperand_CreateReg0(Inst, 0);5067}50685069if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))5070return MCDisassembler_Fail;50715072if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))5073return MCDisassembler_Fail;50745075if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))5076return MCDisassembler_Fail;50775078MCOperand_CreateImm0(Inst, index);50795080return S;5081}50825083static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,5084uint64_t Address, const void *Decoder)5085{5086DecodeStatus S = MCDisassembler_Success;5087unsigned size, align = 0, index = 0, inc = 1;5088unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);5089unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);5090unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);5091Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;5092size = fieldFromInstruction_4(Insn, 10, 2);50935094switch (size) {5095default:5096return MCDisassembler_Fail;5097case 0:5098if (fieldFromInstruction_4(Insn, 4, 1))5099align = 4;5100index = fieldFromInstruction_4(Insn, 5, 3);5101break;5102case 1:5103if (fieldFromInstruction_4(Insn, 4, 1))5104align = 8;5105index = fieldFromInstruction_4(Insn, 6, 2);5106if (fieldFromInstruction_4(Insn, 5, 1))5107inc = 2;5108break;5109case 2:5110switch (fieldFromInstruction_4(Insn, 4, 2)) {5111case 0:5112align = 0; break;5113case 3:5114return MCDisassembler_Fail;5115default:5116align = 4 << fieldFromInstruction_4(Insn, 4, 2); break;5117}51185119index = fieldFromInstruction_4(Insn, 7, 1);5120if (fieldFromInstruction_4(Insn, 6, 1))5121inc = 2;5122break;5123}51245125if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))5126return MCDisassembler_Fail;51275128if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))5129return MCDisassembler_Fail;51305131if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))5132return MCDisassembler_Fail;51335134if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 3*inc, Address, Decoder)))5135return MCDisassembler_Fail;51365137if (Rm != 0xF) { // Writeback5138if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))5139return MCDisassembler_Fail;5140}51415142if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))5143return MCDisassembler_Fail;51445145MCOperand_CreateImm0(Inst, align);51465147if (Rm != 0xF) {5148if (Rm != 0xD) {5149if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))5150return MCDisassembler_Fail;5151} else5152MCOperand_CreateReg0(Inst, 0);5153}51545155if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))5156return MCDisassembler_Fail;51575158if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))5159return MCDisassembler_Fail;51605161if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))5162return MCDisassembler_Fail;51635164if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 3*inc, Address, Decoder)))5165return MCDisassembler_Fail;51665167MCOperand_CreateImm0(Inst, index);51685169return S;5170}51715172static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,5173uint64_t Address, const void *Decoder)5174{5175DecodeStatus S = MCDisassembler_Success;5176unsigned size, align = 0, index = 0, inc = 1;5177unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);5178unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);5179unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);5180Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;5181size = fieldFromInstruction_4(Insn, 10, 2);51825183switch (size) {5184default:5185return MCDisassembler_Fail;5186case 0:5187if (fieldFromInstruction_4(Insn, 4, 1))5188align = 4;5189index = fieldFromInstruction_4(Insn, 5, 3);5190break;5191case 1:5192if (fieldFromInstruction_4(Insn, 4, 1))5193align = 8;5194index = fieldFromInstruction_4(Insn, 6, 2);5195if (fieldFromInstruction_4(Insn, 5, 1))5196inc = 2;5197break;5198case 2:5199switch (fieldFromInstruction_4(Insn, 4, 2)) {5200case 0:5201align = 0; break;5202case 3:5203return MCDisassembler_Fail;5204default:5205align = 4 << fieldFromInstruction_4(Insn, 4, 2); break;5206}52075208index = fieldFromInstruction_4(Insn, 7, 1);5209if (fieldFromInstruction_4(Insn, 6, 1))5210inc = 2;5211break;5212}52135214if (Rm != 0xF) { // Writeback5215if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))5216return MCDisassembler_Fail;5217}52185219if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))5220return MCDisassembler_Fail;52215222MCOperand_CreateImm0(Inst, align);52235224if (Rm != 0xF) {5225if (Rm != 0xD) {5226if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))5227return MCDisassembler_Fail;5228} else5229MCOperand_CreateReg0(Inst, 0);5230}52315232if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))5233return MCDisassembler_Fail;52345235if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))5236return MCDisassembler_Fail;52375238if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))5239return MCDisassembler_Fail;52405241if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 3*inc, Address, Decoder)))5242return MCDisassembler_Fail;52435244MCOperand_CreateImm0(Inst, index);52455246return S;5247}52485249static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,5250uint64_t Address, const void *Decoder)5251{5252DecodeStatus S = MCDisassembler_Success;5253unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);5254unsigned Rt2 = fieldFromInstruction_4(Insn, 16, 4);5255unsigned Rm = fieldFromInstruction_4(Insn, 5, 1);5256unsigned pred = fieldFromInstruction_4(Insn, 28, 4);5257Rm |= fieldFromInstruction_4(Insn, 0, 4) << 1;52585259if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)5260S = MCDisassembler_SoftFail;52615262if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))5263return MCDisassembler_Fail;52645265if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm + 1, Address, Decoder)))5266return MCDisassembler_Fail;52675268if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))5269return MCDisassembler_Fail;52705271if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))5272return MCDisassembler_Fail;52735274if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))5275return MCDisassembler_Fail;52765277return S;5278}52795280static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,5281uint64_t Address, const void *Decoder)5282{5283DecodeStatus S = MCDisassembler_Success;5284unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);5285unsigned Rt2 = fieldFromInstruction_4(Insn, 16, 4);5286unsigned Rm = fieldFromInstruction_4(Insn, 5, 1);5287unsigned pred = fieldFromInstruction_4(Insn, 28, 4);5288Rm |= fieldFromInstruction_4(Insn, 0, 4) << 1;52895290if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)5291S = MCDisassembler_SoftFail;52925293if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))5294return MCDisassembler_Fail;52955296if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))5297return MCDisassembler_Fail;52985299if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))5300return MCDisassembler_Fail;53015302if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm + 1, Address, Decoder)))5303return MCDisassembler_Fail;53045305if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))5306return MCDisassembler_Fail;53075308return S;5309}53105311static DecodeStatus DecodeIT(MCInst *Inst, unsigned Insn,5312uint64_t Address, const void *Decoder)5313{5314DecodeStatus S = MCDisassembler_Success;5315unsigned pred = fieldFromInstruction_4(Insn, 4, 4);5316unsigned mask = fieldFromInstruction_4(Insn, 0, 4);53175318if (pred == 0xF) {5319pred = 0xE;5320S = MCDisassembler_SoftFail;5321}53225323if (mask == 0x0)5324return MCDisassembler_Fail;53255326MCOperand_CreateImm0(Inst, pred);5327MCOperand_CreateImm0(Inst, mask);53285329return S;5330}53315332static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst, unsigned Insn,5333uint64_t Address, const void *Decoder)5334{5335DecodeStatus S = MCDisassembler_Success;5336unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);5337unsigned Rt2 = fieldFromInstruction_4(Insn, 8, 4);5338unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);5339unsigned addr = fieldFromInstruction_4(Insn, 0, 8);5340unsigned W = fieldFromInstruction_4(Insn, 21, 1);5341unsigned U = fieldFromInstruction_4(Insn, 23, 1);5342unsigned P = fieldFromInstruction_4(Insn, 24, 1);5343bool writeback = (W == 1) | (P == 0);53445345addr |= (U << 8) | (Rn << 9);53465347if (writeback && (Rn == Rt || Rn == Rt2))5348Check(&S, MCDisassembler_SoftFail);53495350if (Rt == Rt2)5351Check(&S, MCDisassembler_SoftFail);53525353// Rt5354if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))5355return MCDisassembler_Fail;53565357// Rt25358if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))5359return MCDisassembler_Fail;53605361// Writeback operand5362if (!Check(&S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))5363return MCDisassembler_Fail;53645365// addr5366if (!Check(&S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))5367return MCDisassembler_Fail;53685369return S;5370}53715372static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst, unsigned Insn,5373uint64_t Address, const void *Decoder)5374{5375DecodeStatus S = MCDisassembler_Success;5376unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);5377unsigned Rt2 = fieldFromInstruction_4(Insn, 8, 4);5378unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);5379unsigned addr = fieldFromInstruction_4(Insn, 0, 8);5380unsigned W = fieldFromInstruction_4(Insn, 21, 1);5381unsigned U = fieldFromInstruction_4(Insn, 23, 1);5382unsigned P = fieldFromInstruction_4(Insn, 24, 1);5383bool writeback = (W == 1) | (P == 0);53845385addr |= (U << 8) | (Rn << 9);53865387if (writeback && (Rn == Rt || Rn == Rt2))5388Check(&S, MCDisassembler_SoftFail);53895390// Writeback operand5391if (!Check(&S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))5392return MCDisassembler_Fail;53935394// Rt5395if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))5396return MCDisassembler_Fail;53975398// Rt25399if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))5400return MCDisassembler_Fail;54015402// addr5403if (!Check(&S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))5404return MCDisassembler_Fail;54055406return S;5407}54085409static DecodeStatus DecodeT2Adr(MCInst *Inst, uint32_t Insn,5410uint64_t Address, const void *Decoder)5411{5412unsigned Val;5413unsigned sign1 = fieldFromInstruction_4(Insn, 21, 1);5414unsigned sign2 = fieldFromInstruction_4(Insn, 23, 1);54155416if (sign1 != sign2) return MCDisassembler_Fail;54175418Val = fieldFromInstruction_4(Insn, 0, 8);5419Val |= fieldFromInstruction_4(Insn, 12, 3) << 8;5420Val |= fieldFromInstruction_4(Insn, 26, 1) << 11;5421Val |= sign1 << 12;54225423MCOperand_CreateImm0(Inst, SignExtend32(Val, 13));54245425return MCDisassembler_Success;5426}54275428static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,5429uint64_t Address, const void *Decoder)5430{5431// Shift of "asr #32" is not allowed in Thumb2 mode.5432if (Val == 0x20)5433return MCDisassembler_Fail;54345435MCOperand_CreateImm0(Inst, Val);54365437return MCDisassembler_Success;5438}54395440static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,5441uint64_t Address, const void *Decoder)5442{5443DecodeStatus S;5444unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);5445unsigned Rt2 = fieldFromInstruction_4(Insn, 0, 4);5446unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);5447unsigned pred = fieldFromInstruction_4(Insn, 28, 4);54485449if (pred == 0xF)5450return DecodeCPSInstruction(Inst, Insn, Address, Decoder);54515452S = MCDisassembler_Success;54535454if (Rt == Rn || Rn == Rt2)5455S = MCDisassembler_SoftFail;54565457if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))5458return MCDisassembler_Fail;54595460if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))5461return MCDisassembler_Fail;54625463if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))5464return MCDisassembler_Fail;54655466if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))5467return MCDisassembler_Fail;54685469return S;5470}54715472static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,5473uint64_t Address, const void *Decoder)5474{5475DecodeStatus S = MCDisassembler_Success;5476bool hasFullFP16 = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureFullFP16);5477unsigned Vm, imm, cmode, op;5478unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);54795480Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);5481Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);5482Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);5483imm = fieldFromInstruction_4(Insn, 16, 6);5484cmode = fieldFromInstruction_4(Insn, 8, 4);5485op = fieldFromInstruction_4(Insn, 5, 1);54865487// If the top 3 bits of imm are clear, this is a VMOV (immediate)5488if (!(imm & 0x38)) {5489if (cmode == 0xF) {5490if (op == 1) return MCDisassembler_Fail;5491MCInst_setOpcode(Inst, ARM_VMOVv2f32);5492}54935494if (hasFullFP16) {5495if (cmode == 0xE) {5496if (op == 1) {5497MCInst_setOpcode(Inst, ARM_VMOVv1i64);5498} else {5499MCInst_setOpcode(Inst, ARM_VMOVv8i8);5500}5501}55025503if (cmode == 0xD) {5504if (op == 1) {5505MCInst_setOpcode(Inst, ARM_VMVNv2i32);5506} else {5507MCInst_setOpcode(Inst, ARM_VMOVv2i32);5508}5509}55105511if (cmode == 0xC) {5512if (op == 1) {5513MCInst_setOpcode(Inst, ARM_VMVNv2i32);5514} else {5515MCInst_setOpcode(Inst, ARM_VMOVv2i32);5516}5517}5518}55195520return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);5521}55225523if (!(imm & 0x20)) return MCDisassembler_Fail;55245525if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))5526return MCDisassembler_Fail;55275528if (!Check(&S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))5529return MCDisassembler_Fail;55305531MCOperand_CreateImm0(Inst, 64 - imm);55325533return S;5534}55355536static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,5537uint64_t Address, const void *Decoder)5538{5539DecodeStatus S = MCDisassembler_Success;5540bool hasFullFP16 = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureFullFP16);5541unsigned Vm, imm, cmode, op;5542unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);55435544Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);5545Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);5546Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);5547imm = fieldFromInstruction_4(Insn, 16, 6);5548cmode = fieldFromInstruction_4(Insn, 8, 4);5549op = fieldFromInstruction_4(Insn, 5, 1);55505551// VMOVv4f32 is ambiguous with these decodings.5552if (!(imm & 0x38) && cmode == 0xF) {5553if (op == 1) return MCDisassembler_Fail;5554MCInst_setOpcode(Inst, ARM_VMOVv4f32);5555return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);5556}55575558// If the top 3 bits of imm are clear, this is a VMOV (immediate)5559if (!(imm & 0x38)) {5560if (cmode == 0xF) {5561if (op == 1) return MCDisassembler_Fail;5562MCInst_setOpcode(Inst, ARM_VMOVv4f32);5563}55645565if (hasFullFP16) {5566if (cmode == 0xE) {5567if (op == 1) {5568MCInst_setOpcode(Inst, ARM_VMOVv2i64);5569} else {5570MCInst_setOpcode(Inst, ARM_VMOVv16i8);5571}5572}55735574if (cmode == 0xD) {5575if (op == 1) {5576MCInst_setOpcode(Inst, ARM_VMVNv4i32);5577} else {5578MCInst_setOpcode(Inst, ARM_VMOVv4i32);5579}5580}55815582if (cmode == 0xC) {5583if (op == 1) {5584MCInst_setOpcode(Inst, ARM_VMVNv4i32);5585} else {5586MCInst_setOpcode(Inst, ARM_VMOVv4i32);5587}5588}5589}55905591return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);5592}55935594if (!(imm & 0x20)) return MCDisassembler_Fail;55955596if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))5597return MCDisassembler_Fail;55985599if (!Check(&S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))5600return MCDisassembler_Fail;56015602MCOperand_CreateImm0(Inst, 64 - imm);56035604return S;5605}56065607static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst *Inst, unsigned Insn,5608uint64_t Address, const void *Decoder)5609{5610DecodeStatus S = MCDisassembler_Success;5611unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);5612unsigned Vn = (fieldFromInstruction_4(Insn, 16, 4) << 0);5613unsigned Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);5614unsigned q = (fieldFromInstruction_4(Insn, 6, 1) << 0);5615unsigned rotate = (fieldFromInstruction_4(Insn, 20, 2) << 0);56165617Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);5618Vn |= (fieldFromInstruction_4(Insn, 7, 1) << 4);5619Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);56205621if (q) {5622if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))5623return MCDisassembler_Fail;56245625if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))5626return MCDisassembler_Fail;56275628if (!Check(&S, DecodeQPRRegisterClass(Inst, Vn, Address, Decoder)))5629return MCDisassembler_Fail;5630} else {5631if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))5632return MCDisassembler_Fail;56335634if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))5635return MCDisassembler_Fail;56365637if (!Check(&S, DecodeDPRRegisterClass(Inst, Vn, Address, Decoder)))5638return MCDisassembler_Fail;5639}56405641if (!Check(&S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))5642return MCDisassembler_Fail;56435644// The lane index does not have any bits in the encoding, because it can only5645// be 0.5646MCOperand_CreateImm0(Inst, 0);5647MCOperand_CreateImm0(Inst, rotate);56485649return S;5650}56515652static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,5653uint64_t Address, const void *Decoder)5654{5655DecodeStatus S = MCDisassembler_Success;5656unsigned Cond;5657unsigned Rn = fieldFromInstruction_4(Val, 16, 4);5658unsigned Rt = fieldFromInstruction_4(Val, 12, 4);5659unsigned Rm = fieldFromInstruction_4(Val, 0, 4);56605661Rm |= (fieldFromInstruction_4(Val, 23, 1) << 4);5662Cond = fieldFromInstruction_4(Val, 28, 4);56635664if (fieldFromInstruction_4(Val, 8, 4) != 0 || Rn == Rt)5665S = MCDisassembler_SoftFail;56665667if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))5668return MCDisassembler_Fail;56695670if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))5671return MCDisassembler_Fail;56725673if (!Check(&S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))5674return MCDisassembler_Fail;56755676if (!Check(&S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))5677return MCDisassembler_Fail;56785679if (!Check(&S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))5680return MCDisassembler_Fail;56815682return S;5683}56845685static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst *Inst, unsigned Val,5686uint64_t Address, const void *Decoder)5687{5688DecodeStatus result = MCDisassembler_Success;5689unsigned CRm = fieldFromInstruction_4(Val, 0, 4);5690unsigned opc1 = fieldFromInstruction_4(Val, 4, 4);5691unsigned cop = fieldFromInstruction_4(Val, 8, 4);5692unsigned Rt = fieldFromInstruction_4(Val, 12, 4);5693unsigned Rt2 = fieldFromInstruction_4(Val, 16, 4);56945695if ((cop & ~0x1) == 0xa)5696return MCDisassembler_Fail;56975698if (Rt == Rt2)5699result = MCDisassembler_SoftFail;57005701// We have to check if the instruction is MRRC25702// or MCRR2 when constructing the operands for5703// Inst. Reason is because MRRC2 stores to two5704// registers so it's tablegen desc has has two5705// outputs whereas MCRR doesn't store to any5706// registers so all of it's operands are listed5707// as inputs, therefore the operand order for5708// MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]5709// and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]57105711if (MCInst_getOpcode(Inst) == ARM_MRRC2) {5712if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))5713return MCDisassembler_Fail;57145715if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))5716return MCDisassembler_Fail;5717}57185719MCOperand_CreateImm0(Inst, cop);5720MCOperand_CreateImm0(Inst, opc1);57215722if (MCInst_getOpcode(Inst) == ARM_MCRR2) {5723if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))5724return MCDisassembler_Fail;57255726if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))5727return MCDisassembler_Fail;5728}57295730MCOperand_CreateImm0(Inst, CRm);57315732return result;5733}57345735static DecodeStatus DecodeForVMRSandVMSR(MCInst *Inst, unsigned Val,5736uint64_t Address, const void *Decoder)5737{5738DecodeStatus result = MCDisassembler_Success;5739bool HasV8Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops);5740unsigned Rt = fieldFromInstruction_4(Val, 12, 4);57415742if ((Inst->csh->mode & CS_MODE_THUMB) && !HasV8Ops) {5743if (Rt == 13 || Rt == 15)5744result = MCDisassembler_SoftFail;57455746Check(&result, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));5747} else5748Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));57495750if (Inst->csh->mode & CS_MODE_THUMB) {5751MCOperand_CreateImm0(Inst, ARMCC_AL);5752MCOperand_CreateReg0(Inst, 0);5753} else {5754unsigned pred = fieldFromInstruction_4(Val, 28, 4);5755if (!Check(&result, DecodePredicateOperand(Inst, pred, Address, Decoder)))5756return MCDisassembler_Fail;5757}57585759return result;5760}57615762#endif576357645765