1234353Sdim//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===// 2206124Srdivacky// 3206124Srdivacky// The LLVM Compiler Infrastructure 4206124Srdivacky// 5206124Srdivacky// This file is distributed under the University of Illinois Open Source 6206124Srdivacky// License. See LICENSE.TXT for details. 7206124Srdivacky// 8206124Srdivacky//===----------------------------------------------------------------------===// 9206124Srdivacky 10206124Srdivacky#define DEBUG_TYPE "arm-disassembler" 11206124Srdivacky 12249423Sdim#include "llvm/MC/MCDisassembler.h" 13226633Sdim#include "MCTargetDesc/ARMAddressingModes.h" 14249423Sdim#include "MCTargetDesc/ARMBaseInfo.h" 15226633Sdim#include "MCTargetDesc/ARMMCExpr.h" 16249423Sdim#include "llvm/MC/MCContext.h" 17249423Sdim#include "llvm/MC/MCExpr.h" 18249423Sdim#include "llvm/MC/MCFixedLenDisassembler.h" 19206124Srdivacky#include "llvm/MC/MCInst.h" 20234353Sdim#include "llvm/MC/MCInstrDesc.h" 21234353Sdim#include "llvm/MC/MCSubtargetInfo.h" 22206124Srdivacky#include "llvm/Support/Debug.h" 23206124Srdivacky#include "llvm/Support/ErrorHandling.h" 24239462Sdim#include "llvm/Support/LEB128.h" 25249423Sdim#include "llvm/Support/MemoryObject.h" 26226633Sdim#include "llvm/Support/TargetRegistry.h" 27206124Srdivacky#include "llvm/Support/raw_ostream.h" 28239462Sdim#include <vector> 29206124Srdivacky 30226633Sdimusing namespace llvm; 31212904Sdim 32226633Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus; 33206124Srdivacky 34226633Sdimnamespace { 35239462Sdim // Handles the condition code status of instructions in IT blocks 36239462Sdim class ITStatus 37239462Sdim { 38239462Sdim public: 39239462Sdim // Returns the condition code for instruction in IT block 40239462Sdim unsigned getITCC() { 41239462Sdim unsigned CC = ARMCC::AL; 42239462Sdim if (instrInITBlock()) 43239462Sdim CC = ITStates.back(); 44239462Sdim return CC; 45239462Sdim } 46239462Sdim 47239462Sdim // Advances the IT block state to the next T or E 48239462Sdim void advanceITState() { 49239462Sdim ITStates.pop_back(); 50239462Sdim } 51239462Sdim 52239462Sdim // Returns true if the current instruction is in an IT block 53239462Sdim bool instrInITBlock() { 54239462Sdim return !ITStates.empty(); 55239462Sdim } 56239462Sdim 57239462Sdim // Returns true if current instruction is the last instruction in an IT block 58239462Sdim bool instrLastInITBlock() { 59239462Sdim return ITStates.size() == 1; 60239462Sdim } 61239462Sdim 62239462Sdim // Called when decoding an IT instruction. Sets the IT state for the following 63239462Sdim // instructions that for the IT block. Firstcond and Mask correspond to the 64239462Sdim // fields in the IT instruction encoding. 65239462Sdim void setITState(char Firstcond, char Mask) { 66239462Sdim // (3 - the number of trailing zeros) is the number of then / else. 67239462Sdim unsigned CondBit0 = Firstcond & 1; 68239462Sdim unsigned NumTZ = CountTrailingZeros_32(Mask); 69239462Sdim unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf); 70239462Sdim assert(NumTZ <= 3 && "Invalid IT mask!"); 71239462Sdim // push condition codes onto the stack the correct order for the pops 72239462Sdim for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) { 73239462Sdim bool T = ((Mask >> Pos) & 1) == CondBit0; 74239462Sdim if (T) 75239462Sdim ITStates.push_back(CCBits); 76239462Sdim else 77239462Sdim ITStates.push_back(CCBits ^ 1); 78239462Sdim } 79239462Sdim ITStates.push_back(CCBits); 80239462Sdim } 81239462Sdim 82239462Sdim private: 83239462Sdim std::vector<unsigned char> ITStates; 84239462Sdim }; 85239462Sdim} 86239462Sdim 87239462Sdimnamespace { 88226633Sdim/// ARMDisassembler - ARM disassembler for all ARM platforms. 89226633Sdimclass ARMDisassembler : public MCDisassembler { 90226633Sdimpublic: 91226633Sdim /// Constructor - Initializes the disassembler. 92226633Sdim /// 93226633Sdim ARMDisassembler(const MCSubtargetInfo &STI) : 94226633Sdim MCDisassembler(STI) { 95226633Sdim } 96226633Sdim 97226633Sdim ~ARMDisassembler() { 98226633Sdim } 99226633Sdim 100226633Sdim /// getInstruction - See MCDisassembler. 101226633Sdim DecodeStatus getInstruction(MCInst &instr, 102226633Sdim uint64_t &size, 103226633Sdim const MemoryObject ®ion, 104226633Sdim uint64_t address, 105226633Sdim raw_ostream &vStream, 106226633Sdim raw_ostream &cStream) const; 107226633Sdim}; 108226633Sdim 109226633Sdim/// ThumbDisassembler - Thumb disassembler for all Thumb platforms. 110226633Sdimclass ThumbDisassembler : public MCDisassembler { 111226633Sdimpublic: 112226633Sdim /// Constructor - Initializes the disassembler. 113226633Sdim /// 114226633Sdim ThumbDisassembler(const MCSubtargetInfo &STI) : 115226633Sdim MCDisassembler(STI) { 116226633Sdim } 117226633Sdim 118226633Sdim ~ThumbDisassembler() { 119226633Sdim } 120226633Sdim 121226633Sdim /// getInstruction - See MCDisassembler. 122226633Sdim DecodeStatus getInstruction(MCInst &instr, 123226633Sdim uint64_t &size, 124226633Sdim const MemoryObject ®ion, 125226633Sdim uint64_t address, 126226633Sdim raw_ostream &vStream, 127226633Sdim raw_ostream &cStream) const; 128226633Sdim 129226633Sdimprivate: 130239462Sdim mutable ITStatus ITBlock; 131226633Sdim DecodeStatus AddThumbPredicate(MCInst&) const; 132226633Sdim void UpdateThumbVFPPredicate(MCInst&) const; 133226633Sdim}; 134226633Sdim} 135226633Sdim 136226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) { 137226633Sdim switch (In) { 138226633Sdim case MCDisassembler::Success: 139226633Sdim // Out stays the same. 140226633Sdim return true; 141226633Sdim case MCDisassembler::SoftFail: 142226633Sdim Out = In; 143226633Sdim return true; 144226633Sdim case MCDisassembler::Fail: 145226633Sdim Out = In; 146226633Sdim return false; 147226633Sdim } 148234353Sdim llvm_unreachable("Invalid DecodeStatus!"); 149226633Sdim} 150226633Sdim 151226633Sdim 152226633Sdim// Forward declare these because the autogenerated code will reference them. 153226633Sdim// Definitions are further down. 154234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 155226633Sdim uint64_t Address, const void *Decoder); 156234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, 157226633Sdim unsigned RegNo, uint64_t Address, 158226633Sdim const void *Decoder); 159234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 160226633Sdim uint64_t Address, const void *Decoder); 161234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 162226633Sdim uint64_t Address, const void *Decoder); 163234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 164226633Sdim uint64_t Address, const void *Decoder); 165234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 166226633Sdim uint64_t Address, const void *Decoder); 167234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 168226633Sdim uint64_t Address, const void *Decoder); 169234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 170226633Sdim uint64_t Address, const void *Decoder); 171234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, 172226633Sdim unsigned RegNo, 173226633Sdim uint64_t Address, 174226633Sdim const void *Decoder); 175234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 176226633Sdim uint64_t Address, const void *Decoder); 177234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 178234353Sdim uint64_t Address, const void *Decoder); 179234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 180234353Sdim unsigned RegNo, uint64_t Address, 181234353Sdim const void *Decoder); 182226633Sdim 183234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 184226633Sdim uint64_t Address, const void *Decoder); 185234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 186226633Sdim uint64_t Address, const void *Decoder); 187234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, 188226633Sdim uint64_t Address, const void *Decoder); 189234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 190226633Sdim uint64_t Address, const void *Decoder); 191234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 192226633Sdim uint64_t Address, const void *Decoder); 193234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 194226633Sdim uint64_t Address, const void *Decoder); 195226633Sdim 196234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn, 197226633Sdim uint64_t Address, const void *Decoder); 198234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 199226633Sdim uint64_t Address, const void *Decoder); 200234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst, 201226633Sdim unsigned Insn, 202226633Sdim uint64_t Address, 203226633Sdim const void *Decoder); 204234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn, 205226633Sdim uint64_t Address, const void *Decoder); 206234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn, 207226633Sdim uint64_t Address, const void *Decoder); 208234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn, 209226633Sdim uint64_t Address, const void *Decoder); 210234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn, 211226633Sdim uint64_t Address, const void *Decoder); 212226633Sdim 213234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst, 214226633Sdim unsigned Insn, 215226633Sdim uint64_t Adddress, 216226633Sdim const void *Decoder); 217234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 218226633Sdim uint64_t Address, const void *Decoder); 219234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 220226633Sdim uint64_t Address, const void *Decoder); 221234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 222226633Sdim uint64_t Address, const void *Decoder); 223234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 224226633Sdim uint64_t Address, const void *Decoder); 225234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 226226633Sdim uint64_t Address, const void *Decoder); 227234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 228226633Sdim uint64_t Address, const void *Decoder); 229234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 230226633Sdim uint64_t Address, const void *Decoder); 231234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 232226633Sdim uint64_t Address, const void *Decoder); 233234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn, 234226633Sdim uint64_t Address, const void *Decoder); 235234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn, 236226633Sdim uint64_t Address, const void *Decoder); 237234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 238226633Sdim uint64_t Address, const void *Decoder); 239234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val, 240226633Sdim uint64_t Address, const void *Decoder); 241234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val, 242226633Sdim uint64_t Address, const void *Decoder); 243234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val, 244226633Sdim uint64_t Address, const void *Decoder); 245234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val, 246226633Sdim uint64_t Address, const void *Decoder); 247234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val, 248226633Sdim uint64_t Address, const void *Decoder); 249234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val, 250226633Sdim uint64_t Address, const void *Decoder); 251234353Sdimstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val, 252226633Sdim uint64_t Address, const void *Decoder); 253234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val, 254226633Sdim uint64_t Address, const void *Decoder); 255234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 256226633Sdim uint64_t Address, const void *Decoder); 257234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 258226633Sdim uint64_t Address, const void *Decoder); 259234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 260226633Sdim uint64_t Address, const void *Decoder); 261234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 262226633Sdim uint64_t Address, const void *Decoder); 263234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 264226633Sdim uint64_t Address, const void *Decoder); 265234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 266226633Sdim uint64_t Address, const void *Decoder); 267234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn, 268226633Sdim uint64_t Address, const void *Decoder); 269234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn, 270226633Sdim uint64_t Address, const void *Decoder); 271234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, 272226633Sdim uint64_t Address, const void *Decoder); 273234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 274226633Sdim uint64_t Address, const void *Decoder); 275234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 276226633Sdim uint64_t Address, const void *Decoder); 277234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 278226633Sdim uint64_t Address, const void *Decoder); 279234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 280226633Sdim uint64_t Address, const void *Decoder); 281234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 282226633Sdim uint64_t Address, const void *Decoder); 283234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 284226633Sdim uint64_t Address, const void *Decoder); 285234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 286226633Sdim uint64_t Address, const void *Decoder); 287234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 288226633Sdim uint64_t Address, const void *Decoder); 289234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 290226633Sdim uint64_t Address, const void *Decoder); 291234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 292226633Sdim uint64_t Address, const void *Decoder); 293234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 294226633Sdim uint64_t Address, const void *Decoder); 295234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 296226633Sdim uint64_t Address, const void *Decoder); 297234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 298226633Sdim uint64_t Address, const void *Decoder); 299234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 300226633Sdim uint64_t Address, const void *Decoder); 301234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 302226633Sdim uint64_t Address, const void *Decoder); 303234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 304226633Sdim uint64_t Address, const void *Decoder); 305234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 306234353Sdim uint64_t Address, const void *Decoder); 307234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 308234353Sdim uint64_t Address, const void *Decoder); 309234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 310234353Sdim uint64_t Address, const void *Decoder); 311251662Sdimstatic DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address, 312251662Sdim const void *Decoder); 313226633Sdim 314234353Sdim 315234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 316226633Sdim uint64_t Address, const void *Decoder); 317234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 318226633Sdim uint64_t Address, const void *Decoder); 319234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 320226633Sdim uint64_t Address, const void *Decoder); 321234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 322226633Sdim uint64_t Address, const void *Decoder); 323234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 324226633Sdim uint64_t Address, const void *Decoder); 325234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 326226633Sdim uint64_t Address, const void *Decoder); 327234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 328226633Sdim uint64_t Address, const void *Decoder); 329234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 330226633Sdim uint64_t Address, const void *Decoder); 331234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 332226633Sdim uint64_t Address, const void *Decoder); 333234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val, 334226633Sdim uint64_t Address, const void *Decoder); 335234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 336226633Sdim uint64_t Address, const void *Decoder); 337234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 338226633Sdim uint64_t Address, const void *Decoder); 339234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 340226633Sdim uint64_t Address, const void *Decoder); 341234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 342226633Sdim uint64_t Address, const void *Decoder); 343234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 344226633Sdim uint64_t Address, const void *Decoder); 345234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val, 346226633Sdim uint64_t Address, const void *Decoder); 347234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 348226633Sdim uint64_t Address, const void *Decoder); 349234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 350226633Sdim uint64_t Address, const void *Decoder); 351234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn, 352226633Sdim uint64_t Address, const void *Decoder); 353234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 354226633Sdim uint64_t Address, const void *Decoder); 355234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val, 356226633Sdim uint64_t Address, const void *Decoder); 357234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val, 358226633Sdim uint64_t Address, const void *Decoder); 359234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 360226633Sdim uint64_t Address, const void *Decoder); 361234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val, 362226633Sdim uint64_t Address, const void *Decoder); 363234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 364226633Sdim uint64_t Address, const void *Decoder); 365234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, 366226633Sdim uint64_t Address, const void *Decoder); 367234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn, 368226633Sdim uint64_t Address, const void *Decoder); 369234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn, 370226633Sdim uint64_t Address, const void *Decoder); 371234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, 372226633Sdim uint64_t Address, const void *Decoder); 373234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val, 374226633Sdim uint64_t Address, const void *Decoder); 375234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, 376226633Sdim uint64_t Address, const void *Decoder); 377226633Sdim 378234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 379234353Sdim uint64_t Address, const void *Decoder); 380234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, 381234982Sdim uint64_t Address, const void *Decoder); 382226633Sdim#include "ARMGenDisassemblerTables.inc" 383206124Srdivacky 384226633Sdimstatic MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) { 385226633Sdim return new ARMDisassembler(STI); 386226633Sdim} 387207618Srdivacky 388226633Sdimstatic MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) { 389226633Sdim return new ThumbDisassembler(STI); 390226633Sdim} 391226633Sdim 392226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 393226633Sdim const MemoryObject &Region, 394226633Sdim uint64_t Address, 395226633Sdim raw_ostream &os, 396226633Sdim raw_ostream &cs) const { 397226633Sdim CommentStream = &cs; 398226633Sdim 399226633Sdim uint8_t bytes[4]; 400226633Sdim 401226633Sdim assert(!(STI.getFeatureBits() & ARM::ModeThumb) && 402226633Sdim "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!"); 403226633Sdim 404226633Sdim // We want to read exactly 4 bytes of data. 405226633Sdim if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { 406226633Sdim Size = 0; 407226633Sdim return MCDisassembler::Fail; 408206124Srdivacky } 409226633Sdim 410226633Sdim // Encoded as a small-endian 32-bit word in the stream. 411226633Sdim uint32_t insn = (bytes[3] << 24) | 412226633Sdim (bytes[2] << 16) | 413226633Sdim (bytes[1] << 8) | 414226633Sdim (bytes[0] << 0); 415226633Sdim 416226633Sdim // Calling the auto-generated decoder function. 417239462Sdim DecodeStatus result = decodeInstruction(DecoderTableARM32, MI, insn, 418239462Sdim Address, this, STI); 419226633Sdim if (result != MCDisassembler::Fail) { 420226633Sdim Size = 4; 421226633Sdim return result; 422226633Sdim } 423226633Sdim 424226633Sdim // VFP and NEON instructions, similarly, are shared between ARM 425226633Sdim // and Thumb modes. 426226633Sdim MI.clear(); 427239462Sdim result = decodeInstruction(DecoderTableVFP32, MI, insn, Address, this, STI); 428226633Sdim if (result != MCDisassembler::Fail) { 429226633Sdim Size = 4; 430226633Sdim return result; 431226633Sdim } 432226633Sdim 433226633Sdim MI.clear(); 434239462Sdim result = decodeInstruction(DecoderTableNEONData32, MI, insn, Address, 435239462Sdim this, STI); 436226633Sdim if (result != MCDisassembler::Fail) { 437226633Sdim Size = 4; 438226633Sdim // Add a fake predicate operand, because we share these instruction 439226633Sdim // definitions with Thumb2 where these instructions are predicable. 440226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 441226633Sdim return MCDisassembler::Fail; 442226633Sdim return result; 443226633Sdim } 444226633Sdim 445226633Sdim MI.clear(); 446239462Sdim result = decodeInstruction(DecoderTableNEONLoadStore32, MI, insn, Address, 447239462Sdim this, STI); 448226633Sdim if (result != MCDisassembler::Fail) { 449226633Sdim Size = 4; 450226633Sdim // Add a fake predicate operand, because we share these instruction 451226633Sdim // definitions with Thumb2 where these instructions are predicable. 452226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 453226633Sdim return MCDisassembler::Fail; 454226633Sdim return result; 455226633Sdim } 456226633Sdim 457226633Sdim MI.clear(); 458239462Sdim result = decodeInstruction(DecoderTableNEONDup32, MI, insn, Address, 459239462Sdim this, STI); 460226633Sdim if (result != MCDisassembler::Fail) { 461226633Sdim Size = 4; 462226633Sdim // Add a fake predicate operand, because we share these instruction 463226633Sdim // definitions with Thumb2 where these instructions are predicable. 464226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 465226633Sdim return MCDisassembler::Fail; 466226633Sdim return result; 467226633Sdim } 468226633Sdim 469226633Sdim MI.clear(); 470226633Sdim 471226633Sdim Size = 0; 472226633Sdim return MCDisassembler::Fail; 473206124Srdivacky} 474206124Srdivacky 475226633Sdimnamespace llvm { 476234353Sdimextern const MCInstrDesc ARMInsts[]; 477226633Sdim} 478206124Srdivacky 479226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 480226633Sdim/// immediate Value in the MCInst. The immediate Value has had any PC 481226633Sdim/// adjustment made by the caller. If the instruction is a branch instruction 482226633Sdim/// then isBranch is true, else false. If the getOpInfo() function was set as 483226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called 484226633Sdim/// to get any symbolic information at the Address for this instruction. If 485226633Sdim/// that returns non-zero then the symbolic information it returns is used to 486226633Sdim/// create an MCExpr and that is added as an operand to the MCInst. If 487226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for 488226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else 489226633Sdim/// an MCExpr with Value is created. This function returns true if it adds an 490226633Sdim/// operand to the MCInst and false otherwise. 491226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value, 492226633Sdim bool isBranch, uint64_t InstSize, 493226633Sdim MCInst &MI, const void *Decoder) { 494226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 495226633Sdim LLVMOpInfoCallback getOpInfo = Dis->getLLVMOpInfoCallback(); 496226633Sdim struct LLVMOpInfo1 SymbolicOp; 497234353Sdim memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1)); 498226633Sdim SymbolicOp.Value = Value; 499226633Sdim void *DisInfo = Dis->getDisInfoBlock(); 500234353Sdim 501234353Sdim if (!getOpInfo || 502234353Sdim !getOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp)) { 503234353Sdim // Clear SymbolicOp.Value from above and also all other fields. 504234353Sdim memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1)); 505234353Sdim LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback(); 506234353Sdim if (!SymbolLookUp) 507234353Sdim return false; 508234353Sdim uint64_t ReferenceType; 509234353Sdim if (isBranch) 510234353Sdim ReferenceType = LLVMDisassembler_ReferenceType_In_Branch; 511234353Sdim else 512234353Sdim ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; 513234353Sdim const char *ReferenceName; 514243830Sdim uint64_t SymbolValue = 0x00000000ffffffffULL & Value; 515243830Sdim const char *Name = SymbolLookUp(DisInfo, SymbolValue, &ReferenceType, 516243830Sdim Address, &ReferenceName); 517234353Sdim if (Name) { 518234353Sdim SymbolicOp.AddSymbol.Name = Name; 519234353Sdim SymbolicOp.AddSymbol.Present = true; 520226633Sdim } 521234353Sdim // For branches always create an MCExpr so it gets printed as hex address. 522234353Sdim else if (isBranch) { 523234353Sdim SymbolicOp.Value = Value; 524234353Sdim } 525234353Sdim if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub) 526234353Sdim (*Dis->CommentStream) << "symbol stub for: " << ReferenceName; 527234353Sdim if (!Name && !isBranch) 528226633Sdim return false; 529226633Sdim } 530226633Sdim 531226633Sdim MCContext *Ctx = Dis->getMCContext(); 532226633Sdim const MCExpr *Add = NULL; 533226633Sdim if (SymbolicOp.AddSymbol.Present) { 534226633Sdim if (SymbolicOp.AddSymbol.Name) { 535226633Sdim StringRef Name(SymbolicOp.AddSymbol.Name); 536226633Sdim MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name); 537226633Sdim Add = MCSymbolRefExpr::Create(Sym, *Ctx); 538226633Sdim } else { 539226633Sdim Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx); 540226633Sdim } 541226633Sdim } 542226633Sdim 543226633Sdim const MCExpr *Sub = NULL; 544226633Sdim if (SymbolicOp.SubtractSymbol.Present) { 545226633Sdim if (SymbolicOp.SubtractSymbol.Name) { 546226633Sdim StringRef Name(SymbolicOp.SubtractSymbol.Name); 547226633Sdim MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name); 548226633Sdim Sub = MCSymbolRefExpr::Create(Sym, *Ctx); 549226633Sdim } else { 550226633Sdim Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx); 551226633Sdim } 552226633Sdim } 553226633Sdim 554226633Sdim const MCExpr *Off = NULL; 555226633Sdim if (SymbolicOp.Value != 0) 556226633Sdim Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx); 557226633Sdim 558226633Sdim const MCExpr *Expr; 559226633Sdim if (Sub) { 560226633Sdim const MCExpr *LHS; 561226633Sdim if (Add) 562226633Sdim LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx); 563206124Srdivacky else 564226633Sdim LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx); 565226633Sdim if (Off != 0) 566226633Sdim Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx); 567226633Sdim else 568226633Sdim Expr = LHS; 569226633Sdim } else if (Add) { 570226633Sdim if (Off != 0) 571226633Sdim Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx); 572226633Sdim else 573226633Sdim Expr = Add; 574226633Sdim } else { 575226633Sdim if (Off != 0) 576226633Sdim Expr = Off; 577226633Sdim else 578226633Sdim Expr = MCConstantExpr::Create(0, *Ctx); 579206124Srdivacky } 580206124Srdivacky 581226633Sdim if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16) 582226633Sdim MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx))); 583226633Sdim else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16) 584226633Sdim MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx))); 585226633Sdim else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None) 586226633Sdim MI.addOperand(MCOperand::CreateExpr(Expr)); 587234353Sdim else 588234353Sdim llvm_unreachable("bad SymbolicOp.VariantKind"); 589212904Sdim 590226633Sdim return true; 591226633Sdim} 592226633Sdim 593226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being 594226633Sdim/// referenced by a load instruction with the base register that is the Pc. 595226633Sdim/// These can often be values in a literal pool near the Address of the 596226633Sdim/// instruction. The Address of the instruction and its immediate Value are 597226633Sdim/// used as a possible literal pool entry. The SymbolLookUp call back will 598239462Sdim/// return the name of a symbol referenced by the literal pool's entry if 599226633Sdim/// the referenced address is that of a symbol. Or it will return a pointer to 600226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry 601226633Sdim/// is an address into a section with 'C' string literals. 602226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value, 603234353Sdim const void *Decoder) { 604226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 605226633Sdim LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback(); 606226633Sdim if (SymbolLookUp) { 607226633Sdim void *DisInfo = Dis->getDisInfoBlock(); 608226633Sdim uint64_t ReferenceType; 609226633Sdim ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load; 610226633Sdim const char *ReferenceName; 611226633Sdim (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName); 612226633Sdim if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr || 613226633Sdim ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr) 614226633Sdim (*Dis->CommentStream) << "literal pool for: " << ReferenceName; 615206124Srdivacky } 616226633Sdim} 617206124Srdivacky 618226633Sdim// Thumb1 instructions don't have explicit S bits. Rather, they 619226633Sdim// implicitly set CPSR. Since it's not represented in the encoding, the 620226633Sdim// auto-generated decoder won't inject the CPSR operand. We need to fix 621226633Sdim// that as a post-pass. 622226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) { 623226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 624226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 625226633Sdim MCInst::iterator I = MI.begin(); 626226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 627226633Sdim if (I == MI.end()) break; 628226633Sdim if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) { 629226633Sdim if (i > 0 && OpInfo[i-1].isPredicate()) continue; 630226633Sdim MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); 631226633Sdim return; 632226633Sdim } 633226633Sdim } 634206124Srdivacky 635226633Sdim MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); 636226633Sdim} 637206124Srdivacky 638226633Sdim// Most Thumb instructions don't have explicit predicates in the 639226633Sdim// encoding, but rather get their predicates from IT context. We need 640226633Sdim// to fix up the predicate operands using this context information as a 641226633Sdim// post-pass. 642226633SdimMCDisassembler::DecodeStatus 643226633SdimThumbDisassembler::AddThumbPredicate(MCInst &MI) const { 644226633Sdim MCDisassembler::DecodeStatus S = Success; 645206124Srdivacky 646226633Sdim // A few instructions actually have predicates encoded in them. Don't 647226633Sdim // try to overwrite it if we're seeing one of those. 648226633Sdim switch (MI.getOpcode()) { 649226633Sdim case ARM::tBcc: 650226633Sdim case ARM::t2Bcc: 651226633Sdim case ARM::tCBZ: 652226633Sdim case ARM::tCBNZ: 653226633Sdim case ARM::tCPS: 654226633Sdim case ARM::t2CPS3p: 655226633Sdim case ARM::t2CPS2p: 656226633Sdim case ARM::t2CPS1p: 657226633Sdim case ARM::tMOVSr: 658226633Sdim case ARM::tSETEND: 659226633Sdim // Some instructions (mostly conditional branches) are not 660226633Sdim // allowed in IT blocks. 661239462Sdim if (ITBlock.instrInITBlock()) 662226633Sdim S = SoftFail; 663226633Sdim else 664226633Sdim return Success; 665226633Sdim break; 666226633Sdim case ARM::tB: 667226633Sdim case ARM::t2B: 668226633Sdim case ARM::t2TBB: 669226633Sdim case ARM::t2TBH: 670226633Sdim // Some instructions (mostly unconditional branches) can 671226633Sdim // only appears at the end of, or outside of, an IT. 672239462Sdim if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock()) 673226633Sdim S = SoftFail; 674226633Sdim break; 675226633Sdim default: 676226633Sdim break; 677226633Sdim } 678226633Sdim 679226633Sdim // If we're in an IT block, base the predicate on that. Otherwise, 680226633Sdim // assume a predicate of AL. 681226633Sdim unsigned CC; 682239462Sdim CC = ITBlock.getITCC(); 683239462Sdim if (CC == 0xF) 684226633Sdim CC = ARMCC::AL; 685239462Sdim if (ITBlock.instrInITBlock()) 686239462Sdim ITBlock.advanceITState(); 687226633Sdim 688226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 689226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 690226633Sdim MCInst::iterator I = MI.begin(); 691226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 692226633Sdim if (I == MI.end()) break; 693226633Sdim if (OpInfo[i].isPredicate()) { 694226633Sdim I = MI.insert(I, MCOperand::CreateImm(CC)); 695226633Sdim ++I; 696226633Sdim if (CC == ARMCC::AL) 697226633Sdim MI.insert(I, MCOperand::CreateReg(0)); 698226633Sdim else 699226633Sdim MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 700226633Sdim return S; 701226633Sdim } 702226633Sdim } 703226633Sdim 704226633Sdim I = MI.insert(I, MCOperand::CreateImm(CC)); 705226633Sdim ++I; 706226633Sdim if (CC == ARMCC::AL) 707226633Sdim MI.insert(I, MCOperand::CreateReg(0)); 708226633Sdim else 709226633Sdim MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 710226633Sdim 711226633Sdim return S; 712226633Sdim} 713226633Sdim 714226633Sdim// Thumb VFP instructions are a special case. Because we share their 715226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM 716226633Sdim// mode, the auto-generated decoder will give them an (incorrect) 717226633Sdim// predicate operand. We need to rewrite these operands based on the IT 718226633Sdim// context as a post-pass. 719226633Sdimvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const { 720226633Sdim unsigned CC; 721239462Sdim CC = ITBlock.getITCC(); 722239462Sdim if (ITBlock.instrInITBlock()) 723239462Sdim ITBlock.advanceITState(); 724226633Sdim 725226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 726226633Sdim MCInst::iterator I = MI.begin(); 727226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 728226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 729226633Sdim if (OpInfo[i].isPredicate() ) { 730226633Sdim I->setImm(CC); 731226633Sdim ++I; 732226633Sdim if (CC == ARMCC::AL) 733226633Sdim I->setReg(0); 734226633Sdim else 735226633Sdim I->setReg(ARM::CPSR); 736226633Sdim return; 737226633Sdim } 738226633Sdim } 739226633Sdim} 740226633Sdim 741226633SdimDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 742226633Sdim const MemoryObject &Region, 743226633Sdim uint64_t Address, 744226633Sdim raw_ostream &os, 745226633Sdim raw_ostream &cs) const { 746226633Sdim CommentStream = &cs; 747226633Sdim 748226633Sdim uint8_t bytes[4]; 749226633Sdim 750226633Sdim assert((STI.getFeatureBits() & ARM::ModeThumb) && 751226633Sdim "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!"); 752226633Sdim 753226633Sdim // We want to read exactly 2 bytes of data. 754226633Sdim if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) { 755226633Sdim Size = 0; 756226633Sdim return MCDisassembler::Fail; 757226633Sdim } 758226633Sdim 759226633Sdim uint16_t insn16 = (bytes[1] << 8) | bytes[0]; 760239462Sdim DecodeStatus result = decodeInstruction(DecoderTableThumb16, MI, insn16, 761239462Sdim Address, this, STI); 762226633Sdim if (result != MCDisassembler::Fail) { 763226633Sdim Size = 2; 764226633Sdim Check(result, AddThumbPredicate(MI)); 765226633Sdim return result; 766226633Sdim } 767226633Sdim 768226633Sdim MI.clear(); 769239462Sdim result = decodeInstruction(DecoderTableThumbSBit16, MI, insn16, 770239462Sdim Address, this, STI); 771226633Sdim if (result) { 772226633Sdim Size = 2; 773239462Sdim bool InITBlock = ITBlock.instrInITBlock(); 774226633Sdim Check(result, AddThumbPredicate(MI)); 775226633Sdim AddThumb1SBit(MI, InITBlock); 776226633Sdim return result; 777226633Sdim } 778226633Sdim 779226633Sdim MI.clear(); 780239462Sdim result = decodeInstruction(DecoderTableThumb216, MI, insn16, 781239462Sdim Address, this, STI); 782226633Sdim if (result != MCDisassembler::Fail) { 783226633Sdim Size = 2; 784226633Sdim 785226633Sdim // Nested IT blocks are UNPREDICTABLE. Must be checked before we add 786226633Sdim // the Thumb predicate. 787239462Sdim if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock()) 788226633Sdim result = MCDisassembler::SoftFail; 789226633Sdim 790226633Sdim Check(result, AddThumbPredicate(MI)); 791226633Sdim 792226633Sdim // If we find an IT instruction, we need to parse its condition 793226633Sdim // code and mask operands so that we can apply them correctly 794226633Sdim // to the subsequent instructions. 795226633Sdim if (MI.getOpcode() == ARM::t2IT) { 796226633Sdim 797239462Sdim unsigned Firstcond = MI.getOperand(0).getImm(); 798226633Sdim unsigned Mask = MI.getOperand(1).getImm(); 799239462Sdim ITBlock.setITState(Firstcond, Mask); 800226633Sdim } 801226633Sdim 802226633Sdim return result; 803226633Sdim } 804226633Sdim 805226633Sdim // We want to read exactly 4 bytes of data. 806226633Sdim if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { 807226633Sdim Size = 0; 808226633Sdim return MCDisassembler::Fail; 809226633Sdim } 810226633Sdim 811226633Sdim uint32_t insn32 = (bytes[3] << 8) | 812226633Sdim (bytes[2] << 0) | 813226633Sdim (bytes[1] << 24) | 814226633Sdim (bytes[0] << 16); 815226633Sdim MI.clear(); 816239462Sdim result = decodeInstruction(DecoderTableThumb32, MI, insn32, Address, 817239462Sdim this, STI); 818226633Sdim if (result != MCDisassembler::Fail) { 819226633Sdim Size = 4; 820239462Sdim bool InITBlock = ITBlock.instrInITBlock(); 821226633Sdim Check(result, AddThumbPredicate(MI)); 822226633Sdim AddThumb1SBit(MI, InITBlock); 823226633Sdim return result; 824226633Sdim } 825226633Sdim 826226633Sdim MI.clear(); 827239462Sdim result = decodeInstruction(DecoderTableThumb232, MI, insn32, Address, 828239462Sdim this, STI); 829226633Sdim if (result != MCDisassembler::Fail) { 830226633Sdim Size = 4; 831226633Sdim Check(result, AddThumbPredicate(MI)); 832226633Sdim return result; 833226633Sdim } 834226633Sdim 835226633Sdim MI.clear(); 836239462Sdim result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI); 837226633Sdim if (result != MCDisassembler::Fail) { 838226633Sdim Size = 4; 839226633Sdim UpdateThumbVFPPredicate(MI); 840226633Sdim return result; 841226633Sdim } 842226633Sdim 843226633Sdim MI.clear(); 844239462Sdim result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address, 845239462Sdim this, STI); 846226633Sdim if (result != MCDisassembler::Fail) { 847226633Sdim Size = 4; 848226633Sdim Check(result, AddThumbPredicate(MI)); 849226633Sdim return result; 850226633Sdim } 851226633Sdim 852239462Sdim if (fieldFromInstruction(insn32, 24, 8) == 0xF9) { 853226633Sdim MI.clear(); 854226633Sdim uint32_t NEONLdStInsn = insn32; 855226633Sdim NEONLdStInsn &= 0xF0FFFFFF; 856226633Sdim NEONLdStInsn |= 0x04000000; 857239462Sdim result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, 858239462Sdim Address, this, STI); 859226633Sdim if (result != MCDisassembler::Fail) { 860226633Sdim Size = 4; 861226633Sdim Check(result, AddThumbPredicate(MI)); 862226633Sdim return result; 863226633Sdim } 864226633Sdim } 865226633Sdim 866239462Sdim if (fieldFromInstruction(insn32, 24, 4) == 0xF) { 867226633Sdim MI.clear(); 868226633Sdim uint32_t NEONDataInsn = insn32; 869226633Sdim NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24 870226633Sdim NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 871226633Sdim NEONDataInsn |= 0x12000000; // Set bits 28 and 25 872239462Sdim result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn, 873239462Sdim Address, this, STI); 874226633Sdim if (result != MCDisassembler::Fail) { 875226633Sdim Size = 4; 876226633Sdim Check(result, AddThumbPredicate(MI)); 877226633Sdim return result; 878226633Sdim } 879226633Sdim } 880226633Sdim 881226633Sdim Size = 0; 882226633Sdim return MCDisassembler::Fail; 883226633Sdim} 884226633Sdim 885226633Sdim 886226633Sdimextern "C" void LLVMInitializeARMDisassembler() { 887226633Sdim TargetRegistry::RegisterMCDisassembler(TheARMTarget, 888226633Sdim createARMDisassembler); 889226633Sdim TargetRegistry::RegisterMCDisassembler(TheThumbTarget, 890226633Sdim createThumbDisassembler); 891226633Sdim} 892226633Sdim 893234353Sdimstatic const uint16_t GPRDecoderTable[] = { 894226633Sdim ARM::R0, ARM::R1, ARM::R2, ARM::R3, 895226633Sdim ARM::R4, ARM::R5, ARM::R6, ARM::R7, 896226633Sdim ARM::R8, ARM::R9, ARM::R10, ARM::R11, 897226633Sdim ARM::R12, ARM::SP, ARM::LR, ARM::PC 898226633Sdim}; 899226633Sdim 900234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 901226633Sdim uint64_t Address, const void *Decoder) { 902226633Sdim if (RegNo > 15) 903226633Sdim return MCDisassembler::Fail; 904226633Sdim 905226633Sdim unsigned Register = GPRDecoderTable[RegNo]; 906226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 907226633Sdim return MCDisassembler::Success; 908226633Sdim} 909226633Sdim 910226633Sdimstatic DecodeStatus 911234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo, 912226633Sdim uint64_t Address, const void *Decoder) { 913234353Sdim DecodeStatus S = MCDisassembler::Success; 914234353Sdim 915234353Sdim if (RegNo == 15) 916234353Sdim S = MCDisassembler::SoftFail; 917234353Sdim 918234353Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 919234353Sdim 920234353Sdim return S; 921226633Sdim} 922226633Sdim 923234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 924226633Sdim uint64_t Address, const void *Decoder) { 925226633Sdim if (RegNo > 7) 926226633Sdim return MCDisassembler::Fail; 927226633Sdim return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 928226633Sdim} 929226633Sdim 930234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 931226633Sdim uint64_t Address, const void *Decoder) { 932226633Sdim unsigned Register = 0; 933226633Sdim switch (RegNo) { 934226633Sdim case 0: 935226633Sdim Register = ARM::R0; 936206124Srdivacky break; 937226633Sdim case 1: 938226633Sdim Register = ARM::R1; 939226633Sdim break; 940226633Sdim case 2: 941226633Sdim Register = ARM::R2; 942226633Sdim break; 943206124Srdivacky case 3: 944226633Sdim Register = ARM::R3; 945206124Srdivacky break; 946226633Sdim case 9: 947226633Sdim Register = ARM::R9; 948226633Sdim break; 949226633Sdim case 12: 950226633Sdim Register = ARM::R12; 951226633Sdim break; 952206124Srdivacky default: 953226633Sdim return MCDisassembler::Fail; 954206124Srdivacky } 955226633Sdim 956226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 957226633Sdim return MCDisassembler::Success; 958226633Sdim} 959226633Sdim 960234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 961226633Sdim uint64_t Address, const void *Decoder) { 962226633Sdim if (RegNo == 13 || RegNo == 15) return MCDisassembler::Fail; 963226633Sdim return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 964226633Sdim} 965226633Sdim 966234353Sdimstatic const uint16_t SPRDecoderTable[] = { 967226633Sdim ARM::S0, ARM::S1, ARM::S2, ARM::S3, 968226633Sdim ARM::S4, ARM::S5, ARM::S6, ARM::S7, 969226633Sdim ARM::S8, ARM::S9, ARM::S10, ARM::S11, 970226633Sdim ARM::S12, ARM::S13, ARM::S14, ARM::S15, 971226633Sdim ARM::S16, ARM::S17, ARM::S18, ARM::S19, 972226633Sdim ARM::S20, ARM::S21, ARM::S22, ARM::S23, 973226633Sdim ARM::S24, ARM::S25, ARM::S26, ARM::S27, 974226633Sdim ARM::S28, ARM::S29, ARM::S30, ARM::S31 975226633Sdim}; 976226633Sdim 977234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 978226633Sdim uint64_t Address, const void *Decoder) { 979226633Sdim if (RegNo > 31) 980226633Sdim return MCDisassembler::Fail; 981226633Sdim 982226633Sdim unsigned Register = SPRDecoderTable[RegNo]; 983226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 984226633Sdim return MCDisassembler::Success; 985226633Sdim} 986226633Sdim 987234353Sdimstatic const uint16_t DPRDecoderTable[] = { 988226633Sdim ARM::D0, ARM::D1, ARM::D2, ARM::D3, 989226633Sdim ARM::D4, ARM::D5, ARM::D6, ARM::D7, 990226633Sdim ARM::D8, ARM::D9, ARM::D10, ARM::D11, 991226633Sdim ARM::D12, ARM::D13, ARM::D14, ARM::D15, 992226633Sdim ARM::D16, ARM::D17, ARM::D18, ARM::D19, 993226633Sdim ARM::D20, ARM::D21, ARM::D22, ARM::D23, 994226633Sdim ARM::D24, ARM::D25, ARM::D26, ARM::D27, 995226633Sdim ARM::D28, ARM::D29, ARM::D30, ARM::D31 996226633Sdim}; 997226633Sdim 998234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 999226633Sdim uint64_t Address, const void *Decoder) { 1000226633Sdim if (RegNo > 31) 1001226633Sdim return MCDisassembler::Fail; 1002226633Sdim 1003226633Sdim unsigned Register = DPRDecoderTable[RegNo]; 1004226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1005226633Sdim return MCDisassembler::Success; 1006226633Sdim} 1007226633Sdim 1008234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 1009226633Sdim uint64_t Address, const void *Decoder) { 1010226633Sdim if (RegNo > 7) 1011226633Sdim return MCDisassembler::Fail; 1012226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 1013226633Sdim} 1014226633Sdim 1015226633Sdimstatic DecodeStatus 1016234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo, 1017226633Sdim uint64_t Address, const void *Decoder) { 1018226633Sdim if (RegNo > 15) 1019226633Sdim return MCDisassembler::Fail; 1020226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 1021226633Sdim} 1022226633Sdim 1023234353Sdimstatic const uint16_t QPRDecoderTable[] = { 1024226633Sdim ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3, 1025226633Sdim ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7, 1026226633Sdim ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11, 1027226633Sdim ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15 1028226633Sdim}; 1029226633Sdim 1030226633Sdim 1031234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 1032226633Sdim uint64_t Address, const void *Decoder) { 1033226633Sdim if (RegNo > 31) 1034226633Sdim return MCDisassembler::Fail; 1035226633Sdim RegNo >>= 1; 1036226633Sdim 1037226633Sdim unsigned Register = QPRDecoderTable[RegNo]; 1038226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1039226633Sdim return MCDisassembler::Success; 1040226633Sdim} 1041226633Sdim 1042234353Sdimstatic const uint16_t DPairDecoderTable[] = { 1043234353Sdim ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6, 1044234353Sdim ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12, 1045234353Sdim ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18, 1046234353Sdim ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24, 1047234353Sdim ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30, 1048234353Sdim ARM::Q15 1049234353Sdim}; 1050234353Sdim 1051234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 1052234353Sdim uint64_t Address, const void *Decoder) { 1053234353Sdim if (RegNo > 30) 1054234353Sdim return MCDisassembler::Fail; 1055234353Sdim 1056234353Sdim unsigned Register = DPairDecoderTable[RegNo]; 1057234353Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1058234353Sdim return MCDisassembler::Success; 1059234353Sdim} 1060234353Sdim 1061234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = { 1062234353Sdim ARM::D0_D2, ARM::D1_D3, ARM::D2_D4, ARM::D3_D5, 1063234353Sdim ARM::D4_D6, ARM::D5_D7, ARM::D6_D8, ARM::D7_D9, 1064234353Sdim ARM::D8_D10, ARM::D9_D11, ARM::D10_D12, ARM::D11_D13, 1065234353Sdim ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17, 1066234353Sdim ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21, 1067234353Sdim ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25, 1068234353Sdim ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29, 1069234353Sdim ARM::D28_D30, ARM::D29_D31 1070234353Sdim}; 1071234353Sdim 1072234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 1073234353Sdim unsigned RegNo, 1074234353Sdim uint64_t Address, 1075234353Sdim const void *Decoder) { 1076234353Sdim if (RegNo > 29) 1077234353Sdim return MCDisassembler::Fail; 1078234353Sdim 1079234353Sdim unsigned Register = DPairSpacedDecoderTable[RegNo]; 1080234353Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1081234353Sdim return MCDisassembler::Success; 1082234353Sdim} 1083234353Sdim 1084234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 1085226633Sdim uint64_t Address, const void *Decoder) { 1086226633Sdim if (Val == 0xF) return MCDisassembler::Fail; 1087226633Sdim // AL predicate is not allowed on Thumb1 branches. 1088226633Sdim if (Inst.getOpcode() == ARM::tBcc && Val == 0xE) 1089226633Sdim return MCDisassembler::Fail; 1090226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 1091226633Sdim if (Val == ARMCC::AL) { 1092226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1093226633Sdim } else 1094226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1095226633Sdim return MCDisassembler::Success; 1096226633Sdim} 1097226633Sdim 1098234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 1099226633Sdim uint64_t Address, const void *Decoder) { 1100226633Sdim if (Val) 1101226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1102226633Sdim else 1103226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1104226633Sdim return MCDisassembler::Success; 1105226633Sdim} 1106226633Sdim 1107234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, 1108226633Sdim uint64_t Address, const void *Decoder) { 1109226633Sdim uint32_t imm = Val & 0xFF; 1110226633Sdim uint32_t rot = (Val & 0xF00) >> 7; 1111226633Sdim uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F)); 1112226633Sdim Inst.addOperand(MCOperand::CreateImm(rot_imm)); 1113226633Sdim return MCDisassembler::Success; 1114226633Sdim} 1115226633Sdim 1116234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val, 1117226633Sdim uint64_t Address, const void *Decoder) { 1118226633Sdim DecodeStatus S = MCDisassembler::Success; 1119226633Sdim 1120239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1121239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1122239462Sdim unsigned imm = fieldFromInstruction(Val, 7, 5); 1123226633Sdim 1124226633Sdim // Register-immediate 1125226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1126226633Sdim return MCDisassembler::Fail; 1127226633Sdim 1128226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1129226633Sdim switch (type) { 1130226633Sdim case 0: 1131226633Sdim Shift = ARM_AM::lsl; 1132226633Sdim break; 1133226633Sdim case 1: 1134226633Sdim Shift = ARM_AM::lsr; 1135226633Sdim break; 1136226633Sdim case 2: 1137226633Sdim Shift = ARM_AM::asr; 1138226633Sdim break; 1139226633Sdim case 3: 1140226633Sdim Shift = ARM_AM::ror; 1141226633Sdim break; 1142206124Srdivacky } 1143206124Srdivacky 1144226633Sdim if (Shift == ARM_AM::ror && imm == 0) 1145226633Sdim Shift = ARM_AM::rrx; 1146226633Sdim 1147226633Sdim unsigned Op = Shift | (imm << 3); 1148226633Sdim Inst.addOperand(MCOperand::CreateImm(Op)); 1149226633Sdim 1150226633Sdim return S; 1151226633Sdim} 1152226633Sdim 1153234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val, 1154226633Sdim uint64_t Address, const void *Decoder) { 1155226633Sdim DecodeStatus S = MCDisassembler::Success; 1156226633Sdim 1157239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1158239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1159239462Sdim unsigned Rs = fieldFromInstruction(Val, 8, 4); 1160226633Sdim 1161226633Sdim // Register-register 1162226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1163226633Sdim return MCDisassembler::Fail; 1164226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder))) 1165226633Sdim return MCDisassembler::Fail; 1166226633Sdim 1167226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1168226633Sdim switch (type) { 1169226633Sdim case 0: 1170226633Sdim Shift = ARM_AM::lsl; 1171206124Srdivacky break; 1172226633Sdim case 1: 1173226633Sdim Shift = ARM_AM::lsr; 1174206124Srdivacky break; 1175226633Sdim case 2: 1176226633Sdim Shift = ARM_AM::asr; 1177206124Srdivacky break; 1178226633Sdim case 3: 1179226633Sdim Shift = ARM_AM::ror; 1180226633Sdim break; 1181226633Sdim } 1182226633Sdim 1183226633Sdim Inst.addOperand(MCOperand::CreateImm(Shift)); 1184226633Sdim 1185226633Sdim return S; 1186226633Sdim} 1187226633Sdim 1188234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 1189226633Sdim uint64_t Address, const void *Decoder) { 1190226633Sdim DecodeStatus S = MCDisassembler::Success; 1191226633Sdim 1192226633Sdim bool writebackLoad = false; 1193226633Sdim unsigned writebackReg = 0; 1194226633Sdim switch (Inst.getOpcode()) { 1195206124Srdivacky default: 1196226633Sdim break; 1197226633Sdim case ARM::LDMIA_UPD: 1198226633Sdim case ARM::LDMDB_UPD: 1199226633Sdim case ARM::LDMIB_UPD: 1200226633Sdim case ARM::LDMDA_UPD: 1201226633Sdim case ARM::t2LDMIA_UPD: 1202226633Sdim case ARM::t2LDMDB_UPD: 1203226633Sdim writebackLoad = true; 1204226633Sdim writebackReg = Inst.getOperand(0).getReg(); 1205226633Sdim break; 1206226633Sdim } 1207226633Sdim 1208226633Sdim // Empty register lists are not allowed. 1209226633Sdim if (CountPopulation_32(Val) == 0) return MCDisassembler::Fail; 1210226633Sdim for (unsigned i = 0; i < 16; ++i) { 1211226633Sdim if (Val & (1 << i)) { 1212226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder))) 1213226633Sdim return MCDisassembler::Fail; 1214226633Sdim // Writeback not allowed if Rn is in the target list. 1215226633Sdim if (writebackLoad && writebackReg == Inst.end()[-1].getReg()) 1216226633Sdim Check(S, MCDisassembler::SoftFail); 1217206124Srdivacky } 1218206124Srdivacky } 1219206124Srdivacky 1220226633Sdim return S; 1221226633Sdim} 1222226633Sdim 1223234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 1224226633Sdim uint64_t Address, const void *Decoder) { 1225226633Sdim DecodeStatus S = MCDisassembler::Success; 1226226633Sdim 1227239462Sdim unsigned Vd = fieldFromInstruction(Val, 8, 5); 1228239462Sdim unsigned regs = fieldFromInstruction(Val, 0, 8); 1229226633Sdim 1230226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder))) 1231226633Sdim return MCDisassembler::Fail; 1232226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1233226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1234226633Sdim return MCDisassembler::Fail; 1235226633Sdim } 1236226633Sdim 1237226633Sdim return S; 1238226633Sdim} 1239226633Sdim 1240234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 1241226633Sdim uint64_t Address, const void *Decoder) { 1242226633Sdim DecodeStatus S = MCDisassembler::Success; 1243226633Sdim 1244239462Sdim unsigned Vd = fieldFromInstruction(Val, 8, 5); 1245239462Sdim unsigned regs = fieldFromInstruction(Val, 0, 8); 1246226633Sdim 1247239462Sdim regs = regs >> 1; 1248239462Sdim 1249226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 1250226633Sdim return MCDisassembler::Fail; 1251226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1252226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1253226633Sdim return MCDisassembler::Fail; 1254226633Sdim } 1255226633Sdim 1256226633Sdim return S; 1257226633Sdim} 1258226633Sdim 1259234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val, 1260226633Sdim uint64_t Address, const void *Decoder) { 1261226633Sdim // This operand encodes a mask of contiguous zeros between a specified MSB 1262226633Sdim // and LSB. To decode it, we create the mask of all bits MSB-and-lower, 1263226633Sdim // the mask of all bits LSB-and-lower, and then xor them to create 1264226633Sdim // the mask of that's all ones on [msb, lsb]. Finally we not it to 1265226633Sdim // create the final mask. 1266239462Sdim unsigned msb = fieldFromInstruction(Val, 5, 5); 1267239462Sdim unsigned lsb = fieldFromInstruction(Val, 0, 5); 1268226633Sdim 1269226633Sdim DecodeStatus S = MCDisassembler::Success; 1270249423Sdim if (lsb > msb) { 1271249423Sdim Check(S, MCDisassembler::SoftFail); 1272249423Sdim // The check above will cause the warning for the "potentially undefined 1273249423Sdim // instruction encoding" but we can't build a bad MCOperand value here 1274249423Sdim // with a lsb > msb or else printing the MCInst will cause a crash. 1275249423Sdim lsb = msb; 1276249423Sdim } 1277226633Sdim 1278226633Sdim uint32_t msb_mask = 0xFFFFFFFF; 1279226633Sdim if (msb != 31) msb_mask = (1U << (msb+1)) - 1; 1280226633Sdim uint32_t lsb_mask = (1U << lsb) - 1; 1281226633Sdim 1282226633Sdim Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask))); 1283226633Sdim return S; 1284226633Sdim} 1285226633Sdim 1286234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 1287226633Sdim uint64_t Address, const void *Decoder) { 1288226633Sdim DecodeStatus S = MCDisassembler::Success; 1289226633Sdim 1290239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1291239462Sdim unsigned CRd = fieldFromInstruction(Insn, 12, 4); 1292239462Sdim unsigned coproc = fieldFromInstruction(Insn, 8, 4); 1293239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 1294239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1295239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 1296226633Sdim 1297226633Sdim switch (Inst.getOpcode()) { 1298226633Sdim case ARM::LDC_OFFSET: 1299226633Sdim case ARM::LDC_PRE: 1300226633Sdim case ARM::LDC_POST: 1301226633Sdim case ARM::LDC_OPTION: 1302226633Sdim case ARM::LDCL_OFFSET: 1303226633Sdim case ARM::LDCL_PRE: 1304226633Sdim case ARM::LDCL_POST: 1305226633Sdim case ARM::LDCL_OPTION: 1306226633Sdim case ARM::STC_OFFSET: 1307226633Sdim case ARM::STC_PRE: 1308226633Sdim case ARM::STC_POST: 1309226633Sdim case ARM::STC_OPTION: 1310226633Sdim case ARM::STCL_OFFSET: 1311226633Sdim case ARM::STCL_PRE: 1312226633Sdim case ARM::STCL_POST: 1313226633Sdim case ARM::STCL_OPTION: 1314226633Sdim case ARM::t2LDC_OFFSET: 1315226633Sdim case ARM::t2LDC_PRE: 1316226633Sdim case ARM::t2LDC_POST: 1317226633Sdim case ARM::t2LDC_OPTION: 1318226633Sdim case ARM::t2LDCL_OFFSET: 1319226633Sdim case ARM::t2LDCL_PRE: 1320226633Sdim case ARM::t2LDCL_POST: 1321226633Sdim case ARM::t2LDCL_OPTION: 1322226633Sdim case ARM::t2STC_OFFSET: 1323226633Sdim case ARM::t2STC_PRE: 1324226633Sdim case ARM::t2STC_POST: 1325226633Sdim case ARM::t2STC_OPTION: 1326226633Sdim case ARM::t2STCL_OFFSET: 1327226633Sdim case ARM::t2STCL_PRE: 1328226633Sdim case ARM::t2STCL_POST: 1329226633Sdim case ARM::t2STCL_OPTION: 1330226633Sdim if (coproc == 0xA || coproc == 0xB) 1331226633Sdim return MCDisassembler::Fail; 1332206124Srdivacky break; 1333226633Sdim default: 1334226633Sdim break; 1335226633Sdim } 1336226633Sdim 1337226633Sdim Inst.addOperand(MCOperand::CreateImm(coproc)); 1338226633Sdim Inst.addOperand(MCOperand::CreateImm(CRd)); 1339226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1340226633Sdim return MCDisassembler::Fail; 1341226633Sdim 1342226633Sdim switch (Inst.getOpcode()) { 1343226633Sdim case ARM::t2LDC2_OFFSET: 1344226633Sdim case ARM::t2LDC2L_OFFSET: 1345226633Sdim case ARM::t2LDC2_PRE: 1346226633Sdim case ARM::t2LDC2L_PRE: 1347226633Sdim case ARM::t2STC2_OFFSET: 1348226633Sdim case ARM::t2STC2L_OFFSET: 1349226633Sdim case ARM::t2STC2_PRE: 1350226633Sdim case ARM::t2STC2L_PRE: 1351226633Sdim case ARM::LDC2_OFFSET: 1352226633Sdim case ARM::LDC2L_OFFSET: 1353226633Sdim case ARM::LDC2_PRE: 1354226633Sdim case ARM::LDC2L_PRE: 1355226633Sdim case ARM::STC2_OFFSET: 1356226633Sdim case ARM::STC2L_OFFSET: 1357226633Sdim case ARM::STC2_PRE: 1358226633Sdim case ARM::STC2L_PRE: 1359226633Sdim case ARM::t2LDC_OFFSET: 1360226633Sdim case ARM::t2LDCL_OFFSET: 1361226633Sdim case ARM::t2LDC_PRE: 1362226633Sdim case ARM::t2LDCL_PRE: 1363226633Sdim case ARM::t2STC_OFFSET: 1364226633Sdim case ARM::t2STCL_OFFSET: 1365226633Sdim case ARM::t2STC_PRE: 1366226633Sdim case ARM::t2STCL_PRE: 1367226633Sdim case ARM::LDC_OFFSET: 1368226633Sdim case ARM::LDCL_OFFSET: 1369226633Sdim case ARM::LDC_PRE: 1370226633Sdim case ARM::LDCL_PRE: 1371226633Sdim case ARM::STC_OFFSET: 1372226633Sdim case ARM::STCL_OFFSET: 1373226633Sdim case ARM::STC_PRE: 1374226633Sdim case ARM::STCL_PRE: 1375226633Sdim imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm); 1376226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1377226633Sdim break; 1378226633Sdim case ARM::t2LDC2_POST: 1379226633Sdim case ARM::t2LDC2L_POST: 1380226633Sdim case ARM::t2STC2_POST: 1381226633Sdim case ARM::t2STC2L_POST: 1382226633Sdim case ARM::LDC2_POST: 1383226633Sdim case ARM::LDC2L_POST: 1384226633Sdim case ARM::STC2_POST: 1385226633Sdim case ARM::STC2L_POST: 1386226633Sdim case ARM::t2LDC_POST: 1387226633Sdim case ARM::t2LDCL_POST: 1388226633Sdim case ARM::t2STC_POST: 1389226633Sdim case ARM::t2STCL_POST: 1390226633Sdim case ARM::LDC_POST: 1391226633Sdim case ARM::LDCL_POST: 1392226633Sdim case ARM::STC_POST: 1393226633Sdim case ARM::STCL_POST: 1394226633Sdim imm |= U << 8; 1395226633Sdim // fall through. 1396226633Sdim default: 1397226633Sdim // The 'option' variant doesn't encode 'U' in the immediate since 1398226633Sdim // the immediate is unsigned [0,255]. 1399226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1400226633Sdim break; 1401226633Sdim } 1402226633Sdim 1403226633Sdim switch (Inst.getOpcode()) { 1404226633Sdim case ARM::LDC_OFFSET: 1405226633Sdim case ARM::LDC_PRE: 1406226633Sdim case ARM::LDC_POST: 1407226633Sdim case ARM::LDC_OPTION: 1408226633Sdim case ARM::LDCL_OFFSET: 1409226633Sdim case ARM::LDCL_PRE: 1410226633Sdim case ARM::LDCL_POST: 1411226633Sdim case ARM::LDCL_OPTION: 1412226633Sdim case ARM::STC_OFFSET: 1413226633Sdim case ARM::STC_PRE: 1414226633Sdim case ARM::STC_POST: 1415226633Sdim case ARM::STC_OPTION: 1416226633Sdim case ARM::STCL_OFFSET: 1417226633Sdim case ARM::STCL_PRE: 1418226633Sdim case ARM::STCL_POST: 1419226633Sdim case ARM::STCL_OPTION: 1420226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1421226633Sdim return MCDisassembler::Fail; 1422226633Sdim break; 1423226633Sdim default: 1424226633Sdim break; 1425226633Sdim } 1426226633Sdim 1427226633Sdim return S; 1428226633Sdim} 1429226633Sdim 1430226633Sdimstatic DecodeStatus 1431234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, 1432226633Sdim uint64_t Address, const void *Decoder) { 1433226633Sdim DecodeStatus S = MCDisassembler::Success; 1434226633Sdim 1435239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1436239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 1437239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1438239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 1439239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1440239462Sdim unsigned reg = fieldFromInstruction(Insn, 25, 1); 1441239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 1442239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 1443226633Sdim 1444226633Sdim // On stores, the writeback operand precedes Rt. 1445226633Sdim switch (Inst.getOpcode()) { 1446226633Sdim case ARM::STR_POST_IMM: 1447226633Sdim case ARM::STR_POST_REG: 1448226633Sdim case ARM::STRB_POST_IMM: 1449226633Sdim case ARM::STRB_POST_REG: 1450226633Sdim case ARM::STRT_POST_REG: 1451226633Sdim case ARM::STRT_POST_IMM: 1452226633Sdim case ARM::STRBT_POST_REG: 1453226633Sdim case ARM::STRBT_POST_IMM: 1454226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1455226633Sdim return MCDisassembler::Fail; 1456226633Sdim break; 1457226633Sdim default: 1458226633Sdim break; 1459226633Sdim } 1460226633Sdim 1461226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1462226633Sdim return MCDisassembler::Fail; 1463226633Sdim 1464226633Sdim // On loads, the writeback operand comes after Rt. 1465226633Sdim switch (Inst.getOpcode()) { 1466226633Sdim case ARM::LDR_POST_IMM: 1467226633Sdim case ARM::LDR_POST_REG: 1468226633Sdim case ARM::LDRB_POST_IMM: 1469226633Sdim case ARM::LDRB_POST_REG: 1470226633Sdim case ARM::LDRBT_POST_REG: 1471226633Sdim case ARM::LDRBT_POST_IMM: 1472226633Sdim case ARM::LDRT_POST_REG: 1473226633Sdim case ARM::LDRT_POST_IMM: 1474226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1475226633Sdim return MCDisassembler::Fail; 1476226633Sdim break; 1477226633Sdim default: 1478226633Sdim break; 1479226633Sdim } 1480226633Sdim 1481226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1482226633Sdim return MCDisassembler::Fail; 1483226633Sdim 1484226633Sdim ARM_AM::AddrOpc Op = ARM_AM::add; 1485239462Sdim if (!fieldFromInstruction(Insn, 23, 1)) 1486226633Sdim Op = ARM_AM::sub; 1487226633Sdim 1488226633Sdim bool writeback = (P == 0) || (W == 1); 1489226633Sdim unsigned idx_mode = 0; 1490226633Sdim if (P && writeback) 1491226633Sdim idx_mode = ARMII::IndexModePre; 1492226633Sdim else if (!P && writeback) 1493226633Sdim idx_mode = ARMII::IndexModePost; 1494226633Sdim 1495226633Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1496226633Sdim S = MCDisassembler::SoftFail; // UNPREDICTABLE 1497226633Sdim 1498226633Sdim if (reg) { 1499226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1500226633Sdim return MCDisassembler::Fail; 1501226633Sdim ARM_AM::ShiftOpc Opc = ARM_AM::lsl; 1502239462Sdim switch( fieldFromInstruction(Insn, 5, 2)) { 1503226633Sdim case 0: 1504226633Sdim Opc = ARM_AM::lsl; 1505226633Sdim break; 1506226633Sdim case 1: 1507226633Sdim Opc = ARM_AM::lsr; 1508226633Sdim break; 1509226633Sdim case 2: 1510226633Sdim Opc = ARM_AM::asr; 1511226633Sdim break; 1512226633Sdim case 3: 1513226633Sdim Opc = ARM_AM::ror; 1514226633Sdim break; 1515206124Srdivacky default: 1516226633Sdim return MCDisassembler::Fail; 1517226633Sdim } 1518239462Sdim unsigned amt = fieldFromInstruction(Insn, 7, 5); 1519243830Sdim if (Opc == ARM_AM::ror && amt == 0) 1520243830Sdim Opc = ARM_AM::rrx; 1521226633Sdim unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode); 1522226633Sdim 1523226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1524226633Sdim } else { 1525226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1526226633Sdim unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode); 1527226633Sdim Inst.addOperand(MCOperand::CreateImm(tmp)); 1528226633Sdim } 1529226633Sdim 1530226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1531226633Sdim return MCDisassembler::Fail; 1532226633Sdim 1533226633Sdim return S; 1534226633Sdim} 1535226633Sdim 1536234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val, 1537226633Sdim uint64_t Address, const void *Decoder) { 1538226633Sdim DecodeStatus S = MCDisassembler::Success; 1539226633Sdim 1540239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 1541239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1542239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1543239462Sdim unsigned imm = fieldFromInstruction(Val, 7, 5); 1544239462Sdim unsigned U = fieldFromInstruction(Val, 12, 1); 1545226633Sdim 1546226633Sdim ARM_AM::ShiftOpc ShOp = ARM_AM::lsl; 1547226633Sdim switch (type) { 1548226633Sdim case 0: 1549226633Sdim ShOp = ARM_AM::lsl; 1550206124Srdivacky break; 1551226633Sdim case 1: 1552226633Sdim ShOp = ARM_AM::lsr; 1553226633Sdim break; 1554226633Sdim case 2: 1555226633Sdim ShOp = ARM_AM::asr; 1556226633Sdim break; 1557226633Sdim case 3: 1558226633Sdim ShOp = ARM_AM::ror; 1559226633Sdim break; 1560226633Sdim } 1561226633Sdim 1562243830Sdim if (ShOp == ARM_AM::ror && imm == 0) 1563243830Sdim ShOp = ARM_AM::rrx; 1564243830Sdim 1565226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1566226633Sdim return MCDisassembler::Fail; 1567226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1568226633Sdim return MCDisassembler::Fail; 1569226633Sdim unsigned shift; 1570226633Sdim if (U) 1571226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp); 1572226633Sdim else 1573226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp); 1574226633Sdim Inst.addOperand(MCOperand::CreateImm(shift)); 1575226633Sdim 1576226633Sdim return S; 1577226633Sdim} 1578226633Sdim 1579226633Sdimstatic DecodeStatus 1580234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn, 1581226633Sdim uint64_t Address, const void *Decoder) { 1582226633Sdim DecodeStatus S = MCDisassembler::Success; 1583226633Sdim 1584239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 1585239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1586239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1587239462Sdim unsigned type = fieldFromInstruction(Insn, 22, 1); 1588239462Sdim unsigned imm = fieldFromInstruction(Insn, 8, 4); 1589239462Sdim unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8; 1590239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1591239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 1592239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 1593234353Sdim unsigned Rt2 = Rt + 1; 1594226633Sdim 1595226633Sdim bool writeback = (W == 1) | (P == 0); 1596226633Sdim 1597226633Sdim // For {LD,ST}RD, Rt must be even, else undefined. 1598226633Sdim switch (Inst.getOpcode()) { 1599226633Sdim case ARM::STRD: 1600226633Sdim case ARM::STRD_PRE: 1601226633Sdim case ARM::STRD_POST: 1602226633Sdim case ARM::LDRD: 1603226633Sdim case ARM::LDRD_PRE: 1604226633Sdim case ARM::LDRD_POST: 1605234353Sdim if (Rt & 0x1) S = MCDisassembler::SoftFail; 1606226633Sdim break; 1607226633Sdim default: 1608226633Sdim break; 1609226633Sdim } 1610234353Sdim switch (Inst.getOpcode()) { 1611234353Sdim case ARM::STRD: 1612234353Sdim case ARM::STRD_PRE: 1613234353Sdim case ARM::STRD_POST: 1614234353Sdim if (P == 0 && W == 1) 1615234353Sdim S = MCDisassembler::SoftFail; 1616234353Sdim 1617234353Sdim if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2)) 1618234353Sdim S = MCDisassembler::SoftFail; 1619234353Sdim if (type && Rm == 15) 1620234353Sdim S = MCDisassembler::SoftFail; 1621234353Sdim if (Rt2 == 15) 1622234353Sdim S = MCDisassembler::SoftFail; 1623239462Sdim if (!type && fieldFromInstruction(Insn, 8, 4)) 1624234353Sdim S = MCDisassembler::SoftFail; 1625234353Sdim break; 1626234353Sdim case ARM::STRH: 1627234353Sdim case ARM::STRH_PRE: 1628234353Sdim case ARM::STRH_POST: 1629234353Sdim if (Rt == 15) 1630234353Sdim S = MCDisassembler::SoftFail; 1631234353Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1632234353Sdim S = MCDisassembler::SoftFail; 1633234353Sdim if (!type && Rm == 15) 1634234353Sdim S = MCDisassembler::SoftFail; 1635234353Sdim break; 1636234353Sdim case ARM::LDRD: 1637234353Sdim case ARM::LDRD_PRE: 1638234353Sdim case ARM::LDRD_POST: 1639234353Sdim if (type && Rn == 15){ 1640234353Sdim if (Rt2 == 15) 1641234353Sdim S = MCDisassembler::SoftFail; 1642234353Sdim break; 1643234353Sdim } 1644234353Sdim if (P == 0 && W == 1) 1645234353Sdim S = MCDisassembler::SoftFail; 1646234353Sdim if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2)) 1647234353Sdim S = MCDisassembler::SoftFail; 1648234353Sdim if (!type && writeback && Rn == 15) 1649234353Sdim S = MCDisassembler::SoftFail; 1650234353Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 1651234353Sdim S = MCDisassembler::SoftFail; 1652234353Sdim break; 1653234353Sdim case ARM::LDRH: 1654234353Sdim case ARM::LDRH_PRE: 1655234353Sdim case ARM::LDRH_POST: 1656234353Sdim if (type && Rn == 15){ 1657234353Sdim if (Rt == 15) 1658234353Sdim S = MCDisassembler::SoftFail; 1659234353Sdim break; 1660234353Sdim } 1661234353Sdim if (Rt == 15) 1662234353Sdim S = MCDisassembler::SoftFail; 1663234353Sdim if (!type && Rm == 15) 1664234353Sdim S = MCDisassembler::SoftFail; 1665234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 1666234353Sdim S = MCDisassembler::SoftFail; 1667234353Sdim break; 1668234353Sdim case ARM::LDRSH: 1669234353Sdim case ARM::LDRSH_PRE: 1670234353Sdim case ARM::LDRSH_POST: 1671234353Sdim case ARM::LDRSB: 1672234353Sdim case ARM::LDRSB_PRE: 1673234353Sdim case ARM::LDRSB_POST: 1674234353Sdim if (type && Rn == 15){ 1675234353Sdim if (Rt == 15) 1676234353Sdim S = MCDisassembler::SoftFail; 1677234353Sdim break; 1678234353Sdim } 1679234353Sdim if (type && (Rt == 15 || (writeback && Rn == Rt))) 1680234353Sdim S = MCDisassembler::SoftFail; 1681234353Sdim if (!type && (Rt == 15 || Rm == 15)) 1682234353Sdim S = MCDisassembler::SoftFail; 1683234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 1684234353Sdim S = MCDisassembler::SoftFail; 1685234353Sdim break; 1686234353Sdim default: 1687234353Sdim break; 1688234353Sdim } 1689226633Sdim 1690226633Sdim if (writeback) { // Writeback 1691226633Sdim if (P) 1692226633Sdim U |= ARMII::IndexModePre << 9; 1693226633Sdim else 1694226633Sdim U |= ARMII::IndexModePost << 9; 1695226633Sdim 1696226633Sdim // On stores, the writeback operand precedes Rt. 1697226633Sdim switch (Inst.getOpcode()) { 1698226633Sdim case ARM::STRD: 1699226633Sdim case ARM::STRD_PRE: 1700226633Sdim case ARM::STRD_POST: 1701226633Sdim case ARM::STRH: 1702226633Sdim case ARM::STRH_PRE: 1703226633Sdim case ARM::STRH_POST: 1704226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1705226633Sdim return MCDisassembler::Fail; 1706226633Sdim break; 1707226633Sdim default: 1708226633Sdim break; 1709226633Sdim } 1710226633Sdim } 1711226633Sdim 1712226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1713226633Sdim return MCDisassembler::Fail; 1714226633Sdim switch (Inst.getOpcode()) { 1715226633Sdim case ARM::STRD: 1716226633Sdim case ARM::STRD_PRE: 1717226633Sdim case ARM::STRD_POST: 1718226633Sdim case ARM::LDRD: 1719226633Sdim case ARM::LDRD_PRE: 1720226633Sdim case ARM::LDRD_POST: 1721226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 1722226633Sdim return MCDisassembler::Fail; 1723226633Sdim break; 1724226633Sdim default: 1725226633Sdim break; 1726226633Sdim } 1727226633Sdim 1728226633Sdim if (writeback) { 1729226633Sdim // On loads, the writeback operand comes after Rt. 1730226633Sdim switch (Inst.getOpcode()) { 1731226633Sdim case ARM::LDRD: 1732226633Sdim case ARM::LDRD_PRE: 1733226633Sdim case ARM::LDRD_POST: 1734226633Sdim case ARM::LDRH: 1735226633Sdim case ARM::LDRH_PRE: 1736226633Sdim case ARM::LDRH_POST: 1737226633Sdim case ARM::LDRSH: 1738226633Sdim case ARM::LDRSH_PRE: 1739226633Sdim case ARM::LDRSH_POST: 1740226633Sdim case ARM::LDRSB: 1741226633Sdim case ARM::LDRSB_PRE: 1742226633Sdim case ARM::LDRSB_POST: 1743226633Sdim case ARM::LDRHTr: 1744226633Sdim case ARM::LDRSBTr: 1745226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1746226633Sdim return MCDisassembler::Fail; 1747226633Sdim break; 1748226633Sdim default: 1749226633Sdim break; 1750226633Sdim } 1751226633Sdim } 1752226633Sdim 1753226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1754226633Sdim return MCDisassembler::Fail; 1755226633Sdim 1756226633Sdim if (type) { 1757226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1758226633Sdim Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm)); 1759226633Sdim } else { 1760226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1761226633Sdim return MCDisassembler::Fail; 1762226633Sdim Inst.addOperand(MCOperand::CreateImm(U)); 1763226633Sdim } 1764226633Sdim 1765226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1766226633Sdim return MCDisassembler::Fail; 1767226633Sdim 1768226633Sdim return S; 1769226633Sdim} 1770226633Sdim 1771234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn, 1772226633Sdim uint64_t Address, const void *Decoder) { 1773226633Sdim DecodeStatus S = MCDisassembler::Success; 1774226633Sdim 1775239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1776239462Sdim unsigned mode = fieldFromInstruction(Insn, 23, 2); 1777226633Sdim 1778226633Sdim switch (mode) { 1779226633Sdim case 0: 1780226633Sdim mode = ARM_AM::da; 1781226633Sdim break; 1782226633Sdim case 1: 1783226633Sdim mode = ARM_AM::ia; 1784226633Sdim break; 1785226633Sdim case 2: 1786226633Sdim mode = ARM_AM::db; 1787226633Sdim break; 1788226633Sdim case 3: 1789226633Sdim mode = ARM_AM::ib; 1790226633Sdim break; 1791226633Sdim } 1792226633Sdim 1793226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1794226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1795226633Sdim return MCDisassembler::Fail; 1796226633Sdim 1797226633Sdim return S; 1798226633Sdim} 1799226633Sdim 1800234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst, 1801226633Sdim unsigned Insn, 1802226633Sdim uint64_t Address, const void *Decoder) { 1803226633Sdim DecodeStatus S = MCDisassembler::Success; 1804226633Sdim 1805239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1806239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1807239462Sdim unsigned reglist = fieldFromInstruction(Insn, 0, 16); 1808226633Sdim 1809226633Sdim if (pred == 0xF) { 1810226633Sdim switch (Inst.getOpcode()) { 1811226633Sdim case ARM::LDMDA: 1812226633Sdim Inst.setOpcode(ARM::RFEDA); 1813226633Sdim break; 1814226633Sdim case ARM::LDMDA_UPD: 1815226633Sdim Inst.setOpcode(ARM::RFEDA_UPD); 1816226633Sdim break; 1817226633Sdim case ARM::LDMDB: 1818226633Sdim Inst.setOpcode(ARM::RFEDB); 1819226633Sdim break; 1820226633Sdim case ARM::LDMDB_UPD: 1821226633Sdim Inst.setOpcode(ARM::RFEDB_UPD); 1822226633Sdim break; 1823226633Sdim case ARM::LDMIA: 1824226633Sdim Inst.setOpcode(ARM::RFEIA); 1825226633Sdim break; 1826226633Sdim case ARM::LDMIA_UPD: 1827226633Sdim Inst.setOpcode(ARM::RFEIA_UPD); 1828226633Sdim break; 1829226633Sdim case ARM::LDMIB: 1830226633Sdim Inst.setOpcode(ARM::RFEIB); 1831226633Sdim break; 1832226633Sdim case ARM::LDMIB_UPD: 1833226633Sdim Inst.setOpcode(ARM::RFEIB_UPD); 1834226633Sdim break; 1835226633Sdim case ARM::STMDA: 1836226633Sdim Inst.setOpcode(ARM::SRSDA); 1837226633Sdim break; 1838226633Sdim case ARM::STMDA_UPD: 1839226633Sdim Inst.setOpcode(ARM::SRSDA_UPD); 1840226633Sdim break; 1841226633Sdim case ARM::STMDB: 1842226633Sdim Inst.setOpcode(ARM::SRSDB); 1843226633Sdim break; 1844226633Sdim case ARM::STMDB_UPD: 1845226633Sdim Inst.setOpcode(ARM::SRSDB_UPD); 1846226633Sdim break; 1847226633Sdim case ARM::STMIA: 1848226633Sdim Inst.setOpcode(ARM::SRSIA); 1849226633Sdim break; 1850226633Sdim case ARM::STMIA_UPD: 1851226633Sdim Inst.setOpcode(ARM::SRSIA_UPD); 1852226633Sdim break; 1853226633Sdim case ARM::STMIB: 1854226633Sdim Inst.setOpcode(ARM::SRSIB); 1855226633Sdim break; 1856226633Sdim case ARM::STMIB_UPD: 1857226633Sdim Inst.setOpcode(ARM::SRSIB_UPD); 1858226633Sdim break; 1859206124Srdivacky default: 1860226633Sdim if (!Check(S, MCDisassembler::Fail)) return MCDisassembler::Fail; 1861226633Sdim } 1862226633Sdim 1863226633Sdim // For stores (which become SRS's, the only operand is the mode. 1864239462Sdim if (fieldFromInstruction(Insn, 20, 1) == 0) { 1865226633Sdim Inst.addOperand( 1866239462Sdim MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4))); 1867226633Sdim return S; 1868226633Sdim } 1869226633Sdim 1870226633Sdim return DecodeRFEInstruction(Inst, Insn, Address, Decoder); 1871226633Sdim } 1872226633Sdim 1873226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1874226633Sdim return MCDisassembler::Fail; 1875226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1876226633Sdim return MCDisassembler::Fail; // Tied 1877226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1878226633Sdim return MCDisassembler::Fail; 1879226633Sdim if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder))) 1880226633Sdim return MCDisassembler::Fail; 1881226633Sdim 1882226633Sdim return S; 1883226633Sdim} 1884226633Sdim 1885234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 1886226633Sdim uint64_t Address, const void *Decoder) { 1887239462Sdim unsigned imod = fieldFromInstruction(Insn, 18, 2); 1888239462Sdim unsigned M = fieldFromInstruction(Insn, 17, 1); 1889239462Sdim unsigned iflags = fieldFromInstruction(Insn, 6, 3); 1890239462Sdim unsigned mode = fieldFromInstruction(Insn, 0, 5); 1891226633Sdim 1892226633Sdim DecodeStatus S = MCDisassembler::Success; 1893226633Sdim 1894226633Sdim // imod == '01' --> UNPREDICTABLE 1895226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 1896226633Sdim // return failure here. The '01' imod value is unprintable, so there's 1897226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 1898226633Sdim 1899226633Sdim if (imod == 1) return MCDisassembler::Fail; 1900226633Sdim 1901226633Sdim if (imod && M) { 1902226633Sdim Inst.setOpcode(ARM::CPS3p); 1903226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1904226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1905226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1906226633Sdim } else if (imod && !M) { 1907226633Sdim Inst.setOpcode(ARM::CPS2p); 1908226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1909226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1910226633Sdim if (mode) S = MCDisassembler::SoftFail; 1911226633Sdim } else if (!imod && M) { 1912226633Sdim Inst.setOpcode(ARM::CPS1p); 1913226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1914226633Sdim if (iflags) S = MCDisassembler::SoftFail; 1915226633Sdim } else { 1916226633Sdim // imod == '00' && M == '0' --> UNPREDICTABLE 1917226633Sdim Inst.setOpcode(ARM::CPS1p); 1918226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1919226633Sdim S = MCDisassembler::SoftFail; 1920226633Sdim } 1921226633Sdim 1922226633Sdim return S; 1923226633Sdim} 1924226633Sdim 1925234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 1926226633Sdim uint64_t Address, const void *Decoder) { 1927239462Sdim unsigned imod = fieldFromInstruction(Insn, 9, 2); 1928239462Sdim unsigned M = fieldFromInstruction(Insn, 8, 1); 1929239462Sdim unsigned iflags = fieldFromInstruction(Insn, 5, 3); 1930239462Sdim unsigned mode = fieldFromInstruction(Insn, 0, 5); 1931226633Sdim 1932226633Sdim DecodeStatus S = MCDisassembler::Success; 1933226633Sdim 1934226633Sdim // imod == '01' --> UNPREDICTABLE 1935226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 1936226633Sdim // return failure here. The '01' imod value is unprintable, so there's 1937226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 1938226633Sdim 1939226633Sdim if (imod == 1) return MCDisassembler::Fail; 1940226633Sdim 1941226633Sdim if (imod && M) { 1942226633Sdim Inst.setOpcode(ARM::t2CPS3p); 1943226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1944226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1945226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1946226633Sdim } else if (imod && !M) { 1947226633Sdim Inst.setOpcode(ARM::t2CPS2p); 1948226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1949226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1950226633Sdim if (mode) S = MCDisassembler::SoftFail; 1951226633Sdim } else if (!imod && M) { 1952226633Sdim Inst.setOpcode(ARM::t2CPS1p); 1953226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1954226633Sdim if (iflags) S = MCDisassembler::SoftFail; 1955226633Sdim } else { 1956251662Sdim // imod == '00' && M == '0' --> this is a HINT instruction 1957251662Sdim int imm = fieldFromInstruction(Insn, 0, 8); 1958251662Sdim // HINT are defined only for immediate in [0..4] 1959251662Sdim if(imm > 4) return MCDisassembler::Fail; 1960251662Sdim Inst.setOpcode(ARM::t2HINT); 1961251662Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1962226633Sdim } 1963226633Sdim 1964226633Sdim return S; 1965226633Sdim} 1966226633Sdim 1967234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 1968226633Sdim uint64_t Address, const void *Decoder) { 1969226633Sdim DecodeStatus S = MCDisassembler::Success; 1970226633Sdim 1971239462Sdim unsigned Rd = fieldFromInstruction(Insn, 8, 4); 1972226633Sdim unsigned imm = 0; 1973226633Sdim 1974239462Sdim imm |= (fieldFromInstruction(Insn, 0, 8) << 0); 1975239462Sdim imm |= (fieldFromInstruction(Insn, 12, 3) << 8); 1976239462Sdim imm |= (fieldFromInstruction(Insn, 16, 4) << 12); 1977239462Sdim imm |= (fieldFromInstruction(Insn, 26, 1) << 11); 1978226633Sdim 1979226633Sdim if (Inst.getOpcode() == ARM::t2MOVTi16) 1980226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 1981226633Sdim return MCDisassembler::Fail; 1982226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 1983226633Sdim return MCDisassembler::Fail; 1984226633Sdim 1985226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 1986226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1987226633Sdim 1988226633Sdim return S; 1989226633Sdim} 1990226633Sdim 1991234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 1992226633Sdim uint64_t Address, const void *Decoder) { 1993226633Sdim DecodeStatus S = MCDisassembler::Success; 1994226633Sdim 1995239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 1996239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1997226633Sdim unsigned imm = 0; 1998226633Sdim 1999239462Sdim imm |= (fieldFromInstruction(Insn, 0, 12) << 0); 2000239462Sdim imm |= (fieldFromInstruction(Insn, 16, 4) << 12); 2001226633Sdim 2002226633Sdim if (Inst.getOpcode() == ARM::MOVTi16) 2003251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2004226633Sdim return MCDisassembler::Fail; 2005251662Sdim 2006251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2007226633Sdim return MCDisassembler::Fail; 2008226633Sdim 2009226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 2010226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2011226633Sdim 2012226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2013226633Sdim return MCDisassembler::Fail; 2014226633Sdim 2015226633Sdim return S; 2016226633Sdim} 2017226633Sdim 2018234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 2019226633Sdim uint64_t Address, const void *Decoder) { 2020226633Sdim DecodeStatus S = MCDisassembler::Success; 2021226633Sdim 2022239462Sdim unsigned Rd = fieldFromInstruction(Insn, 16, 4); 2023239462Sdim unsigned Rn = fieldFromInstruction(Insn, 0, 4); 2024239462Sdim unsigned Rm = fieldFromInstruction(Insn, 8, 4); 2025239462Sdim unsigned Ra = fieldFromInstruction(Insn, 12, 4); 2026239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2027226633Sdim 2028226633Sdim if (pred == 0xF) 2029226633Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 2030226633Sdim 2031226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2032226633Sdim return MCDisassembler::Fail; 2033226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 2034226633Sdim return MCDisassembler::Fail; 2035226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 2036226633Sdim return MCDisassembler::Fail; 2037226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder))) 2038226633Sdim return MCDisassembler::Fail; 2039226633Sdim 2040226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2041226633Sdim return MCDisassembler::Fail; 2042226633Sdim 2043226633Sdim return S; 2044226633Sdim} 2045226633Sdim 2046234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 2047226633Sdim uint64_t Address, const void *Decoder) { 2048226633Sdim DecodeStatus S = MCDisassembler::Success; 2049226633Sdim 2050239462Sdim unsigned add = fieldFromInstruction(Val, 12, 1); 2051239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 12); 2052239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 2053226633Sdim 2054226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2055226633Sdim return MCDisassembler::Fail; 2056226633Sdim 2057226633Sdim if (!add) imm *= -1; 2058226633Sdim if (imm == 0 && !add) imm = INT32_MIN; 2059226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2060226633Sdim if (Rn == 15) 2061226633Sdim tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder); 2062226633Sdim 2063226633Sdim return S; 2064226633Sdim} 2065226633Sdim 2066234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 2067226633Sdim uint64_t Address, const void *Decoder) { 2068226633Sdim DecodeStatus S = MCDisassembler::Success; 2069226633Sdim 2070239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 2071239462Sdim unsigned U = fieldFromInstruction(Val, 8, 1); 2072239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 2073226633Sdim 2074226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2075226633Sdim return MCDisassembler::Fail; 2076226633Sdim 2077226633Sdim if (U) 2078226633Sdim Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm))); 2079226633Sdim else 2080226633Sdim Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm))); 2081226633Sdim 2082226633Sdim return S; 2083226633Sdim} 2084226633Sdim 2085234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 2086226633Sdim uint64_t Address, const void *Decoder) { 2087226633Sdim return DecodeGPRRegisterClass(Inst, Val, Address, Decoder); 2088226633Sdim} 2089226633Sdim 2090226633Sdimstatic DecodeStatus 2091234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn, 2092234353Sdim uint64_t Address, const void *Decoder) { 2093243830Sdim DecodeStatus Status = MCDisassembler::Success; 2094243830Sdim 2095243830Sdim // Note the J1 and J2 values are from the encoded instruction. So here 2096243830Sdim // change them to I1 and I2 values via as documented: 2097243830Sdim // I1 = NOT(J1 EOR S); 2098243830Sdim // I2 = NOT(J2 EOR S); 2099243830Sdim // and build the imm32 with one trailing zero as documented: 2100243830Sdim // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); 2101243830Sdim unsigned S = fieldFromInstruction(Insn, 26, 1); 2102243830Sdim unsigned J1 = fieldFromInstruction(Insn, 13, 1); 2103243830Sdim unsigned J2 = fieldFromInstruction(Insn, 11, 1); 2104243830Sdim unsigned I1 = !(J1 ^ S); 2105243830Sdim unsigned I2 = !(J2 ^ S); 2106243830Sdim unsigned imm10 = fieldFromInstruction(Insn, 16, 10); 2107243830Sdim unsigned imm11 = fieldFromInstruction(Insn, 0, 11); 2108243830Sdim unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11; 2109243830Sdim int imm32 = SignExtend32<24>(tmp << 1); 2110243830Sdim if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, 2111234353Sdim true, 4, Inst, Decoder)) 2112243830Sdim Inst.addOperand(MCOperand::CreateImm(imm32)); 2113243830Sdim 2114243830Sdim return Status; 2115234353Sdim} 2116234353Sdim 2117234353Sdimstatic DecodeStatus 2118234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn, 2119226633Sdim uint64_t Address, const void *Decoder) { 2120226633Sdim DecodeStatus S = MCDisassembler::Success; 2121226633Sdim 2122239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2123239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2; 2124226633Sdim 2125226633Sdim if (pred == 0xF) { 2126226633Sdim Inst.setOpcode(ARM::BLXi); 2127239462Sdim imm |= fieldFromInstruction(Insn, 24, 1) << 1; 2128234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2129234353Sdim true, 4, Inst, Decoder)) 2130226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); 2131226633Sdim return S; 2132226633Sdim } 2133226633Sdim 2134234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2135234353Sdim true, 4, Inst, Decoder)) 2136226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); 2137226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2138226633Sdim return MCDisassembler::Fail; 2139226633Sdim 2140226633Sdim return S; 2141226633Sdim} 2142226633Sdim 2143226633Sdim 2144234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 2145226633Sdim uint64_t Address, const void *Decoder) { 2146226633Sdim DecodeStatus S = MCDisassembler::Success; 2147226633Sdim 2148239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 2149239462Sdim unsigned align = fieldFromInstruction(Val, 4, 2); 2150226633Sdim 2151226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2152226633Sdim return MCDisassembler::Fail; 2153226633Sdim if (!align) 2154226633Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2155226633Sdim else 2156226633Sdim Inst.addOperand(MCOperand::CreateImm(4 << align)); 2157226633Sdim 2158226633Sdim return S; 2159226633Sdim} 2160226633Sdim 2161234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn, 2162226633Sdim uint64_t Address, const void *Decoder) { 2163226633Sdim DecodeStatus S = MCDisassembler::Success; 2164226633Sdim 2165239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2166239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2167239462Sdim unsigned wb = fieldFromInstruction(Insn, 16, 4); 2168239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2169239462Sdim Rn |= fieldFromInstruction(Insn, 4, 2) << 4; 2170239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2171226633Sdim 2172226633Sdim // First output register 2173234353Sdim switch (Inst.getOpcode()) { 2174234353Sdim case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8: 2175234353Sdim case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register: 2176234353Sdim case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register: 2177234353Sdim case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register: 2178234353Sdim case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register: 2179234353Sdim case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8: 2180234353Sdim case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register: 2181234353Sdim case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register: 2182234353Sdim case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register: 2183234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2184234353Sdim return MCDisassembler::Fail; 2185234353Sdim break; 2186234353Sdim case ARM::VLD2b16: 2187234353Sdim case ARM::VLD2b32: 2188234353Sdim case ARM::VLD2b8: 2189234353Sdim case ARM::VLD2b16wb_fixed: 2190234353Sdim case ARM::VLD2b16wb_register: 2191234353Sdim case ARM::VLD2b32wb_fixed: 2192234353Sdim case ARM::VLD2b32wb_register: 2193234353Sdim case ARM::VLD2b8wb_fixed: 2194234353Sdim case ARM::VLD2b8wb_register: 2195234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2196234353Sdim return MCDisassembler::Fail; 2197234353Sdim break; 2198234353Sdim default: 2199234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2200234353Sdim return MCDisassembler::Fail; 2201234353Sdim } 2202226633Sdim 2203226633Sdim // Second output register 2204226633Sdim switch (Inst.getOpcode()) { 2205226633Sdim case ARM::VLD3d8: 2206226633Sdim case ARM::VLD3d16: 2207226633Sdim case ARM::VLD3d32: 2208226633Sdim case ARM::VLD3d8_UPD: 2209226633Sdim case ARM::VLD3d16_UPD: 2210226633Sdim case ARM::VLD3d32_UPD: 2211226633Sdim case ARM::VLD4d8: 2212226633Sdim case ARM::VLD4d16: 2213226633Sdim case ARM::VLD4d32: 2214226633Sdim case ARM::VLD4d8_UPD: 2215226633Sdim case ARM::VLD4d16_UPD: 2216226633Sdim case ARM::VLD4d32_UPD: 2217226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2218226633Sdim return MCDisassembler::Fail; 2219206124Srdivacky break; 2220226633Sdim case ARM::VLD3q8: 2221226633Sdim case ARM::VLD3q16: 2222226633Sdim case ARM::VLD3q32: 2223226633Sdim case ARM::VLD3q8_UPD: 2224226633Sdim case ARM::VLD3q16_UPD: 2225226633Sdim case ARM::VLD3q32_UPD: 2226226633Sdim case ARM::VLD4q8: 2227226633Sdim case ARM::VLD4q16: 2228226633Sdim case ARM::VLD4q32: 2229226633Sdim case ARM::VLD4q8_UPD: 2230226633Sdim case ARM::VLD4q16_UPD: 2231226633Sdim case ARM::VLD4q32_UPD: 2232226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2233226633Sdim return MCDisassembler::Fail; 2234206124Srdivacky default: 2235226633Sdim break; 2236226633Sdim } 2237226633Sdim 2238226633Sdim // Third output register 2239226633Sdim switch(Inst.getOpcode()) { 2240226633Sdim case ARM::VLD3d8: 2241226633Sdim case ARM::VLD3d16: 2242226633Sdim case ARM::VLD3d32: 2243226633Sdim case ARM::VLD3d8_UPD: 2244226633Sdim case ARM::VLD3d16_UPD: 2245226633Sdim case ARM::VLD3d32_UPD: 2246226633Sdim case ARM::VLD4d8: 2247226633Sdim case ARM::VLD4d16: 2248226633Sdim case ARM::VLD4d32: 2249226633Sdim case ARM::VLD4d8_UPD: 2250226633Sdim case ARM::VLD4d16_UPD: 2251226633Sdim case ARM::VLD4d32_UPD: 2252226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2253226633Sdim return MCDisassembler::Fail; 2254226633Sdim break; 2255226633Sdim case ARM::VLD3q8: 2256226633Sdim case ARM::VLD3q16: 2257226633Sdim case ARM::VLD3q32: 2258226633Sdim case ARM::VLD3q8_UPD: 2259226633Sdim case ARM::VLD3q16_UPD: 2260226633Sdim case ARM::VLD3q32_UPD: 2261226633Sdim case ARM::VLD4q8: 2262226633Sdim case ARM::VLD4q16: 2263226633Sdim case ARM::VLD4q32: 2264226633Sdim case ARM::VLD4q8_UPD: 2265226633Sdim case ARM::VLD4q16_UPD: 2266226633Sdim case ARM::VLD4q32_UPD: 2267226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2268226633Sdim return MCDisassembler::Fail; 2269226633Sdim break; 2270226633Sdim default: 2271226633Sdim break; 2272226633Sdim } 2273226633Sdim 2274226633Sdim // Fourth output register 2275226633Sdim switch (Inst.getOpcode()) { 2276226633Sdim case ARM::VLD4d8: 2277226633Sdim case ARM::VLD4d16: 2278226633Sdim case ARM::VLD4d32: 2279226633Sdim case ARM::VLD4d8_UPD: 2280226633Sdim case ARM::VLD4d16_UPD: 2281226633Sdim case ARM::VLD4d32_UPD: 2282226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 2283226633Sdim return MCDisassembler::Fail; 2284226633Sdim break; 2285226633Sdim case ARM::VLD4q8: 2286226633Sdim case ARM::VLD4q16: 2287226633Sdim case ARM::VLD4q32: 2288226633Sdim case ARM::VLD4q8_UPD: 2289226633Sdim case ARM::VLD4q16_UPD: 2290226633Sdim case ARM::VLD4q32_UPD: 2291226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2292226633Sdim return MCDisassembler::Fail; 2293226633Sdim break; 2294226633Sdim default: 2295226633Sdim break; 2296226633Sdim } 2297226633Sdim 2298226633Sdim // Writeback operand 2299226633Sdim switch (Inst.getOpcode()) { 2300234353Sdim case ARM::VLD1d8wb_fixed: 2301234353Sdim case ARM::VLD1d16wb_fixed: 2302234353Sdim case ARM::VLD1d32wb_fixed: 2303234353Sdim case ARM::VLD1d64wb_fixed: 2304234353Sdim case ARM::VLD1d8wb_register: 2305234353Sdim case ARM::VLD1d16wb_register: 2306234353Sdim case ARM::VLD1d32wb_register: 2307234353Sdim case ARM::VLD1d64wb_register: 2308234353Sdim case ARM::VLD1q8wb_fixed: 2309234353Sdim case ARM::VLD1q16wb_fixed: 2310234353Sdim case ARM::VLD1q32wb_fixed: 2311234353Sdim case ARM::VLD1q64wb_fixed: 2312234353Sdim case ARM::VLD1q8wb_register: 2313234353Sdim case ARM::VLD1q16wb_register: 2314234353Sdim case ARM::VLD1q32wb_register: 2315234353Sdim case ARM::VLD1q64wb_register: 2316234353Sdim case ARM::VLD1d8Twb_fixed: 2317234353Sdim case ARM::VLD1d8Twb_register: 2318234353Sdim case ARM::VLD1d16Twb_fixed: 2319234353Sdim case ARM::VLD1d16Twb_register: 2320234353Sdim case ARM::VLD1d32Twb_fixed: 2321234353Sdim case ARM::VLD1d32Twb_register: 2322234353Sdim case ARM::VLD1d64Twb_fixed: 2323234353Sdim case ARM::VLD1d64Twb_register: 2324234353Sdim case ARM::VLD1d8Qwb_fixed: 2325234353Sdim case ARM::VLD1d8Qwb_register: 2326234353Sdim case ARM::VLD1d16Qwb_fixed: 2327234353Sdim case ARM::VLD1d16Qwb_register: 2328234353Sdim case ARM::VLD1d32Qwb_fixed: 2329234353Sdim case ARM::VLD1d32Qwb_register: 2330234353Sdim case ARM::VLD1d64Qwb_fixed: 2331234353Sdim case ARM::VLD1d64Qwb_register: 2332234353Sdim case ARM::VLD2d8wb_fixed: 2333234353Sdim case ARM::VLD2d16wb_fixed: 2334234353Sdim case ARM::VLD2d32wb_fixed: 2335234353Sdim case ARM::VLD2q8wb_fixed: 2336234353Sdim case ARM::VLD2q16wb_fixed: 2337234353Sdim case ARM::VLD2q32wb_fixed: 2338234353Sdim case ARM::VLD2d8wb_register: 2339234353Sdim case ARM::VLD2d16wb_register: 2340234353Sdim case ARM::VLD2d32wb_register: 2341234353Sdim case ARM::VLD2q8wb_register: 2342234353Sdim case ARM::VLD2q16wb_register: 2343234353Sdim case ARM::VLD2q32wb_register: 2344234353Sdim case ARM::VLD2b8wb_fixed: 2345234353Sdim case ARM::VLD2b16wb_fixed: 2346234353Sdim case ARM::VLD2b32wb_fixed: 2347234353Sdim case ARM::VLD2b8wb_register: 2348234353Sdim case ARM::VLD2b16wb_register: 2349234353Sdim case ARM::VLD2b32wb_register: 2350234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2351234353Sdim break; 2352226633Sdim case ARM::VLD3d8_UPD: 2353226633Sdim case ARM::VLD3d16_UPD: 2354226633Sdim case ARM::VLD3d32_UPD: 2355226633Sdim case ARM::VLD3q8_UPD: 2356226633Sdim case ARM::VLD3q16_UPD: 2357226633Sdim case ARM::VLD3q32_UPD: 2358226633Sdim case ARM::VLD4d8_UPD: 2359226633Sdim case ARM::VLD4d16_UPD: 2360226633Sdim case ARM::VLD4d32_UPD: 2361226633Sdim case ARM::VLD4q8_UPD: 2362226633Sdim case ARM::VLD4q16_UPD: 2363226633Sdim case ARM::VLD4q32_UPD: 2364226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2365226633Sdim return MCDisassembler::Fail; 2366226633Sdim break; 2367226633Sdim default: 2368226633Sdim break; 2369226633Sdim } 2370226633Sdim 2371226633Sdim // AddrMode6 Base (register+alignment) 2372226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2373226633Sdim return MCDisassembler::Fail; 2374226633Sdim 2375226633Sdim // AddrMode6 Offset (register) 2376234353Sdim switch (Inst.getOpcode()) { 2377234353Sdim default: 2378234353Sdim // The below have been updated to have explicit am6offset split 2379234353Sdim // between fixed and register offset. For those instructions not 2380234353Sdim // yet updated, we need to add an additional reg0 operand for the 2381234353Sdim // fixed variant. 2382234353Sdim // 2383234353Sdim // The fixed offset encodes as Rm == 0xd, so we check for that. 2384234353Sdim if (Rm == 0xd) { 2385234353Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2386234353Sdim break; 2387234353Sdim } 2388234353Sdim // Fall through to handle the register offset variant. 2389234353Sdim case ARM::VLD1d8wb_fixed: 2390234353Sdim case ARM::VLD1d16wb_fixed: 2391234353Sdim case ARM::VLD1d32wb_fixed: 2392234353Sdim case ARM::VLD1d64wb_fixed: 2393234353Sdim case ARM::VLD1d8Twb_fixed: 2394234353Sdim case ARM::VLD1d16Twb_fixed: 2395234353Sdim case ARM::VLD1d32Twb_fixed: 2396234353Sdim case ARM::VLD1d64Twb_fixed: 2397234353Sdim case ARM::VLD1d8Qwb_fixed: 2398234353Sdim case ARM::VLD1d16Qwb_fixed: 2399234353Sdim case ARM::VLD1d32Qwb_fixed: 2400234353Sdim case ARM::VLD1d64Qwb_fixed: 2401234353Sdim case ARM::VLD1d8wb_register: 2402234353Sdim case ARM::VLD1d16wb_register: 2403234353Sdim case ARM::VLD1d32wb_register: 2404234353Sdim case ARM::VLD1d64wb_register: 2405234353Sdim case ARM::VLD1q8wb_fixed: 2406234353Sdim case ARM::VLD1q16wb_fixed: 2407234353Sdim case ARM::VLD1q32wb_fixed: 2408234353Sdim case ARM::VLD1q64wb_fixed: 2409234353Sdim case ARM::VLD1q8wb_register: 2410234353Sdim case ARM::VLD1q16wb_register: 2411234353Sdim case ARM::VLD1q32wb_register: 2412234353Sdim case ARM::VLD1q64wb_register: 2413234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2414234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2415234353Sdim // increment and we need to add the register operand to the instruction. 2416234353Sdim if (Rm != 0xD && Rm != 0xF && 2417234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2418226633Sdim return MCDisassembler::Fail; 2419234353Sdim break; 2420234353Sdim case ARM::VLD2d8wb_fixed: 2421234353Sdim case ARM::VLD2d16wb_fixed: 2422234353Sdim case ARM::VLD2d32wb_fixed: 2423234353Sdim case ARM::VLD2b8wb_fixed: 2424234353Sdim case ARM::VLD2b16wb_fixed: 2425234353Sdim case ARM::VLD2b32wb_fixed: 2426234353Sdim case ARM::VLD2q8wb_fixed: 2427234353Sdim case ARM::VLD2q16wb_fixed: 2428234353Sdim case ARM::VLD2q32wb_fixed: 2429234353Sdim break; 2430226633Sdim } 2431226633Sdim 2432226633Sdim return S; 2433226633Sdim} 2434226633Sdim 2435234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn, 2436226633Sdim uint64_t Address, const void *Decoder) { 2437226633Sdim DecodeStatus S = MCDisassembler::Success; 2438226633Sdim 2439239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2440239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2441239462Sdim unsigned wb = fieldFromInstruction(Insn, 16, 4); 2442239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2443239462Sdim Rn |= fieldFromInstruction(Insn, 4, 2) << 4; 2444239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2445226633Sdim 2446226633Sdim // Writeback Operand 2447226633Sdim switch (Inst.getOpcode()) { 2448234353Sdim case ARM::VST1d8wb_fixed: 2449234353Sdim case ARM::VST1d16wb_fixed: 2450234353Sdim case ARM::VST1d32wb_fixed: 2451234353Sdim case ARM::VST1d64wb_fixed: 2452234353Sdim case ARM::VST1d8wb_register: 2453234353Sdim case ARM::VST1d16wb_register: 2454234353Sdim case ARM::VST1d32wb_register: 2455234353Sdim case ARM::VST1d64wb_register: 2456234353Sdim case ARM::VST1q8wb_fixed: 2457234353Sdim case ARM::VST1q16wb_fixed: 2458234353Sdim case ARM::VST1q32wb_fixed: 2459234353Sdim case ARM::VST1q64wb_fixed: 2460234353Sdim case ARM::VST1q8wb_register: 2461234353Sdim case ARM::VST1q16wb_register: 2462234353Sdim case ARM::VST1q32wb_register: 2463234353Sdim case ARM::VST1q64wb_register: 2464234353Sdim case ARM::VST1d8Twb_fixed: 2465234353Sdim case ARM::VST1d16Twb_fixed: 2466234353Sdim case ARM::VST1d32Twb_fixed: 2467234353Sdim case ARM::VST1d64Twb_fixed: 2468234353Sdim case ARM::VST1d8Twb_register: 2469234353Sdim case ARM::VST1d16Twb_register: 2470234353Sdim case ARM::VST1d32Twb_register: 2471234353Sdim case ARM::VST1d64Twb_register: 2472234353Sdim case ARM::VST1d8Qwb_fixed: 2473234353Sdim case ARM::VST1d16Qwb_fixed: 2474234353Sdim case ARM::VST1d32Qwb_fixed: 2475234353Sdim case ARM::VST1d64Qwb_fixed: 2476234353Sdim case ARM::VST1d8Qwb_register: 2477234353Sdim case ARM::VST1d16Qwb_register: 2478234353Sdim case ARM::VST1d32Qwb_register: 2479234353Sdim case ARM::VST1d64Qwb_register: 2480234353Sdim case ARM::VST2d8wb_fixed: 2481234353Sdim case ARM::VST2d16wb_fixed: 2482234353Sdim case ARM::VST2d32wb_fixed: 2483234353Sdim case ARM::VST2d8wb_register: 2484234353Sdim case ARM::VST2d16wb_register: 2485234353Sdim case ARM::VST2d32wb_register: 2486234353Sdim case ARM::VST2q8wb_fixed: 2487234353Sdim case ARM::VST2q16wb_fixed: 2488234353Sdim case ARM::VST2q32wb_fixed: 2489234353Sdim case ARM::VST2q8wb_register: 2490234353Sdim case ARM::VST2q16wb_register: 2491234353Sdim case ARM::VST2q32wb_register: 2492234353Sdim case ARM::VST2b8wb_fixed: 2493234353Sdim case ARM::VST2b16wb_fixed: 2494234353Sdim case ARM::VST2b32wb_fixed: 2495234353Sdim case ARM::VST2b8wb_register: 2496234353Sdim case ARM::VST2b16wb_register: 2497234353Sdim case ARM::VST2b32wb_register: 2498234353Sdim if (Rm == 0xF) 2499234353Sdim return MCDisassembler::Fail; 2500234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2501234353Sdim break; 2502226633Sdim case ARM::VST3d8_UPD: 2503226633Sdim case ARM::VST3d16_UPD: 2504226633Sdim case ARM::VST3d32_UPD: 2505226633Sdim case ARM::VST3q8_UPD: 2506226633Sdim case ARM::VST3q16_UPD: 2507226633Sdim case ARM::VST3q32_UPD: 2508226633Sdim case ARM::VST4d8_UPD: 2509226633Sdim case ARM::VST4d16_UPD: 2510226633Sdim case ARM::VST4d32_UPD: 2511226633Sdim case ARM::VST4q8_UPD: 2512226633Sdim case ARM::VST4q16_UPD: 2513226633Sdim case ARM::VST4q32_UPD: 2514226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2515226633Sdim return MCDisassembler::Fail; 2516226633Sdim break; 2517226633Sdim default: 2518226633Sdim break; 2519226633Sdim } 2520226633Sdim 2521226633Sdim // AddrMode6 Base (register+alignment) 2522226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2523226633Sdim return MCDisassembler::Fail; 2524226633Sdim 2525226633Sdim // AddrMode6 Offset (register) 2526234353Sdim switch (Inst.getOpcode()) { 2527234353Sdim default: 2528234353Sdim if (Rm == 0xD) 2529234353Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2530234353Sdim else if (Rm != 0xF) { 2531234353Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2532234353Sdim return MCDisassembler::Fail; 2533234353Sdim } 2534234353Sdim break; 2535234353Sdim case ARM::VST1d8wb_fixed: 2536234353Sdim case ARM::VST1d16wb_fixed: 2537234353Sdim case ARM::VST1d32wb_fixed: 2538234353Sdim case ARM::VST1d64wb_fixed: 2539234353Sdim case ARM::VST1q8wb_fixed: 2540234353Sdim case ARM::VST1q16wb_fixed: 2541234353Sdim case ARM::VST1q32wb_fixed: 2542234353Sdim case ARM::VST1q64wb_fixed: 2543234353Sdim case ARM::VST1d8Twb_fixed: 2544234353Sdim case ARM::VST1d16Twb_fixed: 2545234353Sdim case ARM::VST1d32Twb_fixed: 2546234353Sdim case ARM::VST1d64Twb_fixed: 2547234353Sdim case ARM::VST1d8Qwb_fixed: 2548234353Sdim case ARM::VST1d16Qwb_fixed: 2549234353Sdim case ARM::VST1d32Qwb_fixed: 2550234353Sdim case ARM::VST1d64Qwb_fixed: 2551234353Sdim case ARM::VST2d8wb_fixed: 2552234353Sdim case ARM::VST2d16wb_fixed: 2553234353Sdim case ARM::VST2d32wb_fixed: 2554234353Sdim case ARM::VST2q8wb_fixed: 2555234353Sdim case ARM::VST2q16wb_fixed: 2556234353Sdim case ARM::VST2q32wb_fixed: 2557234353Sdim case ARM::VST2b8wb_fixed: 2558234353Sdim case ARM::VST2b16wb_fixed: 2559234353Sdim case ARM::VST2b32wb_fixed: 2560234353Sdim break; 2561226633Sdim } 2562226633Sdim 2563234353Sdim 2564226633Sdim // First input register 2565234353Sdim switch (Inst.getOpcode()) { 2566234353Sdim case ARM::VST1q16: 2567234353Sdim case ARM::VST1q32: 2568234353Sdim case ARM::VST1q64: 2569234353Sdim case ARM::VST1q8: 2570234353Sdim case ARM::VST1q16wb_fixed: 2571234353Sdim case ARM::VST1q16wb_register: 2572234353Sdim case ARM::VST1q32wb_fixed: 2573234353Sdim case ARM::VST1q32wb_register: 2574234353Sdim case ARM::VST1q64wb_fixed: 2575234353Sdim case ARM::VST1q64wb_register: 2576234353Sdim case ARM::VST1q8wb_fixed: 2577234353Sdim case ARM::VST1q8wb_register: 2578234353Sdim case ARM::VST2d16: 2579234353Sdim case ARM::VST2d32: 2580234353Sdim case ARM::VST2d8: 2581234353Sdim case ARM::VST2d16wb_fixed: 2582234353Sdim case ARM::VST2d16wb_register: 2583234353Sdim case ARM::VST2d32wb_fixed: 2584234353Sdim case ARM::VST2d32wb_register: 2585234353Sdim case ARM::VST2d8wb_fixed: 2586234353Sdim case ARM::VST2d8wb_register: 2587234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2588234353Sdim return MCDisassembler::Fail; 2589234353Sdim break; 2590234353Sdim case ARM::VST2b16: 2591234353Sdim case ARM::VST2b32: 2592234353Sdim case ARM::VST2b8: 2593234353Sdim case ARM::VST2b16wb_fixed: 2594234353Sdim case ARM::VST2b16wb_register: 2595234353Sdim case ARM::VST2b32wb_fixed: 2596234353Sdim case ARM::VST2b32wb_register: 2597234353Sdim case ARM::VST2b8wb_fixed: 2598234353Sdim case ARM::VST2b8wb_register: 2599234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2600234353Sdim return MCDisassembler::Fail; 2601234353Sdim break; 2602234353Sdim default: 2603234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2604234353Sdim return MCDisassembler::Fail; 2605234353Sdim } 2606226633Sdim 2607226633Sdim // Second input register 2608226633Sdim switch (Inst.getOpcode()) { 2609226633Sdim case ARM::VST3d8: 2610226633Sdim case ARM::VST3d16: 2611226633Sdim case ARM::VST3d32: 2612226633Sdim case ARM::VST3d8_UPD: 2613226633Sdim case ARM::VST3d16_UPD: 2614226633Sdim case ARM::VST3d32_UPD: 2615226633Sdim case ARM::VST4d8: 2616226633Sdim case ARM::VST4d16: 2617226633Sdim case ARM::VST4d32: 2618226633Sdim case ARM::VST4d8_UPD: 2619226633Sdim case ARM::VST4d16_UPD: 2620226633Sdim case ARM::VST4d32_UPD: 2621226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2622226633Sdim return MCDisassembler::Fail; 2623226633Sdim break; 2624226633Sdim case ARM::VST3q8: 2625226633Sdim case ARM::VST3q16: 2626226633Sdim case ARM::VST3q32: 2627226633Sdim case ARM::VST3q8_UPD: 2628226633Sdim case ARM::VST3q16_UPD: 2629226633Sdim case ARM::VST3q32_UPD: 2630226633Sdim case ARM::VST4q8: 2631226633Sdim case ARM::VST4q16: 2632226633Sdim case ARM::VST4q32: 2633226633Sdim case ARM::VST4q8_UPD: 2634226633Sdim case ARM::VST4q16_UPD: 2635226633Sdim case ARM::VST4q32_UPD: 2636226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2637226633Sdim return MCDisassembler::Fail; 2638226633Sdim break; 2639226633Sdim default: 2640226633Sdim break; 2641226633Sdim } 2642226633Sdim 2643226633Sdim // Third input register 2644226633Sdim switch (Inst.getOpcode()) { 2645226633Sdim case ARM::VST3d8: 2646226633Sdim case ARM::VST3d16: 2647226633Sdim case ARM::VST3d32: 2648226633Sdim case ARM::VST3d8_UPD: 2649226633Sdim case ARM::VST3d16_UPD: 2650226633Sdim case ARM::VST3d32_UPD: 2651226633Sdim case ARM::VST4d8: 2652226633Sdim case ARM::VST4d16: 2653226633Sdim case ARM::VST4d32: 2654226633Sdim case ARM::VST4d8_UPD: 2655226633Sdim case ARM::VST4d16_UPD: 2656226633Sdim case ARM::VST4d32_UPD: 2657226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2658226633Sdim return MCDisassembler::Fail; 2659226633Sdim break; 2660226633Sdim case ARM::VST3q8: 2661226633Sdim case ARM::VST3q16: 2662226633Sdim case ARM::VST3q32: 2663226633Sdim case ARM::VST3q8_UPD: 2664226633Sdim case ARM::VST3q16_UPD: 2665226633Sdim case ARM::VST3q32_UPD: 2666226633Sdim case ARM::VST4q8: 2667226633Sdim case ARM::VST4q16: 2668226633Sdim case ARM::VST4q32: 2669226633Sdim case ARM::VST4q8_UPD: 2670226633Sdim case ARM::VST4q16_UPD: 2671226633Sdim case ARM::VST4q32_UPD: 2672226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2673226633Sdim return MCDisassembler::Fail; 2674226633Sdim break; 2675226633Sdim default: 2676226633Sdim break; 2677226633Sdim } 2678226633Sdim 2679226633Sdim // Fourth input register 2680226633Sdim switch (Inst.getOpcode()) { 2681226633Sdim case ARM::VST4d8: 2682226633Sdim case ARM::VST4d16: 2683226633Sdim case ARM::VST4d32: 2684226633Sdim case ARM::VST4d8_UPD: 2685226633Sdim case ARM::VST4d16_UPD: 2686226633Sdim case ARM::VST4d32_UPD: 2687226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 2688226633Sdim return MCDisassembler::Fail; 2689226633Sdim break; 2690226633Sdim case ARM::VST4q8: 2691226633Sdim case ARM::VST4q16: 2692226633Sdim case ARM::VST4q32: 2693226633Sdim case ARM::VST4q8_UPD: 2694226633Sdim case ARM::VST4q16_UPD: 2695226633Sdim case ARM::VST4q32_UPD: 2696226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2697226633Sdim return MCDisassembler::Fail; 2698226633Sdim break; 2699226633Sdim default: 2700226633Sdim break; 2701226633Sdim } 2702226633Sdim 2703226633Sdim return S; 2704226633Sdim} 2705226633Sdim 2706234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn, 2707226633Sdim uint64_t Address, const void *Decoder) { 2708226633Sdim DecodeStatus S = MCDisassembler::Success; 2709226633Sdim 2710239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2711239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2712239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2713239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2714239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 2715239462Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2716226633Sdim 2717243830Sdim if (size == 0 && align == 1) 2718243830Sdim return MCDisassembler::Fail; 2719226633Sdim align *= (1 << size); 2720226633Sdim 2721234353Sdim switch (Inst.getOpcode()) { 2722234353Sdim case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8: 2723234353Sdim case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register: 2724234353Sdim case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register: 2725234353Sdim case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register: 2726234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2727226633Sdim return MCDisassembler::Fail; 2728234353Sdim break; 2729234353Sdim default: 2730234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2731234353Sdim return MCDisassembler::Fail; 2732234353Sdim break; 2733226633Sdim } 2734226633Sdim if (Rm != 0xF) { 2735226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2736226633Sdim return MCDisassembler::Fail; 2737226633Sdim } 2738226633Sdim 2739226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2740226633Sdim return MCDisassembler::Fail; 2741226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2742226633Sdim 2743234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2744234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2745234353Sdim // increment and we need to add the register operand to the instruction. 2746234353Sdim if (Rm != 0xD && Rm != 0xF && 2747234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2748234353Sdim return MCDisassembler::Fail; 2749226633Sdim 2750226633Sdim return S; 2751226633Sdim} 2752226633Sdim 2753234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, 2754226633Sdim uint64_t Address, const void *Decoder) { 2755226633Sdim DecodeStatus S = MCDisassembler::Success; 2756226633Sdim 2757239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2758239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2759239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2760239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2761239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 2762239462Sdim unsigned size = 1 << fieldFromInstruction(Insn, 6, 2); 2763226633Sdim align *= 2*size; 2764226633Sdim 2765234353Sdim switch (Inst.getOpcode()) { 2766234353Sdim case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8: 2767234353Sdim case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register: 2768234353Sdim case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register: 2769234353Sdim case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register: 2770234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2771226633Sdim return MCDisassembler::Fail; 2772234353Sdim break; 2773234353Sdim case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2: 2774234353Sdim case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register: 2775234353Sdim case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register: 2776234353Sdim case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register: 2777234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2778234353Sdim return MCDisassembler::Fail; 2779234353Sdim break; 2780234353Sdim default: 2781234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2782234353Sdim return MCDisassembler::Fail; 2783234353Sdim break; 2784226633Sdim } 2785226633Sdim 2786234353Sdim if (Rm != 0xF) 2787234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2788234353Sdim 2789226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2790226633Sdim return MCDisassembler::Fail; 2791226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2792226633Sdim 2793234982Sdim if (Rm != 0xD && Rm != 0xF) { 2794226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2795226633Sdim return MCDisassembler::Fail; 2796226633Sdim } 2797226633Sdim 2798226633Sdim return S; 2799226633Sdim} 2800226633Sdim 2801234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn, 2802226633Sdim uint64_t Address, const void *Decoder) { 2803226633Sdim DecodeStatus S = MCDisassembler::Success; 2804226633Sdim 2805239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2806239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2807239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2808239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2809239462Sdim unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; 2810226633Sdim 2811226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2812226633Sdim return MCDisassembler::Fail; 2813226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 2814226633Sdim return MCDisassembler::Fail; 2815226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 2816226633Sdim return MCDisassembler::Fail; 2817226633Sdim if (Rm != 0xF) { 2818226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2819226633Sdim return MCDisassembler::Fail; 2820226633Sdim } 2821226633Sdim 2822226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2823226633Sdim return MCDisassembler::Fail; 2824226633Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2825226633Sdim 2826226633Sdim if (Rm == 0xD) 2827226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2828226633Sdim else if (Rm != 0xF) { 2829226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2830226633Sdim return MCDisassembler::Fail; 2831226633Sdim } 2832226633Sdim 2833226633Sdim return S; 2834226633Sdim} 2835226633Sdim 2836234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn, 2837226633Sdim uint64_t Address, const void *Decoder) { 2838226633Sdim DecodeStatus S = MCDisassembler::Success; 2839226633Sdim 2840239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2841239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2842239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2843239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2844239462Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2845239462Sdim unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; 2846239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 2847226633Sdim 2848226633Sdim if (size == 0x3) { 2849243830Sdim if (align == 0) 2850243830Sdim return MCDisassembler::Fail; 2851226633Sdim size = 4; 2852226633Sdim align = 16; 2853226633Sdim } else { 2854226633Sdim if (size == 2) { 2855226633Sdim size = 1 << size; 2856226633Sdim align *= 8; 2857226633Sdim } else { 2858226633Sdim size = 1 << size; 2859226633Sdim align *= 4*size; 2860206124Srdivacky } 2861206124Srdivacky } 2862206124Srdivacky 2863226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2864226633Sdim return MCDisassembler::Fail; 2865226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 2866226633Sdim return MCDisassembler::Fail; 2867226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 2868226633Sdim return MCDisassembler::Fail; 2869226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder))) 2870226633Sdim return MCDisassembler::Fail; 2871226633Sdim if (Rm != 0xF) { 2872226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2873226633Sdim return MCDisassembler::Fail; 2874226633Sdim } 2875226633Sdim 2876226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2877226633Sdim return MCDisassembler::Fail; 2878226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2879226633Sdim 2880226633Sdim if (Rm == 0xD) 2881226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2882226633Sdim else if (Rm != 0xF) { 2883226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2884226633Sdim return MCDisassembler::Fail; 2885226633Sdim } 2886226633Sdim 2887226633Sdim return S; 2888206124Srdivacky} 2889206124Srdivacky 2890226633Sdimstatic DecodeStatus 2891234353SdimDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn, 2892226633Sdim uint64_t Address, const void *Decoder) { 2893226633Sdim DecodeStatus S = MCDisassembler::Success; 2894206124Srdivacky 2895239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2896239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2897239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 2898239462Sdim imm |= fieldFromInstruction(Insn, 16, 3) << 4; 2899239462Sdim imm |= fieldFromInstruction(Insn, 24, 1) << 7; 2900239462Sdim imm |= fieldFromInstruction(Insn, 8, 4) << 8; 2901239462Sdim imm |= fieldFromInstruction(Insn, 5, 1) << 12; 2902239462Sdim unsigned Q = fieldFromInstruction(Insn, 6, 1); 2903206124Srdivacky 2904226633Sdim if (Q) { 2905226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 2906226633Sdim return MCDisassembler::Fail; 2907226633Sdim } else { 2908226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2909226633Sdim return MCDisassembler::Fail; 2910226633Sdim } 2911206124Srdivacky 2912226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2913206124Srdivacky 2914226633Sdim switch (Inst.getOpcode()) { 2915226633Sdim case ARM::VORRiv4i16: 2916226633Sdim case ARM::VORRiv2i32: 2917226633Sdim case ARM::VBICiv4i16: 2918226633Sdim case ARM::VBICiv2i32: 2919226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2920226633Sdim return MCDisassembler::Fail; 2921226633Sdim break; 2922226633Sdim case ARM::VORRiv8i16: 2923226633Sdim case ARM::VORRiv4i32: 2924226633Sdim case ARM::VBICiv8i16: 2925226633Sdim case ARM::VBICiv4i32: 2926226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 2927226633Sdim return MCDisassembler::Fail; 2928226633Sdim break; 2929226633Sdim default: 2930226633Sdim break; 2931226633Sdim } 2932206124Srdivacky 2933226633Sdim return S; 2934226633Sdim} 2935226633Sdim 2936234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn, 2937226633Sdim uint64_t Address, const void *Decoder) { 2938226633Sdim DecodeStatus S = MCDisassembler::Success; 2939226633Sdim 2940239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2941239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2942239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2943239462Sdim Rm |= fieldFromInstruction(Insn, 5, 1) << 4; 2944239462Sdim unsigned size = fieldFromInstruction(Insn, 18, 2); 2945226633Sdim 2946226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 2947226633Sdim return MCDisassembler::Fail; 2948226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 2949226633Sdim return MCDisassembler::Fail; 2950226633Sdim Inst.addOperand(MCOperand::CreateImm(8 << size)); 2951226633Sdim 2952226633Sdim return S; 2953226633Sdim} 2954226633Sdim 2955234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 2956226633Sdim uint64_t Address, const void *Decoder) { 2957226633Sdim Inst.addOperand(MCOperand::CreateImm(8 - Val)); 2958226633Sdim return MCDisassembler::Success; 2959226633Sdim} 2960226633Sdim 2961234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 2962226633Sdim uint64_t Address, const void *Decoder) { 2963226633Sdim Inst.addOperand(MCOperand::CreateImm(16 - Val)); 2964226633Sdim return MCDisassembler::Success; 2965226633Sdim} 2966226633Sdim 2967234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 2968226633Sdim uint64_t Address, const void *Decoder) { 2969226633Sdim Inst.addOperand(MCOperand::CreateImm(32 - Val)); 2970226633Sdim return MCDisassembler::Success; 2971226633Sdim} 2972226633Sdim 2973234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 2974226633Sdim uint64_t Address, const void *Decoder) { 2975226633Sdim Inst.addOperand(MCOperand::CreateImm(64 - Val)); 2976226633Sdim return MCDisassembler::Success; 2977226633Sdim} 2978226633Sdim 2979234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 2980226633Sdim uint64_t Address, const void *Decoder) { 2981226633Sdim DecodeStatus S = MCDisassembler::Success; 2982226633Sdim 2983239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2984239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2985239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2986239462Sdim Rn |= fieldFromInstruction(Insn, 7, 1) << 4; 2987239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2988239462Sdim Rm |= fieldFromInstruction(Insn, 5, 1) << 4; 2989239462Sdim unsigned op = fieldFromInstruction(Insn, 6, 1); 2990226633Sdim 2991226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2992226633Sdim return MCDisassembler::Fail; 2993226633Sdim if (op) { 2994226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2995226633Sdim return MCDisassembler::Fail; // Writeback 2996206124Srdivacky } 2997226633Sdim 2998234353Sdim switch (Inst.getOpcode()) { 2999234353Sdim case ARM::VTBL2: 3000234353Sdim case ARM::VTBX2: 3001234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder))) 3002234353Sdim return MCDisassembler::Fail; 3003234353Sdim break; 3004234353Sdim default: 3005234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder))) 3006234353Sdim return MCDisassembler::Fail; 3007226633Sdim } 3008226633Sdim 3009226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 3010226633Sdim return MCDisassembler::Fail; 3011226633Sdim 3012226633Sdim return S; 3013206124Srdivacky} 3014206124Srdivacky 3015234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 3016226633Sdim uint64_t Address, const void *Decoder) { 3017226633Sdim DecodeStatus S = MCDisassembler::Success; 3018221345Sdim 3019239462Sdim unsigned dst = fieldFromInstruction(Insn, 8, 3); 3020239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 3021221345Sdim 3022226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder))) 3023226633Sdim return MCDisassembler::Fail; 3024226633Sdim 3025226633Sdim switch(Inst.getOpcode()) { 3026226633Sdim default: 3027226633Sdim return MCDisassembler::Fail; 3028226633Sdim case ARM::tADR: 3029226633Sdim break; // tADR does not explicitly represent the PC as an operand. 3030226633Sdim case ARM::tADDrSPi: 3031226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3032226633Sdim break; 3033221345Sdim } 3034226633Sdim 3035226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3036226633Sdim return S; 3037221345Sdim} 3038221345Sdim 3039234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 3040226633Sdim uint64_t Address, const void *Decoder) { 3041234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4, 3042234353Sdim true, 2, Inst, Decoder)) 3043234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1))); 3044226633Sdim return MCDisassembler::Success; 3045226633Sdim} 3046206124Srdivacky 3047234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 3048226633Sdim uint64_t Address, const void *Decoder) { 3049239462Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4, 3050234353Sdim true, 4, Inst, Decoder)) 3051234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val))); 3052226633Sdim return MCDisassembler::Success; 3053226633Sdim} 3054206124Srdivacky 3055234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 3056226633Sdim uint64_t Address, const void *Decoder) { 3057249423Sdim if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4, 3058234353Sdim true, 2, Inst, Decoder)) 3059249423Sdim Inst.addOperand(MCOperand::CreateImm(Val << 1)); 3060226633Sdim return MCDisassembler::Success; 3061226633Sdim} 3062206124Srdivacky 3063234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 3064226633Sdim uint64_t Address, const void *Decoder) { 3065226633Sdim DecodeStatus S = MCDisassembler::Success; 3066206124Srdivacky 3067239462Sdim unsigned Rn = fieldFromInstruction(Val, 0, 3); 3068239462Sdim unsigned Rm = fieldFromInstruction(Val, 3, 3); 3069226633Sdim 3070226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3071226633Sdim return MCDisassembler::Fail; 3072226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder))) 3073226633Sdim return MCDisassembler::Fail; 3074226633Sdim 3075226633Sdim return S; 3076226633Sdim} 3077226633Sdim 3078234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 3079226633Sdim uint64_t Address, const void *Decoder) { 3080226633Sdim DecodeStatus S = MCDisassembler::Success; 3081226633Sdim 3082239462Sdim unsigned Rn = fieldFromInstruction(Val, 0, 3); 3083239462Sdim unsigned imm = fieldFromInstruction(Val, 3, 5); 3084226633Sdim 3085226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3086226633Sdim return MCDisassembler::Fail; 3087226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3088226633Sdim 3089226633Sdim return S; 3090226633Sdim} 3091226633Sdim 3092234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 3093226633Sdim uint64_t Address, const void *Decoder) { 3094226633Sdim unsigned imm = Val << 2; 3095226633Sdim 3096226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3097226633Sdim tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder); 3098226633Sdim 3099226633Sdim return MCDisassembler::Success; 3100226633Sdim} 3101226633Sdim 3102234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 3103226633Sdim uint64_t Address, const void *Decoder) { 3104226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3105226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3106226633Sdim 3107226633Sdim return MCDisassembler::Success; 3108226633Sdim} 3109226633Sdim 3110234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 3111226633Sdim uint64_t Address, const void *Decoder) { 3112226633Sdim DecodeStatus S = MCDisassembler::Success; 3113226633Sdim 3114239462Sdim unsigned Rn = fieldFromInstruction(Val, 6, 4); 3115239462Sdim unsigned Rm = fieldFromInstruction(Val, 2, 4); 3116239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 2); 3117226633Sdim 3118226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3119226633Sdim return MCDisassembler::Fail; 3120226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3121226633Sdim return MCDisassembler::Fail; 3122226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3123226633Sdim 3124226633Sdim return S; 3125226633Sdim} 3126226633Sdim 3127234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn, 3128226633Sdim uint64_t Address, const void *Decoder) { 3129226633Sdim DecodeStatus S = MCDisassembler::Success; 3130226633Sdim 3131226633Sdim switch (Inst.getOpcode()) { 3132226633Sdim case ARM::t2PLDs: 3133226633Sdim case ARM::t2PLDWs: 3134226633Sdim case ARM::t2PLIs: 3135226633Sdim break; 3136226633Sdim default: { 3137239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3138226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 3139226633Sdim return MCDisassembler::Fail; 3140206124Srdivacky } 3141226633Sdim } 3142206124Srdivacky 3143239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3144226633Sdim if (Rn == 0xF) { 3145226633Sdim switch (Inst.getOpcode()) { 3146226633Sdim case ARM::t2LDRBs: 3147226633Sdim Inst.setOpcode(ARM::t2LDRBpci); 3148226633Sdim break; 3149226633Sdim case ARM::t2LDRHs: 3150226633Sdim Inst.setOpcode(ARM::t2LDRHpci); 3151226633Sdim break; 3152226633Sdim case ARM::t2LDRSHs: 3153226633Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3154226633Sdim break; 3155226633Sdim case ARM::t2LDRSBs: 3156226633Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3157226633Sdim break; 3158226633Sdim case ARM::t2PLDs: 3159226633Sdim Inst.setOpcode(ARM::t2PLDi12); 3160226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::PC)); 3161226633Sdim break; 3162226633Sdim default: 3163226633Sdim return MCDisassembler::Fail; 3164206124Srdivacky } 3165206124Srdivacky 3166239462Sdim int imm = fieldFromInstruction(Insn, 0, 12); 3167239462Sdim if (!fieldFromInstruction(Insn, 23, 1)) imm *= -1; 3168226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3169221345Sdim 3170226633Sdim return S; 3171226633Sdim } 3172226633Sdim 3173239462Sdim unsigned addrmode = fieldFromInstruction(Insn, 4, 2); 3174239462Sdim addrmode |= fieldFromInstruction(Insn, 0, 4) << 2; 3175239462Sdim addrmode |= fieldFromInstruction(Insn, 16, 4) << 6; 3176226633Sdim if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder))) 3177226633Sdim return MCDisassembler::Fail; 3178226633Sdim 3179226633Sdim return S; 3180226633Sdim} 3181226633Sdim 3182234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 3183226633Sdim uint64_t Address, const void *Decoder) { 3184239462Sdim if (Val == 0) 3185239462Sdim Inst.addOperand(MCOperand::CreateImm(INT32_MIN)); 3186239462Sdim else { 3187239462Sdim int imm = Val & 0xFF; 3188226633Sdim 3189239462Sdim if (!(Val & 0x100)) imm *= -1; 3190243830Sdim Inst.addOperand(MCOperand::CreateImm(imm * 4)); 3191239462Sdim } 3192239462Sdim 3193226633Sdim return MCDisassembler::Success; 3194226633Sdim} 3195226633Sdim 3196234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 3197226633Sdim uint64_t Address, const void *Decoder) { 3198226633Sdim DecodeStatus S = MCDisassembler::Success; 3199226633Sdim 3200239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 3201239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 9); 3202226633Sdim 3203226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3204226633Sdim return MCDisassembler::Fail; 3205226633Sdim if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder))) 3206226633Sdim return MCDisassembler::Fail; 3207226633Sdim 3208226633Sdim return S; 3209226633Sdim} 3210226633Sdim 3211234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 3212226633Sdim uint64_t Address, const void *Decoder) { 3213226633Sdim DecodeStatus S = MCDisassembler::Success; 3214226633Sdim 3215239462Sdim unsigned Rn = fieldFromInstruction(Val, 8, 4); 3216239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 3217226633Sdim 3218226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 3219226633Sdim return MCDisassembler::Fail; 3220226633Sdim 3221226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3222226633Sdim 3223226633Sdim return S; 3224226633Sdim} 3225226633Sdim 3226234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 3227226633Sdim uint64_t Address, const void *Decoder) { 3228226633Sdim int imm = Val & 0xFF; 3229226633Sdim if (Val == 0) 3230226633Sdim imm = INT32_MIN; 3231226633Sdim else if (!(Val & 0x100)) 3232226633Sdim imm *= -1; 3233226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3234226633Sdim 3235226633Sdim return MCDisassembler::Success; 3236226633Sdim} 3237226633Sdim 3238226633Sdim 3239234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 3240226633Sdim uint64_t Address, const void *Decoder) { 3241226633Sdim DecodeStatus S = MCDisassembler::Success; 3242226633Sdim 3243239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 3244239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 9); 3245226633Sdim 3246226633Sdim // Some instructions always use an additive offset. 3247226633Sdim switch (Inst.getOpcode()) { 3248226633Sdim case ARM::t2LDRT: 3249226633Sdim case ARM::t2LDRBT: 3250226633Sdim case ARM::t2LDRHT: 3251226633Sdim case ARM::t2LDRSBT: 3252226633Sdim case ARM::t2LDRSHT: 3253226633Sdim case ARM::t2STRT: 3254226633Sdim case ARM::t2STRBT: 3255226633Sdim case ARM::t2STRHT: 3256226633Sdim imm |= 0x100; 3257226633Sdim break; 3258226633Sdim default: 3259226633Sdim break; 3260226633Sdim } 3261226633Sdim 3262226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3263226633Sdim return MCDisassembler::Fail; 3264226633Sdim if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder))) 3265226633Sdim return MCDisassembler::Fail; 3266226633Sdim 3267226633Sdim return S; 3268226633Sdim} 3269226633Sdim 3270234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn, 3271226633Sdim uint64_t Address, const void *Decoder) { 3272226633Sdim DecodeStatus S = MCDisassembler::Success; 3273226633Sdim 3274239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3275239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3276239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 3277239462Sdim addr |= fieldFromInstruction(Insn, 9, 1) << 8; 3278226633Sdim addr |= Rn << 9; 3279239462Sdim unsigned load = fieldFromInstruction(Insn, 20, 1); 3280226633Sdim 3281226633Sdim if (!load) { 3282226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3283226633Sdim return MCDisassembler::Fail; 3284226633Sdim } 3285226633Sdim 3286249423Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3287226633Sdim return MCDisassembler::Fail; 3288226633Sdim 3289226633Sdim if (load) { 3290226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3291226633Sdim return MCDisassembler::Fail; 3292226633Sdim } 3293226633Sdim 3294226633Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder))) 3295226633Sdim return MCDisassembler::Fail; 3296226633Sdim 3297226633Sdim return S; 3298226633Sdim} 3299226633Sdim 3300234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 3301226633Sdim uint64_t Address, const void *Decoder) { 3302226633Sdim DecodeStatus S = MCDisassembler::Success; 3303226633Sdim 3304239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 3305239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 12); 3306226633Sdim 3307226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3308226633Sdim return MCDisassembler::Fail; 3309226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3310226633Sdim 3311226633Sdim return S; 3312226633Sdim} 3313226633Sdim 3314226633Sdim 3315234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn, 3316226633Sdim uint64_t Address, const void *Decoder) { 3317239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 7); 3318226633Sdim 3319226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3320226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3321226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3322226633Sdim 3323226633Sdim return MCDisassembler::Success; 3324226633Sdim} 3325226633Sdim 3326234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 3327226633Sdim uint64_t Address, const void *Decoder) { 3328226633Sdim DecodeStatus S = MCDisassembler::Success; 3329226633Sdim 3330226633Sdim if (Inst.getOpcode() == ARM::tADDrSP) { 3331239462Sdim unsigned Rdm = fieldFromInstruction(Insn, 0, 3); 3332239462Sdim Rdm |= fieldFromInstruction(Insn, 7, 1) << 3; 3333226633Sdim 3334226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 3335226633Sdim return MCDisassembler::Fail; 3336239462Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3337226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 3338226633Sdim return MCDisassembler::Fail; 3339226633Sdim } else if (Inst.getOpcode() == ARM::tADDspr) { 3340239462Sdim unsigned Rm = fieldFromInstruction(Insn, 3, 4); 3341226633Sdim 3342226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3343226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3344226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3345226633Sdim return MCDisassembler::Fail; 3346226633Sdim } 3347226633Sdim 3348226633Sdim return S; 3349226633Sdim} 3350226633Sdim 3351234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 3352226633Sdim uint64_t Address, const void *Decoder) { 3353239462Sdim unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2; 3354239462Sdim unsigned flags = fieldFromInstruction(Insn, 0, 3); 3355226633Sdim 3356226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 3357226633Sdim Inst.addOperand(MCOperand::CreateImm(flags)); 3358226633Sdim 3359226633Sdim return MCDisassembler::Success; 3360226633Sdim} 3361226633Sdim 3362234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 3363226633Sdim uint64_t Address, const void *Decoder) { 3364226633Sdim DecodeStatus S = MCDisassembler::Success; 3365239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3366239462Sdim unsigned add = fieldFromInstruction(Insn, 4, 1); 3367226633Sdim 3368234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 3369226633Sdim return MCDisassembler::Fail; 3370226633Sdim Inst.addOperand(MCOperand::CreateImm(add)); 3371226633Sdim 3372226633Sdim return S; 3373226633Sdim} 3374226633Sdim 3375234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val, 3376226633Sdim uint64_t Address, const void *Decoder) { 3377239462Sdim // Val is passed in as S:J1:J2:imm10H:imm10L:'0' 3378239462Sdim // Note only one trailing zero not two. Also the J1 and J2 values are from 3379239462Sdim // the encoded instruction. So here change to I1 and I2 values via: 3380239462Sdim // I1 = NOT(J1 EOR S); 3381239462Sdim // I2 = NOT(J2 EOR S); 3382239462Sdim // and build the imm32 with two trailing zeros as documented: 3383239462Sdim // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32); 3384239462Sdim unsigned S = (Val >> 23) & 1; 3385239462Sdim unsigned J1 = (Val >> 22) & 1; 3386239462Sdim unsigned J2 = (Val >> 21) & 1; 3387239462Sdim unsigned I1 = !(J1 ^ S); 3388239462Sdim unsigned I2 = !(J2 ^ S); 3389239462Sdim unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); 3390239462Sdim int imm32 = SignExtend32<25>(tmp << 1); 3391239462Sdim 3392234353Sdim if (!tryAddingSymbolicOperand(Address, 3393239462Sdim (Address & ~2u) + imm32 + 4, 3394226633Sdim true, 4, Inst, Decoder)) 3395239462Sdim Inst.addOperand(MCOperand::CreateImm(imm32)); 3396226633Sdim return MCDisassembler::Success; 3397226633Sdim} 3398226633Sdim 3399234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val, 3400226633Sdim uint64_t Address, const void *Decoder) { 3401226633Sdim if (Val == 0xA || Val == 0xB) 3402226633Sdim return MCDisassembler::Fail; 3403226633Sdim 3404226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3405226633Sdim return MCDisassembler::Success; 3406226633Sdim} 3407226633Sdim 3408226633Sdimstatic DecodeStatus 3409234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn, 3410226633Sdim uint64_t Address, const void *Decoder) { 3411226633Sdim DecodeStatus S = MCDisassembler::Success; 3412226633Sdim 3413239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3414239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3415226633Sdim 3416226633Sdim if (Rn == ARM::SP) S = MCDisassembler::SoftFail; 3417226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3418226633Sdim return MCDisassembler::Fail; 3419226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3420226633Sdim return MCDisassembler::Fail; 3421226633Sdim return S; 3422226633Sdim} 3423226633Sdim 3424226633Sdimstatic DecodeStatus 3425234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn, 3426226633Sdim uint64_t Address, const void *Decoder) { 3427226633Sdim DecodeStatus S = MCDisassembler::Success; 3428226633Sdim 3429239462Sdim unsigned pred = fieldFromInstruction(Insn, 22, 4); 3430226633Sdim if (pred == 0xE || pred == 0xF) { 3431239462Sdim unsigned opc = fieldFromInstruction(Insn, 4, 28); 3432226633Sdim switch (opc) { 3433226633Sdim default: 3434226633Sdim return MCDisassembler::Fail; 3435226633Sdim case 0xf3bf8f4: 3436226633Sdim Inst.setOpcode(ARM::t2DSB); 3437226633Sdim break; 3438226633Sdim case 0xf3bf8f5: 3439226633Sdim Inst.setOpcode(ARM::t2DMB); 3440226633Sdim break; 3441226633Sdim case 0xf3bf8f6: 3442226633Sdim Inst.setOpcode(ARM::t2ISB); 3443226633Sdim break; 3444221345Sdim } 3445206124Srdivacky 3446239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 3447226633Sdim return DecodeMemBarrierOption(Inst, imm, Address, Decoder); 3448226633Sdim } 3449226633Sdim 3450239462Sdim unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1; 3451239462Sdim brtarget |= fieldFromInstruction(Insn, 11, 1) << 19; 3452239462Sdim brtarget |= fieldFromInstruction(Insn, 13, 1) << 18; 3453239462Sdim brtarget |= fieldFromInstruction(Insn, 16, 6) << 12; 3454239462Sdim brtarget |= fieldFromInstruction(Insn, 26, 1) << 20; 3455226633Sdim 3456226633Sdim if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder))) 3457226633Sdim return MCDisassembler::Fail; 3458226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3459226633Sdim return MCDisassembler::Fail; 3460226633Sdim 3461226633Sdim return S; 3462226633Sdim} 3463226633Sdim 3464226633Sdim// Decode a shifted immediate operand. These basically consist 3465226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either 3466226633Sdim// a splat operation or a rotation. 3467234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 3468226633Sdim uint64_t Address, const void *Decoder) { 3469239462Sdim unsigned ctrl = fieldFromInstruction(Val, 10, 2); 3470226633Sdim if (ctrl == 0) { 3471239462Sdim unsigned byte = fieldFromInstruction(Val, 8, 2); 3472239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 3473226633Sdim switch (byte) { 3474226633Sdim case 0: 3475226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3476226633Sdim break; 3477226633Sdim case 1: 3478226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm)); 3479226633Sdim break; 3480226633Sdim case 2: 3481226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8))); 3482226633Sdim break; 3483226633Sdim case 3: 3484226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) | 3485226633Sdim (imm << 8) | imm)); 3486226633Sdim break; 3487221345Sdim } 3488226633Sdim } else { 3489239462Sdim unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80; 3490239462Sdim unsigned rot = fieldFromInstruction(Val, 7, 5); 3491226633Sdim unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31)); 3492226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3493226633Sdim } 3494221345Sdim 3495226633Sdim return MCDisassembler::Success; 3496226633Sdim} 3497206124Srdivacky 3498226633Sdimstatic DecodeStatus 3499234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val, 3500226633Sdim uint64_t Address, const void *Decoder){ 3501239462Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4, 3502234353Sdim true, 2, Inst, Decoder)) 3503239462Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1))); 3504226633Sdim return MCDisassembler::Success; 3505226633Sdim} 3506226633Sdim 3507234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 3508226633Sdim uint64_t Address, const void *Decoder){ 3509239462Sdim // Val is passed in as S:J1:J2:imm10:imm11 3510239462Sdim // Note no trailing zero after imm11. Also the J1 and J2 values are from 3511239462Sdim // the encoded instruction. So here change to I1 and I2 values via: 3512239462Sdim // I1 = NOT(J1 EOR S); 3513239462Sdim // I2 = NOT(J2 EOR S); 3514239462Sdim // and build the imm32 with one trailing zero as documented: 3515239462Sdim // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); 3516239462Sdim unsigned S = (Val >> 23) & 1; 3517239462Sdim unsigned J1 = (Val >> 22) & 1; 3518239462Sdim unsigned J2 = (Val >> 21) & 1; 3519239462Sdim unsigned I1 = !(J1 ^ S); 3520239462Sdim unsigned I2 = !(J2 ^ S); 3521239462Sdim unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); 3522239462Sdim int imm32 = SignExtend32<25>(tmp << 1); 3523239462Sdim 3524239462Sdim if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, 3525234353Sdim true, 4, Inst, Decoder)) 3526239462Sdim Inst.addOperand(MCOperand::CreateImm(imm32)); 3527226633Sdim return MCDisassembler::Success; 3528226633Sdim} 3529226633Sdim 3530234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val, 3531226633Sdim uint64_t Address, const void *Decoder) { 3532239462Sdim if (Val & ~0xf) 3533226633Sdim return MCDisassembler::Fail; 3534206124Srdivacky 3535226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3536226633Sdim return MCDisassembler::Success; 3537206124Srdivacky} 3538206124Srdivacky 3539234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, 3540226633Sdim uint64_t Address, const void *Decoder) { 3541226633Sdim if (!Val) return MCDisassembler::Fail; 3542226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3543226633Sdim return MCDisassembler::Success; 3544226633Sdim} 3545206124Srdivacky 3546234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 3547226633Sdim uint64_t Address, const void *Decoder) { 3548226633Sdim DecodeStatus S = MCDisassembler::Success; 3549206124Srdivacky 3550239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3551239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3552239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3553206124Srdivacky 3554226633Sdim if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; 3555206274Srdivacky 3556226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3557226633Sdim return MCDisassembler::Fail; 3558226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 3559226633Sdim return MCDisassembler::Fail; 3560226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3561226633Sdim return MCDisassembler::Fail; 3562226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3563226633Sdim return MCDisassembler::Fail; 3564206124Srdivacky 3565226633Sdim return S; 3566226633Sdim} 3567206124Srdivacky 3568206124Srdivacky 3569234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 3570226633Sdim uint64_t Address, const void *Decoder){ 3571226633Sdim DecodeStatus S = MCDisassembler::Success; 3572221345Sdim 3573239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3574239462Sdim unsigned Rt = fieldFromInstruction(Insn, 0, 4); 3575239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3576239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3577206124Srdivacky 3578251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 3579226633Sdim return MCDisassembler::Fail; 3580226633Sdim 3581226633Sdim if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; 3582226633Sdim if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail; 3583226633Sdim 3584226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3585226633Sdim return MCDisassembler::Fail; 3586226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 3587226633Sdim return MCDisassembler::Fail; 3588226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3589226633Sdim return MCDisassembler::Fail; 3590226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3591226633Sdim return MCDisassembler::Fail; 3592226633Sdim 3593226633Sdim return S; 3594206124Srdivacky} 3595206124Srdivacky 3596234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 3597226633Sdim uint64_t Address, const void *Decoder) { 3598226633Sdim DecodeStatus S = MCDisassembler::Success; 3599206274Srdivacky 3600239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3601239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3602239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 3603239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 3604239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 3605239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3606206124Srdivacky 3607226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3608206124Srdivacky 3609226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3610226633Sdim return MCDisassembler::Fail; 3611226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3612226633Sdim return MCDisassembler::Fail; 3613226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 3614226633Sdim return MCDisassembler::Fail; 3615226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3616226633Sdim return MCDisassembler::Fail; 3617206124Srdivacky 3618226633Sdim return S; 3619226633Sdim} 3620206124Srdivacky 3621234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 3622226633Sdim uint64_t Address, const void *Decoder) { 3623226633Sdim DecodeStatus S = MCDisassembler::Success; 3624226633Sdim 3625239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3626239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3627239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 3628239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 3629239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 3630239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3631239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3632226633Sdim 3633226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3634226633Sdim if (Rm == 0xF) S = MCDisassembler::SoftFail; 3635226633Sdim 3636226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3637226633Sdim return MCDisassembler::Fail; 3638226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3639226633Sdim return MCDisassembler::Fail; 3640226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 3641226633Sdim return MCDisassembler::Fail; 3642226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3643226633Sdim return MCDisassembler::Fail; 3644226633Sdim 3645226633Sdim return S; 3646226633Sdim} 3647226633Sdim 3648226633Sdim 3649234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 3650226633Sdim uint64_t Address, const void *Decoder) { 3651226633Sdim DecodeStatus S = MCDisassembler::Success; 3652226633Sdim 3653239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3654239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3655239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 3656239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 3657239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 3658239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3659226633Sdim 3660226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3661226633Sdim 3662226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3663226633Sdim return MCDisassembler::Fail; 3664226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3665226633Sdim return MCDisassembler::Fail; 3666226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 3667226633Sdim return MCDisassembler::Fail; 3668226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3669226633Sdim return MCDisassembler::Fail; 3670226633Sdim 3671226633Sdim return S; 3672226633Sdim} 3673226633Sdim 3674234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 3675226633Sdim uint64_t Address, const void *Decoder) { 3676226633Sdim DecodeStatus S = MCDisassembler::Success; 3677226633Sdim 3678239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3679239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3680239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 3681239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 3682239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 3683239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3684226633Sdim 3685226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3686226633Sdim 3687226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3688226633Sdim return MCDisassembler::Fail; 3689226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3690226633Sdim return MCDisassembler::Fail; 3691226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 3692226633Sdim return MCDisassembler::Fail; 3693226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3694226633Sdim return MCDisassembler::Fail; 3695226633Sdim 3696226633Sdim return S; 3697226633Sdim} 3698226633Sdim 3699234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 3700226633Sdim uint64_t Address, const void *Decoder) { 3701226633Sdim DecodeStatus S = MCDisassembler::Success; 3702226633Sdim 3703239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3704239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3705239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3706239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3707239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 3708226633Sdim 3709226633Sdim unsigned align = 0; 3710226633Sdim unsigned index = 0; 3711226633Sdim switch (size) { 3712226633Sdim default: 3713226633Sdim return MCDisassembler::Fail; 3714226633Sdim case 0: 3715239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3716226633Sdim return MCDisassembler::Fail; // UNDEFINED 3717239462Sdim index = fieldFromInstruction(Insn, 5, 3); 3718226633Sdim break; 3719226633Sdim case 1: 3720239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3721226633Sdim return MCDisassembler::Fail; // UNDEFINED 3722239462Sdim index = fieldFromInstruction(Insn, 6, 2); 3723239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3724226633Sdim align = 2; 3725226633Sdim break; 3726226633Sdim case 2: 3727239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 3728226633Sdim return MCDisassembler::Fail; // UNDEFINED 3729239462Sdim index = fieldFromInstruction(Insn, 7, 1); 3730243830Sdim 3731243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 3732243830Sdim case 0 : 3733243830Sdim align = 0; break; 3734243830Sdim case 3: 3735243830Sdim align = 4; break; 3736243830Sdim default: 3737243830Sdim return MCDisassembler::Fail; 3738243830Sdim } 3739243830Sdim break; 3740206124Srdivacky } 3741206124Srdivacky 3742226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3743226633Sdim return MCDisassembler::Fail; 3744226633Sdim if (Rm != 0xF) { // Writeback 3745226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3746226633Sdim return MCDisassembler::Fail; 3747226633Sdim } 3748226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3749226633Sdim return MCDisassembler::Fail; 3750226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3751226633Sdim if (Rm != 0xF) { 3752226633Sdim if (Rm != 0xD) { 3753226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3754226633Sdim return MCDisassembler::Fail; 3755226633Sdim } else 3756226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3757226633Sdim } 3758206124Srdivacky 3759226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3760226633Sdim return MCDisassembler::Fail; 3761226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3762206124Srdivacky 3763226633Sdim return S; 3764226633Sdim} 3765206124Srdivacky 3766234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 3767226633Sdim uint64_t Address, const void *Decoder) { 3768226633Sdim DecodeStatus S = MCDisassembler::Success; 3769206124Srdivacky 3770239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3771239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3772239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3773239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3774239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 3775207618Srdivacky 3776226633Sdim unsigned align = 0; 3777226633Sdim unsigned index = 0; 3778226633Sdim switch (size) { 3779226633Sdim default: 3780226633Sdim return MCDisassembler::Fail; 3781226633Sdim case 0: 3782239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3783226633Sdim return MCDisassembler::Fail; // UNDEFINED 3784239462Sdim index = fieldFromInstruction(Insn, 5, 3); 3785226633Sdim break; 3786226633Sdim case 1: 3787239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3788226633Sdim return MCDisassembler::Fail; // UNDEFINED 3789239462Sdim index = fieldFromInstruction(Insn, 6, 2); 3790239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3791226633Sdim align = 2; 3792226633Sdim break; 3793226633Sdim case 2: 3794239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 3795226633Sdim return MCDisassembler::Fail; // UNDEFINED 3796239462Sdim index = fieldFromInstruction(Insn, 7, 1); 3797243830Sdim 3798243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 3799243830Sdim case 0: 3800243830Sdim align = 0; break; 3801243830Sdim case 3: 3802243830Sdim align = 4; break; 3803243830Sdim default: 3804243830Sdim return MCDisassembler::Fail; 3805243830Sdim } 3806243830Sdim break; 3807226633Sdim } 3808221345Sdim 3809226633Sdim if (Rm != 0xF) { // Writeback 3810226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3811226633Sdim return MCDisassembler::Fail; 3812226633Sdim } 3813226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3814226633Sdim return MCDisassembler::Fail; 3815226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3816226633Sdim if (Rm != 0xF) { 3817226633Sdim if (Rm != 0xD) { 3818226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3819226633Sdim return MCDisassembler::Fail; 3820226633Sdim } else 3821226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3822226633Sdim } 3823206124Srdivacky 3824226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3825226633Sdim return MCDisassembler::Fail; 3826226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3827226633Sdim 3828226633Sdim return S; 3829206124Srdivacky} 3830206124Srdivacky 3831226633Sdim 3832234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 3833226633Sdim uint64_t Address, const void *Decoder) { 3834226633Sdim DecodeStatus S = MCDisassembler::Success; 3835226633Sdim 3836239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3837239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3838239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3839239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3840239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 3841226633Sdim 3842226633Sdim unsigned align = 0; 3843226633Sdim unsigned index = 0; 3844226633Sdim unsigned inc = 1; 3845226633Sdim switch (size) { 3846226633Sdim default: 3847226633Sdim return MCDisassembler::Fail; 3848226633Sdim case 0: 3849239462Sdim index = fieldFromInstruction(Insn, 5, 3); 3850239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3851226633Sdim align = 2; 3852226633Sdim break; 3853226633Sdim case 1: 3854239462Sdim index = fieldFromInstruction(Insn, 6, 2); 3855239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3856226633Sdim align = 4; 3857239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3858226633Sdim inc = 2; 3859226633Sdim break; 3860226633Sdim case 2: 3861239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3862226633Sdim return MCDisassembler::Fail; // UNDEFINED 3863239462Sdim index = fieldFromInstruction(Insn, 7, 1); 3864239462Sdim if (fieldFromInstruction(Insn, 4, 1) != 0) 3865226633Sdim align = 8; 3866239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 3867226633Sdim inc = 2; 3868226633Sdim break; 3869207618Srdivacky } 3870226633Sdim 3871226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3872226633Sdim return MCDisassembler::Fail; 3873226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3874226633Sdim return MCDisassembler::Fail; 3875226633Sdim if (Rm != 0xF) { // Writeback 3876226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3877226633Sdim return MCDisassembler::Fail; 3878226633Sdim } 3879226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3880226633Sdim return MCDisassembler::Fail; 3881226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3882226633Sdim if (Rm != 0xF) { 3883226633Sdim if (Rm != 0xD) { 3884226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3885226633Sdim return MCDisassembler::Fail; 3886226633Sdim } else 3887226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3888226633Sdim } 3889226633Sdim 3890226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3891226633Sdim return MCDisassembler::Fail; 3892226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3893226633Sdim return MCDisassembler::Fail; 3894226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3895226633Sdim 3896226633Sdim return S; 3897206124Srdivacky} 3898206124Srdivacky 3899234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 3900226633Sdim uint64_t Address, const void *Decoder) { 3901226633Sdim DecodeStatus S = MCDisassembler::Success; 3902207618Srdivacky 3903239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3904239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3905239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3906239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3907239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 3908226633Sdim 3909226633Sdim unsigned align = 0; 3910226633Sdim unsigned index = 0; 3911226633Sdim unsigned inc = 1; 3912226633Sdim switch (size) { 3913226633Sdim default: 3914226633Sdim return MCDisassembler::Fail; 3915226633Sdim case 0: 3916239462Sdim index = fieldFromInstruction(Insn, 5, 3); 3917239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3918226633Sdim align = 2; 3919226633Sdim break; 3920226633Sdim case 1: 3921239462Sdim index = fieldFromInstruction(Insn, 6, 2); 3922239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3923226633Sdim align = 4; 3924239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3925226633Sdim inc = 2; 3926226633Sdim break; 3927226633Sdim case 2: 3928239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3929226633Sdim return MCDisassembler::Fail; // UNDEFINED 3930239462Sdim index = fieldFromInstruction(Insn, 7, 1); 3931239462Sdim if (fieldFromInstruction(Insn, 4, 1) != 0) 3932226633Sdim align = 8; 3933239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 3934226633Sdim inc = 2; 3935226633Sdim break; 3936207618Srdivacky } 3937226633Sdim 3938226633Sdim if (Rm != 0xF) { // Writeback 3939226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3940226633Sdim return MCDisassembler::Fail; 3941207618Srdivacky } 3942226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3943226633Sdim return MCDisassembler::Fail; 3944226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3945226633Sdim if (Rm != 0xF) { 3946226633Sdim if (Rm != 0xD) { 3947226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3948226633Sdim return MCDisassembler::Fail; 3949226633Sdim } else 3950226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3951226633Sdim } 3952207618Srdivacky 3953226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3954226633Sdim return MCDisassembler::Fail; 3955226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3956226633Sdim return MCDisassembler::Fail; 3957226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3958207618Srdivacky 3959226633Sdim return S; 3960206124Srdivacky} 3961206124Srdivacky 3962226633Sdim 3963234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 3964226633Sdim uint64_t Address, const void *Decoder) { 3965226633Sdim DecodeStatus S = MCDisassembler::Success; 3966226633Sdim 3967239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3968239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3969239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3970239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3971239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 3972226633Sdim 3973226633Sdim unsigned align = 0; 3974226633Sdim unsigned index = 0; 3975226633Sdim unsigned inc = 1; 3976226633Sdim switch (size) { 3977226633Sdim default: 3978226633Sdim return MCDisassembler::Fail; 3979226633Sdim case 0: 3980239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3981226633Sdim return MCDisassembler::Fail; // UNDEFINED 3982239462Sdim index = fieldFromInstruction(Insn, 5, 3); 3983226633Sdim break; 3984226633Sdim case 1: 3985239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 3986226633Sdim return MCDisassembler::Fail; // UNDEFINED 3987239462Sdim index = fieldFromInstruction(Insn, 6, 2); 3988239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 3989226633Sdim inc = 2; 3990226633Sdim break; 3991226633Sdim case 2: 3992239462Sdim if (fieldFromInstruction(Insn, 4, 2)) 3993226633Sdim return MCDisassembler::Fail; // UNDEFINED 3994239462Sdim index = fieldFromInstruction(Insn, 7, 1); 3995239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 3996226633Sdim inc = 2; 3997226633Sdim break; 3998206124Srdivacky } 3999226633Sdim 4000226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4001226633Sdim return MCDisassembler::Fail; 4002226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4003226633Sdim return MCDisassembler::Fail; 4004226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4005226633Sdim return MCDisassembler::Fail; 4006226633Sdim 4007226633Sdim if (Rm != 0xF) { // Writeback 4008226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4009226633Sdim return MCDisassembler::Fail; 4010226633Sdim } 4011226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4012226633Sdim return MCDisassembler::Fail; 4013226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4014226633Sdim if (Rm != 0xF) { 4015226633Sdim if (Rm != 0xD) { 4016226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4017226633Sdim return MCDisassembler::Fail; 4018226633Sdim } else 4019226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4020226633Sdim } 4021226633Sdim 4022226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4023226633Sdim return MCDisassembler::Fail; 4024226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4025226633Sdim return MCDisassembler::Fail; 4026226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4027226633Sdim return MCDisassembler::Fail; 4028226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4029226633Sdim 4030226633Sdim return S; 4031206124Srdivacky} 4032206124Srdivacky 4033234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 4034226633Sdim uint64_t Address, const void *Decoder) { 4035226633Sdim DecodeStatus S = MCDisassembler::Success; 4036226633Sdim 4037239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4038239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4039239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4040239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4041239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4042226633Sdim 4043226633Sdim unsigned align = 0; 4044226633Sdim unsigned index = 0; 4045226633Sdim unsigned inc = 1; 4046226633Sdim switch (size) { 4047226633Sdim default: 4048226633Sdim return MCDisassembler::Fail; 4049226633Sdim case 0: 4050239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4051226633Sdim return MCDisassembler::Fail; // UNDEFINED 4052239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4053226633Sdim break; 4054226633Sdim case 1: 4055239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4056226633Sdim return MCDisassembler::Fail; // UNDEFINED 4057239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4058239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4059226633Sdim inc = 2; 4060226633Sdim break; 4061226633Sdim case 2: 4062239462Sdim if (fieldFromInstruction(Insn, 4, 2)) 4063226633Sdim return MCDisassembler::Fail; // UNDEFINED 4064239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4065239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4066226633Sdim inc = 2; 4067226633Sdim break; 4068226633Sdim } 4069226633Sdim 4070226633Sdim if (Rm != 0xF) { // Writeback 4071226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4072226633Sdim return MCDisassembler::Fail; 4073226633Sdim } 4074226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4075226633Sdim return MCDisassembler::Fail; 4076226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4077226633Sdim if (Rm != 0xF) { 4078226633Sdim if (Rm != 0xD) { 4079226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4080226633Sdim return MCDisassembler::Fail; 4081226633Sdim } else 4082226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4083226633Sdim } 4084226633Sdim 4085226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4086226633Sdim return MCDisassembler::Fail; 4087226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4088226633Sdim return MCDisassembler::Fail; 4089226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4090226633Sdim return MCDisassembler::Fail; 4091226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4092226633Sdim 4093226633Sdim return S; 4094206124Srdivacky} 4095206124Srdivacky 4096226633Sdim 4097234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 4098226633Sdim uint64_t Address, const void *Decoder) { 4099226633Sdim DecodeStatus S = MCDisassembler::Success; 4100226633Sdim 4101239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4102239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4103239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4104239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4105239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4106226633Sdim 4107226633Sdim unsigned align = 0; 4108226633Sdim unsigned index = 0; 4109226633Sdim unsigned inc = 1; 4110226633Sdim switch (size) { 4111226633Sdim default: 4112226633Sdim return MCDisassembler::Fail; 4113226633Sdim case 0: 4114239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4115226633Sdim align = 4; 4116239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4117226633Sdim break; 4118226633Sdim case 1: 4119239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4120226633Sdim align = 8; 4121239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4122239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4123226633Sdim inc = 2; 4124226633Sdim break; 4125226633Sdim case 2: 4126243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4127243830Sdim case 0: 4128243830Sdim align = 0; break; 4129243830Sdim case 3: 4130243830Sdim return MCDisassembler::Fail; 4131243830Sdim default: 4132243830Sdim align = 4 << fieldFromInstruction(Insn, 4, 2); break; 4133243830Sdim } 4134243830Sdim 4135239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4136239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4137226633Sdim inc = 2; 4138226633Sdim break; 4139226633Sdim } 4140226633Sdim 4141226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4142226633Sdim return MCDisassembler::Fail; 4143226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4144226633Sdim return MCDisassembler::Fail; 4145226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4146226633Sdim return MCDisassembler::Fail; 4147226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4148226633Sdim return MCDisassembler::Fail; 4149226633Sdim 4150226633Sdim if (Rm != 0xF) { // Writeback 4151226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4152226633Sdim return MCDisassembler::Fail; 4153226633Sdim } 4154226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4155226633Sdim return MCDisassembler::Fail; 4156226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4157226633Sdim if (Rm != 0xF) { 4158226633Sdim if (Rm != 0xD) { 4159226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4160226633Sdim return MCDisassembler::Fail; 4161226633Sdim } else 4162226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4163226633Sdim } 4164226633Sdim 4165226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4166226633Sdim return MCDisassembler::Fail; 4167226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4168226633Sdim return MCDisassembler::Fail; 4169226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4170226633Sdim return MCDisassembler::Fail; 4171226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4172226633Sdim return MCDisassembler::Fail; 4173226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4174226633Sdim 4175226633Sdim return S; 4176206124Srdivacky} 4177206124Srdivacky 4178234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 4179226633Sdim uint64_t Address, const void *Decoder) { 4180226633Sdim DecodeStatus S = MCDisassembler::Success; 4181226633Sdim 4182239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4183239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4184239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4185239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4186239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4187226633Sdim 4188226633Sdim unsigned align = 0; 4189226633Sdim unsigned index = 0; 4190226633Sdim unsigned inc = 1; 4191226633Sdim switch (size) { 4192226633Sdim default: 4193226633Sdim return MCDisassembler::Fail; 4194226633Sdim case 0: 4195239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4196226633Sdim align = 4; 4197239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4198226633Sdim break; 4199226633Sdim case 1: 4200239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4201226633Sdim align = 8; 4202239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4203239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4204226633Sdim inc = 2; 4205226633Sdim break; 4206226633Sdim case 2: 4207243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4208243830Sdim case 0: 4209243830Sdim align = 0; break; 4210243830Sdim case 3: 4211243830Sdim return MCDisassembler::Fail; 4212243830Sdim default: 4213243830Sdim align = 4 << fieldFromInstruction(Insn, 4, 2); break; 4214243830Sdim } 4215243830Sdim 4216239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4217239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4218226633Sdim inc = 2; 4219226633Sdim break; 4220226633Sdim } 4221226633Sdim 4222226633Sdim if (Rm != 0xF) { // Writeback 4223226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4224226633Sdim return MCDisassembler::Fail; 4225226633Sdim } 4226226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4227226633Sdim return MCDisassembler::Fail; 4228226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4229226633Sdim if (Rm != 0xF) { 4230226633Sdim if (Rm != 0xD) { 4231226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4232226633Sdim return MCDisassembler::Fail; 4233226633Sdim } else 4234226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4235226633Sdim } 4236226633Sdim 4237226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4238226633Sdim return MCDisassembler::Fail; 4239226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4240226633Sdim return MCDisassembler::Fail; 4241226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4242226633Sdim return MCDisassembler::Fail; 4243226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4244226633Sdim return MCDisassembler::Fail; 4245226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4246226633Sdim 4247226633Sdim return S; 4248206124Srdivacky} 4249206124Srdivacky 4250234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 4251226633Sdim uint64_t Address, const void *Decoder) { 4252226633Sdim DecodeStatus S = MCDisassembler::Success; 4253239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4254239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 4255239462Sdim unsigned Rm = fieldFromInstruction(Insn, 5, 1); 4256239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4257239462Sdim Rm |= fieldFromInstruction(Insn, 0, 4) << 1; 4258226633Sdim 4259226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 4260226633Sdim S = MCDisassembler::SoftFail; 4261226633Sdim 4262226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 4263226633Sdim return MCDisassembler::Fail; 4264226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 4265226633Sdim return MCDisassembler::Fail; 4266226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 4267226633Sdim return MCDisassembler::Fail; 4268226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 4269226633Sdim return MCDisassembler::Fail; 4270226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4271226633Sdim return MCDisassembler::Fail; 4272226633Sdim 4273226633Sdim return S; 4274207618Srdivacky} 4275207618Srdivacky 4276234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 4277226633Sdim uint64_t Address, const void *Decoder) { 4278226633Sdim DecodeStatus S = MCDisassembler::Success; 4279239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4280239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 4281239462Sdim unsigned Rm = fieldFromInstruction(Insn, 5, 1); 4282239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4283239462Sdim Rm |= fieldFromInstruction(Insn, 0, 4) << 1; 4284226633Sdim 4285226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 4286226633Sdim S = MCDisassembler::SoftFail; 4287226633Sdim 4288226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 4289226633Sdim return MCDisassembler::Fail; 4290226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 4291226633Sdim return MCDisassembler::Fail; 4292226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 4293226633Sdim return MCDisassembler::Fail; 4294226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 4295226633Sdim return MCDisassembler::Fail; 4296226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4297226633Sdim return MCDisassembler::Fail; 4298226633Sdim 4299226633Sdim return S; 4300207618Srdivacky} 4301226633Sdim 4302234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, 4303226633Sdim uint64_t Address, const void *Decoder) { 4304226633Sdim DecodeStatus S = MCDisassembler::Success; 4305239462Sdim unsigned pred = fieldFromInstruction(Insn, 4, 4); 4306239462Sdim unsigned mask = fieldFromInstruction(Insn, 0, 4); 4307226633Sdim 4308226633Sdim if (pred == 0xF) { 4309226633Sdim pred = 0xE; 4310226633Sdim S = MCDisassembler::SoftFail; 4311226633Sdim } 4312226633Sdim 4313239462Sdim if (mask == 0x0) { 4314226633Sdim mask |= 0x8; 4315226633Sdim S = MCDisassembler::SoftFail; 4316226633Sdim } 4317226633Sdim 4318226633Sdim Inst.addOperand(MCOperand::CreateImm(pred)); 4319226633Sdim Inst.addOperand(MCOperand::CreateImm(mask)); 4320226633Sdim return S; 4321226633Sdim} 4322226633Sdim 4323226633Sdimstatic DecodeStatus 4324234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn, 4325226633Sdim uint64_t Address, const void *Decoder) { 4326226633Sdim DecodeStatus S = MCDisassembler::Success; 4327226633Sdim 4328239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4329239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); 4330239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4331239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 4332239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 4333239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 4334239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 4335226633Sdim bool writeback = (W == 1) | (P == 0); 4336226633Sdim 4337226633Sdim addr |= (U << 8) | (Rn << 9); 4338226633Sdim 4339226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 4340226633Sdim Check(S, MCDisassembler::SoftFail); 4341226633Sdim if (Rt == Rt2) 4342226633Sdim Check(S, MCDisassembler::SoftFail); 4343226633Sdim 4344226633Sdim // Rt 4345226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4346226633Sdim return MCDisassembler::Fail; 4347226633Sdim // Rt2 4348226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 4349226633Sdim return MCDisassembler::Fail; 4350226633Sdim // Writeback operand 4351226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4352226633Sdim return MCDisassembler::Fail; 4353226633Sdim // addr 4354226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 4355226633Sdim return MCDisassembler::Fail; 4356226633Sdim 4357226633Sdim return S; 4358226633Sdim} 4359226633Sdim 4360226633Sdimstatic DecodeStatus 4361234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn, 4362226633Sdim uint64_t Address, const void *Decoder) { 4363226633Sdim DecodeStatus S = MCDisassembler::Success; 4364226633Sdim 4365239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4366239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); 4367239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4368239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 4369239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 4370239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 4371239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 4372226633Sdim bool writeback = (W == 1) | (P == 0); 4373226633Sdim 4374226633Sdim addr |= (U << 8) | (Rn << 9); 4375226633Sdim 4376226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 4377226633Sdim Check(S, MCDisassembler::SoftFail); 4378226633Sdim 4379226633Sdim // Writeback operand 4380226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4381226633Sdim return MCDisassembler::Fail; 4382226633Sdim // Rt 4383226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4384226633Sdim return MCDisassembler::Fail; 4385226633Sdim // Rt2 4386226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 4387226633Sdim return MCDisassembler::Fail; 4388226633Sdim // addr 4389226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 4390226633Sdim return MCDisassembler::Fail; 4391226633Sdim 4392226633Sdim return S; 4393226633Sdim} 4394226633Sdim 4395234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, 4396226633Sdim uint64_t Address, const void *Decoder) { 4397239462Sdim unsigned sign1 = fieldFromInstruction(Insn, 21, 1); 4398239462Sdim unsigned sign2 = fieldFromInstruction(Insn, 23, 1); 4399226633Sdim if (sign1 != sign2) return MCDisassembler::Fail; 4400226633Sdim 4401239462Sdim unsigned Val = fieldFromInstruction(Insn, 0, 8); 4402239462Sdim Val |= fieldFromInstruction(Insn, 12, 3) << 8; 4403239462Sdim Val |= fieldFromInstruction(Insn, 26, 1) << 11; 4404226633Sdim Val |= sign1 << 12; 4405226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val))); 4406226633Sdim 4407226633Sdim return MCDisassembler::Success; 4408226633Sdim} 4409226633Sdim 4410234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val, 4411226633Sdim uint64_t Address, 4412226633Sdim const void *Decoder) { 4413226633Sdim DecodeStatus S = MCDisassembler::Success; 4414226633Sdim 4415226633Sdim // Shift of "asr #32" is not allowed in Thumb2 mode. 4416226633Sdim if (Val == 0x20) S = MCDisassembler::SoftFail; 4417226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 4418226633Sdim return S; 4419226633Sdim} 4420226633Sdim 4421234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 4422234353Sdim uint64_t Address, const void *Decoder) { 4423239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4424239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 0, 4); 4425239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4426239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4427234353Sdim 4428234353Sdim if (pred == 0xF) 4429234353Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 4430234353Sdim 4431234353Sdim DecodeStatus S = MCDisassembler::Success; 4432234982Sdim 4433234982Sdim if (Rt == Rn || Rn == Rt2) 4434234982Sdim S = MCDisassembler::SoftFail; 4435234982Sdim 4436234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4437234353Sdim return MCDisassembler::Fail; 4438234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 4439234353Sdim return MCDisassembler::Fail; 4440234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4441234353Sdim return MCDisassembler::Fail; 4442234353Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4443234353Sdim return MCDisassembler::Fail; 4444234353Sdim 4445234353Sdim return S; 4446234353Sdim} 4447234353Sdim 4448234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 4449234353Sdim uint64_t Address, const void *Decoder) { 4450239462Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 4451239462Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 4452239462Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 4453239462Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 4454239462Sdim unsigned imm = fieldFromInstruction(Insn, 16, 6); 4455239462Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 4456234353Sdim 4457234353Sdim DecodeStatus S = MCDisassembler::Success; 4458234353Sdim 4459234353Sdim // VMOVv2f32 is ambiguous with these decodings. 4460234353Sdim if (!(imm & 0x38) && cmode == 0xF) { 4461234353Sdim Inst.setOpcode(ARM::VMOVv2f32); 4462234353Sdim return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); 4463234353Sdim } 4464234353Sdim 4465234353Sdim if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail); 4466234353Sdim 4467234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 4468234353Sdim return MCDisassembler::Fail; 4469234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder))) 4470234353Sdim return MCDisassembler::Fail; 4471234353Sdim Inst.addOperand(MCOperand::CreateImm(64 - imm)); 4472234353Sdim 4473234353Sdim return S; 4474234353Sdim} 4475234353Sdim 4476234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 4477234353Sdim uint64_t Address, const void *Decoder) { 4478239462Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 4479239462Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 4480239462Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 4481239462Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 4482239462Sdim unsigned imm = fieldFromInstruction(Insn, 16, 6); 4483239462Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 4484234353Sdim 4485234353Sdim DecodeStatus S = MCDisassembler::Success; 4486234353Sdim 4487234353Sdim // VMOVv4f32 is ambiguous with these decodings. 4488234353Sdim if (!(imm & 0x38) && cmode == 0xF) { 4489234353Sdim Inst.setOpcode(ARM::VMOVv4f32); 4490234353Sdim return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); 4491234353Sdim } 4492234353Sdim 4493234353Sdim if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail); 4494234353Sdim 4495234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder))) 4496234353Sdim return MCDisassembler::Fail; 4497234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder))) 4498234353Sdim return MCDisassembler::Fail; 4499234353Sdim Inst.addOperand(MCOperand::CreateImm(64 - imm)); 4500234353Sdim 4501234353Sdim return S; 4502234353Sdim} 4503234353Sdim 4504251662Sdimstatic DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address, 4505251662Sdim const void *Decoder) 4506251662Sdim{ 4507251662Sdim unsigned Imm = fieldFromInstruction(Insn, 0, 3); 4508251662Sdim if (Imm > 4) return MCDisassembler::Fail; 4509251662Sdim Inst.addOperand(MCOperand::CreateImm(Imm)); 4510251662Sdim return MCDisassembler::Success; 4511251662Sdim} 4512251662Sdim 4513234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 4514234353Sdim uint64_t Address, const void *Decoder) { 4515234353Sdim DecodeStatus S = MCDisassembler::Success; 4516234353Sdim 4517239462Sdim unsigned Rn = fieldFromInstruction(Val, 16, 4); 4518239462Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 4519239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 4520239462Sdim Rm |= (fieldFromInstruction(Val, 23, 1) << 4); 4521239462Sdim unsigned Cond = fieldFromInstruction(Val, 28, 4); 4522234353Sdim 4523239462Sdim if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt) 4524234353Sdim S = MCDisassembler::SoftFail; 4525234353Sdim 4526234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4527234353Sdim return MCDisassembler::Fail; 4528234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4529234353Sdim return MCDisassembler::Fail; 4530234353Sdim if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder))) 4531234353Sdim return MCDisassembler::Fail; 4532234353Sdim if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder))) 4533234353Sdim return MCDisassembler::Fail; 4534234353Sdim if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder))) 4535234353Sdim return MCDisassembler::Fail; 4536234353Sdim 4537234353Sdim return S; 4538234353Sdim} 4539234353Sdim 4540234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, 4541234982Sdim uint64_t Address, const void *Decoder) { 4542234982Sdim 4543234982Sdim DecodeStatus S = MCDisassembler::Success; 4544234982Sdim 4545239462Sdim unsigned CRm = fieldFromInstruction(Val, 0, 4); 4546239462Sdim unsigned opc1 = fieldFromInstruction(Val, 4, 4); 4547239462Sdim unsigned cop = fieldFromInstruction(Val, 8, 4); 4548239462Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 4549239462Sdim unsigned Rt2 = fieldFromInstruction(Val, 16, 4); 4550234982Sdim 4551234982Sdim if ((cop & ~0x1) == 0xa) 4552234982Sdim return MCDisassembler::Fail; 4553234982Sdim 4554234982Sdim if (Rt == Rt2) 4555234982Sdim S = MCDisassembler::SoftFail; 4556234982Sdim 4557234982Sdim Inst.addOperand(MCOperand::CreateImm(cop)); 4558234982Sdim Inst.addOperand(MCOperand::CreateImm(opc1)); 4559234982Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4560234982Sdim return MCDisassembler::Fail; 4561234982Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 4562234982Sdim return MCDisassembler::Fail; 4563234982Sdim Inst.addOperand(MCOperand::CreateImm(CRm)); 4564234982Sdim 4565234982Sdim return S; 4566234982Sdim} 4567234982Sdim 4568