ARMDisassembler.cpp revision 234982
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 12226633Sdim#include "MCTargetDesc/ARMAddressingModes.h" 13226633Sdim#include "MCTargetDesc/ARMMCExpr.h" 14226633Sdim#include "MCTargetDesc/ARMBaseInfo.h" 15207618Srdivacky#include "llvm/MC/EDInstInfo.h" 16206124Srdivacky#include "llvm/MC/MCInst.h" 17234353Sdim#include "llvm/MC/MCInstrDesc.h" 18226633Sdim#include "llvm/MC/MCExpr.h" 19226633Sdim#include "llvm/MC/MCContext.h" 20226633Sdim#include "llvm/MC/MCDisassembler.h" 21234353Sdim#include "llvm/MC/MCSubtargetInfo.h" 22206124Srdivacky#include "llvm/Support/Debug.h" 23206124Srdivacky#include "llvm/Support/MemoryObject.h" 24206124Srdivacky#include "llvm/Support/ErrorHandling.h" 25226633Sdim#include "llvm/Support/TargetRegistry.h" 26206124Srdivacky#include "llvm/Support/raw_ostream.h" 27206124Srdivacky 28226633Sdimusing namespace llvm; 29212904Sdim 30226633Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus; 31206124Srdivacky 32226633Sdimnamespace { 33226633Sdim/// ARMDisassembler - ARM disassembler for all ARM platforms. 34226633Sdimclass ARMDisassembler : public MCDisassembler { 35226633Sdimpublic: 36226633Sdim /// Constructor - Initializes the disassembler. 37226633Sdim /// 38226633Sdim ARMDisassembler(const MCSubtargetInfo &STI) : 39226633Sdim MCDisassembler(STI) { 40226633Sdim } 41226633Sdim 42226633Sdim ~ARMDisassembler() { 43226633Sdim } 44226633Sdim 45226633Sdim /// getInstruction - See MCDisassembler. 46226633Sdim DecodeStatus getInstruction(MCInst &instr, 47226633Sdim uint64_t &size, 48226633Sdim const MemoryObject ®ion, 49226633Sdim uint64_t address, 50226633Sdim raw_ostream &vStream, 51226633Sdim raw_ostream &cStream) const; 52226633Sdim 53226633Sdim /// getEDInfo - See MCDisassembler. 54234353Sdim const EDInstInfo *getEDInfo() const; 55226633Sdimprivate: 56226633Sdim}; 57226633Sdim 58226633Sdim/// ThumbDisassembler - Thumb disassembler for all Thumb platforms. 59226633Sdimclass ThumbDisassembler : public MCDisassembler { 60226633Sdimpublic: 61226633Sdim /// Constructor - Initializes the disassembler. 62226633Sdim /// 63226633Sdim ThumbDisassembler(const MCSubtargetInfo &STI) : 64226633Sdim MCDisassembler(STI) { 65226633Sdim } 66226633Sdim 67226633Sdim ~ThumbDisassembler() { 68226633Sdim } 69226633Sdim 70226633Sdim /// getInstruction - See MCDisassembler. 71226633Sdim DecodeStatus getInstruction(MCInst &instr, 72226633Sdim uint64_t &size, 73226633Sdim const MemoryObject ®ion, 74226633Sdim uint64_t address, 75226633Sdim raw_ostream &vStream, 76226633Sdim raw_ostream &cStream) const; 77226633Sdim 78226633Sdim /// getEDInfo - See MCDisassembler. 79234353Sdim const EDInstInfo *getEDInfo() const; 80226633Sdimprivate: 81226633Sdim mutable std::vector<unsigned> ITBlock; 82226633Sdim DecodeStatus AddThumbPredicate(MCInst&) const; 83226633Sdim void UpdateThumbVFPPredicate(MCInst&) const; 84226633Sdim}; 85226633Sdim} 86226633Sdim 87226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) { 88226633Sdim switch (In) { 89226633Sdim case MCDisassembler::Success: 90226633Sdim // Out stays the same. 91226633Sdim return true; 92226633Sdim case MCDisassembler::SoftFail: 93226633Sdim Out = In; 94226633Sdim return true; 95226633Sdim case MCDisassembler::Fail: 96226633Sdim Out = In; 97226633Sdim return false; 98226633Sdim } 99234353Sdim llvm_unreachable("Invalid DecodeStatus!"); 100226633Sdim} 101226633Sdim 102226633Sdim 103226633Sdim// Forward declare these because the autogenerated code will reference them. 104226633Sdim// Definitions are further down. 105234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 106226633Sdim uint64_t Address, const void *Decoder); 107234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, 108226633Sdim unsigned RegNo, uint64_t Address, 109226633Sdim const void *Decoder); 110234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 111226633Sdim uint64_t Address, const void *Decoder); 112234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 113226633Sdim uint64_t Address, const void *Decoder); 114234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 115226633Sdim uint64_t Address, const void *Decoder); 116234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 117226633Sdim uint64_t Address, const void *Decoder); 118234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 119226633Sdim uint64_t Address, const void *Decoder); 120234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 121226633Sdim uint64_t Address, const void *Decoder); 122234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, 123226633Sdim unsigned RegNo, 124226633Sdim uint64_t Address, 125226633Sdim const void *Decoder); 126234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 127226633Sdim uint64_t Address, const void *Decoder); 128234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 129234353Sdim uint64_t Address, const void *Decoder); 130234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 131234353Sdim unsigned RegNo, uint64_t Address, 132234353Sdim const void *Decoder); 133226633Sdim 134234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 135226633Sdim uint64_t Address, const void *Decoder); 136234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 137226633Sdim uint64_t Address, const void *Decoder); 138234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, 139226633Sdim uint64_t Address, const void *Decoder); 140234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 141226633Sdim uint64_t Address, const void *Decoder); 142234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 143226633Sdim uint64_t Address, const void *Decoder); 144234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 145226633Sdim uint64_t Address, const void *Decoder); 146226633Sdim 147234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn, 148226633Sdim uint64_t Address, const void *Decoder); 149234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 150226633Sdim uint64_t Address, const void *Decoder); 151234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst, 152226633Sdim unsigned Insn, 153226633Sdim uint64_t Address, 154226633Sdim const void *Decoder); 155234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn, 156226633Sdim uint64_t Address, const void *Decoder); 157234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn, 158226633Sdim uint64_t Address, const void *Decoder); 159234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn, 160226633Sdim uint64_t Address, const void *Decoder); 161234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn, 162226633Sdim uint64_t Address, const void *Decoder); 163226633Sdim 164234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst, 165226633Sdim unsigned Insn, 166226633Sdim uint64_t Adddress, 167226633Sdim const void *Decoder); 168234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 169226633Sdim uint64_t Address, const void *Decoder); 170234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 171226633Sdim uint64_t Address, const void *Decoder); 172234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 173226633Sdim uint64_t Address, const void *Decoder); 174234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 175226633Sdim uint64_t Address, const void *Decoder); 176234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 177226633Sdim uint64_t Address, const void *Decoder); 178234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 179226633Sdim uint64_t Address, const void *Decoder); 180234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 181226633Sdim uint64_t Address, const void *Decoder); 182234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 183226633Sdim uint64_t Address, const void *Decoder); 184234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn, 185226633Sdim uint64_t Address, const void *Decoder); 186234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn, 187226633Sdim uint64_t Address, const void *Decoder); 188234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 189226633Sdim uint64_t Address, const void *Decoder); 190234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val, 191226633Sdim uint64_t Address, const void *Decoder); 192234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val, 193226633Sdim uint64_t Address, const void *Decoder); 194234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val, 195226633Sdim uint64_t Address, const void *Decoder); 196234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val, 197226633Sdim uint64_t Address, const void *Decoder); 198234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val, 199226633Sdim uint64_t Address, const void *Decoder); 200234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val, 201226633Sdim uint64_t Address, const void *Decoder); 202234353Sdimstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val, 203226633Sdim uint64_t Address, const void *Decoder); 204234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val, 205226633Sdim uint64_t Address, const void *Decoder); 206234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 207226633Sdim uint64_t Address, const void *Decoder); 208234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 209226633Sdim uint64_t Address, const void *Decoder); 210234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 211226633Sdim uint64_t Address, const void *Decoder); 212234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 213226633Sdim uint64_t Address, const void *Decoder); 214234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 215226633Sdim uint64_t Address, const void *Decoder); 216234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 217226633Sdim uint64_t Address, const void *Decoder); 218234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn, 219226633Sdim uint64_t Address, const void *Decoder); 220234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn, 221226633Sdim uint64_t Address, const void *Decoder); 222234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, 223226633Sdim uint64_t Address, const void *Decoder); 224234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 225226633Sdim uint64_t Address, const void *Decoder); 226234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 227226633Sdim uint64_t Address, const void *Decoder); 228234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 229226633Sdim uint64_t Address, const void *Decoder); 230234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 231226633Sdim uint64_t Address, const void *Decoder); 232234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 233226633Sdim uint64_t Address, const void *Decoder); 234234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 235226633Sdim uint64_t Address, const void *Decoder); 236234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 237226633Sdim uint64_t Address, const void *Decoder); 238234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 239226633Sdim uint64_t Address, const void *Decoder); 240234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 241226633Sdim uint64_t Address, const void *Decoder); 242234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 243226633Sdim uint64_t Address, const void *Decoder); 244234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 245226633Sdim uint64_t Address, const void *Decoder); 246234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 247226633Sdim uint64_t Address, const void *Decoder); 248234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 249226633Sdim uint64_t Address, const void *Decoder); 250234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 251226633Sdim uint64_t Address, const void *Decoder); 252234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 253226633Sdim uint64_t Address, const void *Decoder); 254234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 255226633Sdim uint64_t Address, const void *Decoder); 256234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 257234353Sdim uint64_t Address, const void *Decoder); 258234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 259234353Sdim uint64_t Address, const void *Decoder); 260234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 261234353Sdim uint64_t Address, const void *Decoder); 262226633Sdim 263234353Sdim 264234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 265226633Sdim uint64_t Address, const void *Decoder); 266234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 267226633Sdim uint64_t Address, const void *Decoder); 268234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 269226633Sdim uint64_t Address, const void *Decoder); 270234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 271226633Sdim uint64_t Address, const void *Decoder); 272234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 273226633Sdim uint64_t Address, const void *Decoder); 274234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 275226633Sdim uint64_t Address, const void *Decoder); 276234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 277226633Sdim uint64_t Address, const void *Decoder); 278234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 279226633Sdim uint64_t Address, const void *Decoder); 280234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 281226633Sdim uint64_t Address, const void *Decoder); 282234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val, 283226633Sdim uint64_t Address, const void *Decoder); 284234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 285226633Sdim uint64_t Address, const void *Decoder); 286234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 287226633Sdim uint64_t Address, const void *Decoder); 288234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 289226633Sdim uint64_t Address, const void *Decoder); 290234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 291226633Sdim uint64_t Address, const void *Decoder); 292234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 293226633Sdim uint64_t Address, const void *Decoder); 294234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val, 295226633Sdim uint64_t Address, const void *Decoder); 296234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 297226633Sdim uint64_t Address, const void *Decoder); 298234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 299226633Sdim uint64_t Address, const void *Decoder); 300234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn, 301226633Sdim uint64_t Address, const void *Decoder); 302234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 303226633Sdim uint64_t Address, const void *Decoder); 304234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val, 305226633Sdim uint64_t Address, const void *Decoder); 306234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val, 307226633Sdim uint64_t Address, const void *Decoder); 308234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 309226633Sdim uint64_t Address, const void *Decoder); 310234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val, 311226633Sdim uint64_t Address, const void *Decoder); 312234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 313226633Sdim uint64_t Address, const void *Decoder); 314234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, 315226633Sdim uint64_t Address, const void *Decoder); 316234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn, 317226633Sdim uint64_t Address, const void *Decoder); 318234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn, 319226633Sdim uint64_t Address, const void *Decoder); 320234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, 321226633Sdim uint64_t Address, const void *Decoder); 322234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val, 323226633Sdim uint64_t Address, const void *Decoder); 324234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, 325226633Sdim uint64_t Address, const void *Decoder); 326226633Sdim 327234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 328234353Sdim uint64_t Address, const void *Decoder); 329234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, 330234982Sdim uint64_t Address, const void *Decoder); 331226633Sdim#include "ARMGenDisassemblerTables.inc" 332226633Sdim#include "ARMGenInstrInfo.inc" 333218893Sdim#include "ARMGenEDInfo.inc" 334206124Srdivacky 335226633Sdimstatic MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) { 336226633Sdim return new ARMDisassembler(STI); 337226633Sdim} 338207618Srdivacky 339226633Sdimstatic MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) { 340226633Sdim return new ThumbDisassembler(STI); 341226633Sdim} 342226633Sdim 343234353Sdimconst EDInstInfo *ARMDisassembler::getEDInfo() const { 344226633Sdim return instInfoARM; 345226633Sdim} 346226633Sdim 347234353Sdimconst EDInstInfo *ThumbDisassembler::getEDInfo() const { 348226633Sdim return instInfoARM; 349226633Sdim} 350226633Sdim 351226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 352226633Sdim const MemoryObject &Region, 353226633Sdim uint64_t Address, 354226633Sdim raw_ostream &os, 355226633Sdim raw_ostream &cs) const { 356226633Sdim CommentStream = &cs; 357226633Sdim 358226633Sdim uint8_t bytes[4]; 359226633Sdim 360226633Sdim assert(!(STI.getFeatureBits() & ARM::ModeThumb) && 361226633Sdim "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!"); 362226633Sdim 363226633Sdim // We want to read exactly 4 bytes of data. 364226633Sdim if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { 365226633Sdim Size = 0; 366226633Sdim return MCDisassembler::Fail; 367206124Srdivacky } 368226633Sdim 369226633Sdim // Encoded as a small-endian 32-bit word in the stream. 370226633Sdim uint32_t insn = (bytes[3] << 24) | 371226633Sdim (bytes[2] << 16) | 372226633Sdim (bytes[1] << 8) | 373226633Sdim (bytes[0] << 0); 374226633Sdim 375226633Sdim // Calling the auto-generated decoder function. 376226633Sdim DecodeStatus result = decodeARMInstruction32(MI, insn, Address, this, STI); 377226633Sdim if (result != MCDisassembler::Fail) { 378226633Sdim Size = 4; 379226633Sdim return result; 380226633Sdim } 381226633Sdim 382226633Sdim // VFP and NEON instructions, similarly, are shared between ARM 383226633Sdim // and Thumb modes. 384226633Sdim MI.clear(); 385226633Sdim result = decodeVFPInstruction32(MI, insn, Address, this, STI); 386226633Sdim if (result != MCDisassembler::Fail) { 387226633Sdim Size = 4; 388226633Sdim return result; 389226633Sdim } 390226633Sdim 391226633Sdim MI.clear(); 392226633Sdim result = decodeNEONDataInstruction32(MI, insn, Address, this, STI); 393226633Sdim if (result != MCDisassembler::Fail) { 394226633Sdim Size = 4; 395226633Sdim // Add a fake predicate operand, because we share these instruction 396226633Sdim // definitions with Thumb2 where these instructions are predicable. 397226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 398226633Sdim return MCDisassembler::Fail; 399226633Sdim return result; 400226633Sdim } 401226633Sdim 402226633Sdim MI.clear(); 403226633Sdim result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this, STI); 404226633Sdim if (result != MCDisassembler::Fail) { 405226633Sdim Size = 4; 406226633Sdim // Add a fake predicate operand, because we share these instruction 407226633Sdim // definitions with Thumb2 where these instructions are predicable. 408226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 409226633Sdim return MCDisassembler::Fail; 410226633Sdim return result; 411226633Sdim } 412226633Sdim 413226633Sdim MI.clear(); 414226633Sdim result = decodeNEONDupInstruction32(MI, insn, Address, this, STI); 415226633Sdim if (result != MCDisassembler::Fail) { 416226633Sdim Size = 4; 417226633Sdim // Add a fake predicate operand, because we share these instruction 418226633Sdim // definitions with Thumb2 where these instructions are predicable. 419226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 420226633Sdim return MCDisassembler::Fail; 421226633Sdim return result; 422226633Sdim } 423226633Sdim 424226633Sdim MI.clear(); 425226633Sdim 426226633Sdim Size = 0; 427226633Sdim return MCDisassembler::Fail; 428206124Srdivacky} 429206124Srdivacky 430226633Sdimnamespace llvm { 431234353Sdimextern const MCInstrDesc ARMInsts[]; 432226633Sdim} 433206124Srdivacky 434226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 435226633Sdim/// immediate Value in the MCInst. The immediate Value has had any PC 436226633Sdim/// adjustment made by the caller. If the instruction is a branch instruction 437226633Sdim/// then isBranch is true, else false. If the getOpInfo() function was set as 438226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called 439226633Sdim/// to get any symbolic information at the Address for this instruction. If 440226633Sdim/// that returns non-zero then the symbolic information it returns is used to 441226633Sdim/// create an MCExpr and that is added as an operand to the MCInst. If 442226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for 443226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else 444226633Sdim/// an MCExpr with Value is created. This function returns true if it adds an 445226633Sdim/// operand to the MCInst and false otherwise. 446226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value, 447226633Sdim bool isBranch, uint64_t InstSize, 448226633Sdim MCInst &MI, const void *Decoder) { 449226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 450226633Sdim LLVMOpInfoCallback getOpInfo = Dis->getLLVMOpInfoCallback(); 451226633Sdim struct LLVMOpInfo1 SymbolicOp; 452234353Sdim memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1)); 453226633Sdim SymbolicOp.Value = Value; 454226633Sdim void *DisInfo = Dis->getDisInfoBlock(); 455234353Sdim 456234353Sdim if (!getOpInfo || 457234353Sdim !getOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp)) { 458234353Sdim // Clear SymbolicOp.Value from above and also all other fields. 459234353Sdim memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1)); 460234353Sdim LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback(); 461234353Sdim if (!SymbolLookUp) 462234353Sdim return false; 463234353Sdim uint64_t ReferenceType; 464234353Sdim if (isBranch) 465234353Sdim ReferenceType = LLVMDisassembler_ReferenceType_In_Branch; 466234353Sdim else 467234353Sdim ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; 468234353Sdim const char *ReferenceName; 469234353Sdim const char *Name = SymbolLookUp(DisInfo, Value, &ReferenceType, Address, 470234353Sdim &ReferenceName); 471234353Sdim if (Name) { 472234353Sdim SymbolicOp.AddSymbol.Name = Name; 473234353Sdim SymbolicOp.AddSymbol.Present = true; 474226633Sdim } 475234353Sdim // For branches always create an MCExpr so it gets printed as hex address. 476234353Sdim else if (isBranch) { 477234353Sdim SymbolicOp.Value = Value; 478234353Sdim } 479234353Sdim if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub) 480234353Sdim (*Dis->CommentStream) << "symbol stub for: " << ReferenceName; 481234353Sdim if (!Name && !isBranch) 482226633Sdim return false; 483226633Sdim } 484226633Sdim 485226633Sdim MCContext *Ctx = Dis->getMCContext(); 486226633Sdim const MCExpr *Add = NULL; 487226633Sdim if (SymbolicOp.AddSymbol.Present) { 488226633Sdim if (SymbolicOp.AddSymbol.Name) { 489226633Sdim StringRef Name(SymbolicOp.AddSymbol.Name); 490226633Sdim MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name); 491226633Sdim Add = MCSymbolRefExpr::Create(Sym, *Ctx); 492226633Sdim } else { 493226633Sdim Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx); 494226633Sdim } 495226633Sdim } 496226633Sdim 497226633Sdim const MCExpr *Sub = NULL; 498226633Sdim if (SymbolicOp.SubtractSymbol.Present) { 499226633Sdim if (SymbolicOp.SubtractSymbol.Name) { 500226633Sdim StringRef Name(SymbolicOp.SubtractSymbol.Name); 501226633Sdim MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name); 502226633Sdim Sub = MCSymbolRefExpr::Create(Sym, *Ctx); 503226633Sdim } else { 504226633Sdim Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx); 505226633Sdim } 506226633Sdim } 507226633Sdim 508226633Sdim const MCExpr *Off = NULL; 509226633Sdim if (SymbolicOp.Value != 0) 510226633Sdim Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx); 511226633Sdim 512226633Sdim const MCExpr *Expr; 513226633Sdim if (Sub) { 514226633Sdim const MCExpr *LHS; 515226633Sdim if (Add) 516226633Sdim LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx); 517206124Srdivacky else 518226633Sdim LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx); 519226633Sdim if (Off != 0) 520226633Sdim Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx); 521226633Sdim else 522226633Sdim Expr = LHS; 523226633Sdim } else if (Add) { 524226633Sdim if (Off != 0) 525226633Sdim Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx); 526226633Sdim else 527226633Sdim Expr = Add; 528226633Sdim } else { 529226633Sdim if (Off != 0) 530226633Sdim Expr = Off; 531226633Sdim else 532226633Sdim Expr = MCConstantExpr::Create(0, *Ctx); 533206124Srdivacky } 534206124Srdivacky 535226633Sdim if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16) 536226633Sdim MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx))); 537226633Sdim else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16) 538226633Sdim MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx))); 539226633Sdim else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None) 540226633Sdim MI.addOperand(MCOperand::CreateExpr(Expr)); 541234353Sdim else 542234353Sdim llvm_unreachable("bad SymbolicOp.VariantKind"); 543212904Sdim 544226633Sdim return true; 545226633Sdim} 546226633Sdim 547226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being 548226633Sdim/// referenced by a load instruction with the base register that is the Pc. 549226633Sdim/// These can often be values in a literal pool near the Address of the 550226633Sdim/// instruction. The Address of the instruction and its immediate Value are 551226633Sdim/// used as a possible literal pool entry. The SymbolLookUp call back will 552226633Sdim/// return the name of a symbol referenced by the the literal pool's entry if 553226633Sdim/// the referenced address is that of a symbol. Or it will return a pointer to 554226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry 555226633Sdim/// is an address into a section with 'C' string literals. 556226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value, 557234353Sdim const void *Decoder) { 558226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 559226633Sdim LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback(); 560226633Sdim if (SymbolLookUp) { 561226633Sdim void *DisInfo = Dis->getDisInfoBlock(); 562226633Sdim uint64_t ReferenceType; 563226633Sdim ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load; 564226633Sdim const char *ReferenceName; 565226633Sdim (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName); 566226633Sdim if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr || 567226633Sdim ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr) 568226633Sdim (*Dis->CommentStream) << "literal pool for: " << ReferenceName; 569206124Srdivacky } 570226633Sdim} 571206124Srdivacky 572226633Sdim// Thumb1 instructions don't have explicit S bits. Rather, they 573226633Sdim// implicitly set CPSR. Since it's not represented in the encoding, the 574226633Sdim// auto-generated decoder won't inject the CPSR operand. We need to fix 575226633Sdim// that as a post-pass. 576226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) { 577226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 578226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 579226633Sdim MCInst::iterator I = MI.begin(); 580226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 581226633Sdim if (I == MI.end()) break; 582226633Sdim if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) { 583226633Sdim if (i > 0 && OpInfo[i-1].isPredicate()) continue; 584226633Sdim MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); 585226633Sdim return; 586226633Sdim } 587226633Sdim } 588206124Srdivacky 589226633Sdim MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); 590226633Sdim} 591206124Srdivacky 592226633Sdim// Most Thumb instructions don't have explicit predicates in the 593226633Sdim// encoding, but rather get their predicates from IT context. We need 594226633Sdim// to fix up the predicate operands using this context information as a 595226633Sdim// post-pass. 596226633SdimMCDisassembler::DecodeStatus 597226633SdimThumbDisassembler::AddThumbPredicate(MCInst &MI) const { 598226633Sdim MCDisassembler::DecodeStatus S = Success; 599206124Srdivacky 600226633Sdim // A few instructions actually have predicates encoded in them. Don't 601226633Sdim // try to overwrite it if we're seeing one of those. 602226633Sdim switch (MI.getOpcode()) { 603226633Sdim case ARM::tBcc: 604226633Sdim case ARM::t2Bcc: 605226633Sdim case ARM::tCBZ: 606226633Sdim case ARM::tCBNZ: 607226633Sdim case ARM::tCPS: 608226633Sdim case ARM::t2CPS3p: 609226633Sdim case ARM::t2CPS2p: 610226633Sdim case ARM::t2CPS1p: 611226633Sdim case ARM::tMOVSr: 612226633Sdim case ARM::tSETEND: 613226633Sdim // Some instructions (mostly conditional branches) are not 614226633Sdim // allowed in IT blocks. 615226633Sdim if (!ITBlock.empty()) 616226633Sdim S = SoftFail; 617226633Sdim else 618226633Sdim return Success; 619226633Sdim break; 620226633Sdim case ARM::tB: 621226633Sdim case ARM::t2B: 622226633Sdim case ARM::t2TBB: 623226633Sdim case ARM::t2TBH: 624226633Sdim // Some instructions (mostly unconditional branches) can 625226633Sdim // only appears at the end of, or outside of, an IT. 626226633Sdim if (ITBlock.size() > 1) 627226633Sdim S = SoftFail; 628226633Sdim break; 629226633Sdim default: 630226633Sdim break; 631226633Sdim } 632226633Sdim 633226633Sdim // If we're in an IT block, base the predicate on that. Otherwise, 634226633Sdim // assume a predicate of AL. 635226633Sdim unsigned CC; 636226633Sdim if (!ITBlock.empty()) { 637226633Sdim CC = ITBlock.back(); 638226633Sdim if (CC == 0xF) 639226633Sdim CC = ARMCC::AL; 640226633Sdim ITBlock.pop_back(); 641226633Sdim } else 642226633Sdim CC = ARMCC::AL; 643226633Sdim 644226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 645226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 646226633Sdim MCInst::iterator I = MI.begin(); 647226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 648226633Sdim if (I == MI.end()) break; 649226633Sdim if (OpInfo[i].isPredicate()) { 650226633Sdim I = MI.insert(I, MCOperand::CreateImm(CC)); 651226633Sdim ++I; 652226633Sdim if (CC == ARMCC::AL) 653226633Sdim MI.insert(I, MCOperand::CreateReg(0)); 654226633Sdim else 655226633Sdim MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 656226633Sdim return S; 657226633Sdim } 658226633Sdim } 659226633Sdim 660226633Sdim I = MI.insert(I, MCOperand::CreateImm(CC)); 661226633Sdim ++I; 662226633Sdim if (CC == ARMCC::AL) 663226633Sdim MI.insert(I, MCOperand::CreateReg(0)); 664226633Sdim else 665226633Sdim MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 666226633Sdim 667226633Sdim return S; 668226633Sdim} 669226633Sdim 670226633Sdim// Thumb VFP instructions are a special case. Because we share their 671226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM 672226633Sdim// mode, the auto-generated decoder will give them an (incorrect) 673226633Sdim// predicate operand. We need to rewrite these operands based on the IT 674226633Sdim// context as a post-pass. 675226633Sdimvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const { 676226633Sdim unsigned CC; 677226633Sdim if (!ITBlock.empty()) { 678226633Sdim CC = ITBlock.back(); 679226633Sdim ITBlock.pop_back(); 680226633Sdim } else 681226633Sdim CC = ARMCC::AL; 682226633Sdim 683226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 684226633Sdim MCInst::iterator I = MI.begin(); 685226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 686226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 687226633Sdim if (OpInfo[i].isPredicate() ) { 688226633Sdim I->setImm(CC); 689226633Sdim ++I; 690226633Sdim if (CC == ARMCC::AL) 691226633Sdim I->setReg(0); 692226633Sdim else 693226633Sdim I->setReg(ARM::CPSR); 694226633Sdim return; 695226633Sdim } 696226633Sdim } 697226633Sdim} 698226633Sdim 699226633SdimDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 700226633Sdim const MemoryObject &Region, 701226633Sdim uint64_t Address, 702226633Sdim raw_ostream &os, 703226633Sdim raw_ostream &cs) const { 704226633Sdim CommentStream = &cs; 705226633Sdim 706226633Sdim uint8_t bytes[4]; 707226633Sdim 708226633Sdim assert((STI.getFeatureBits() & ARM::ModeThumb) && 709226633Sdim "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!"); 710226633Sdim 711226633Sdim // We want to read exactly 2 bytes of data. 712226633Sdim if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) { 713226633Sdim Size = 0; 714226633Sdim return MCDisassembler::Fail; 715226633Sdim } 716226633Sdim 717226633Sdim uint16_t insn16 = (bytes[1] << 8) | bytes[0]; 718226633Sdim DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this, STI); 719226633Sdim if (result != MCDisassembler::Fail) { 720226633Sdim Size = 2; 721226633Sdim Check(result, AddThumbPredicate(MI)); 722226633Sdim return result; 723226633Sdim } 724226633Sdim 725226633Sdim MI.clear(); 726226633Sdim result = decodeThumbSBitInstruction16(MI, insn16, Address, this, STI); 727226633Sdim if (result) { 728226633Sdim Size = 2; 729226633Sdim bool InITBlock = !ITBlock.empty(); 730226633Sdim Check(result, AddThumbPredicate(MI)); 731226633Sdim AddThumb1SBit(MI, InITBlock); 732226633Sdim return result; 733226633Sdim } 734226633Sdim 735226633Sdim MI.clear(); 736226633Sdim result = decodeThumb2Instruction16(MI, insn16, Address, this, STI); 737226633Sdim if (result != MCDisassembler::Fail) { 738226633Sdim Size = 2; 739226633Sdim 740226633Sdim // Nested IT blocks are UNPREDICTABLE. Must be checked before we add 741226633Sdim // the Thumb predicate. 742226633Sdim if (MI.getOpcode() == ARM::t2IT && !ITBlock.empty()) 743226633Sdim result = MCDisassembler::SoftFail; 744226633Sdim 745226633Sdim Check(result, AddThumbPredicate(MI)); 746226633Sdim 747226633Sdim // If we find an IT instruction, we need to parse its condition 748226633Sdim // code and mask operands so that we can apply them correctly 749226633Sdim // to the subsequent instructions. 750226633Sdim if (MI.getOpcode() == ARM::t2IT) { 751226633Sdim 752226633Sdim // (3 - the number of trailing zeros) is the number of then / else. 753226633Sdim unsigned firstcond = MI.getOperand(0).getImm(); 754226633Sdim unsigned Mask = MI.getOperand(1).getImm(); 755226633Sdim unsigned CondBit0 = Mask >> 4 & 1; 756226633Sdim unsigned NumTZ = CountTrailingZeros_32(Mask); 757226633Sdim assert(NumTZ <= 3 && "Invalid IT mask!"); 758226633Sdim for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 759226633Sdim bool T = ((Mask >> Pos) & 1) == CondBit0; 760226633Sdim if (T) 761226633Sdim ITBlock.insert(ITBlock.begin(), firstcond); 762226633Sdim else 763226633Sdim ITBlock.insert(ITBlock.begin(), firstcond ^ 1); 764206124Srdivacky } 765226633Sdim 766226633Sdim ITBlock.push_back(firstcond); 767226633Sdim } 768226633Sdim 769226633Sdim return result; 770226633Sdim } 771226633Sdim 772226633Sdim // We want to read exactly 4 bytes of data. 773226633Sdim if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { 774226633Sdim Size = 0; 775226633Sdim return MCDisassembler::Fail; 776226633Sdim } 777226633Sdim 778226633Sdim uint32_t insn32 = (bytes[3] << 8) | 779226633Sdim (bytes[2] << 0) | 780226633Sdim (bytes[1] << 24) | 781226633Sdim (bytes[0] << 16); 782226633Sdim MI.clear(); 783226633Sdim result = decodeThumbInstruction32(MI, insn32, Address, this, STI); 784226633Sdim if (result != MCDisassembler::Fail) { 785226633Sdim Size = 4; 786226633Sdim bool InITBlock = ITBlock.size(); 787226633Sdim Check(result, AddThumbPredicate(MI)); 788226633Sdim AddThumb1SBit(MI, InITBlock); 789226633Sdim return result; 790226633Sdim } 791226633Sdim 792226633Sdim MI.clear(); 793226633Sdim result = decodeThumb2Instruction32(MI, insn32, Address, this, STI); 794226633Sdim if (result != MCDisassembler::Fail) { 795226633Sdim Size = 4; 796226633Sdim Check(result, AddThumbPredicate(MI)); 797226633Sdim return result; 798226633Sdim } 799226633Sdim 800226633Sdim MI.clear(); 801226633Sdim result = decodeVFPInstruction32(MI, insn32, Address, this, STI); 802226633Sdim if (result != MCDisassembler::Fail) { 803226633Sdim Size = 4; 804226633Sdim UpdateThumbVFPPredicate(MI); 805226633Sdim return result; 806226633Sdim } 807226633Sdim 808226633Sdim MI.clear(); 809226633Sdim result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI); 810226633Sdim if (result != MCDisassembler::Fail) { 811226633Sdim Size = 4; 812226633Sdim Check(result, AddThumbPredicate(MI)); 813226633Sdim return result; 814226633Sdim } 815226633Sdim 816226633Sdim if (fieldFromInstruction32(insn32, 24, 8) == 0xF9) { 817226633Sdim MI.clear(); 818226633Sdim uint32_t NEONLdStInsn = insn32; 819226633Sdim NEONLdStInsn &= 0xF0FFFFFF; 820226633Sdim NEONLdStInsn |= 0x04000000; 821226633Sdim result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI); 822226633Sdim if (result != MCDisassembler::Fail) { 823226633Sdim Size = 4; 824226633Sdim Check(result, AddThumbPredicate(MI)); 825226633Sdim return result; 826226633Sdim } 827226633Sdim } 828226633Sdim 829226633Sdim if (fieldFromInstruction32(insn32, 24, 4) == 0xF) { 830226633Sdim MI.clear(); 831226633Sdim uint32_t NEONDataInsn = insn32; 832226633Sdim NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24 833226633Sdim NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 834226633Sdim NEONDataInsn |= 0x12000000; // Set bits 28 and 25 835226633Sdim result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI); 836226633Sdim if (result != MCDisassembler::Fail) { 837226633Sdim Size = 4; 838226633Sdim Check(result, AddThumbPredicate(MI)); 839226633Sdim return result; 840226633Sdim } 841226633Sdim } 842226633Sdim 843226633Sdim Size = 0; 844226633Sdim return MCDisassembler::Fail; 845226633Sdim} 846226633Sdim 847226633Sdim 848226633Sdimextern "C" void LLVMInitializeARMDisassembler() { 849226633Sdim TargetRegistry::RegisterMCDisassembler(TheARMTarget, 850226633Sdim createARMDisassembler); 851226633Sdim TargetRegistry::RegisterMCDisassembler(TheThumbTarget, 852226633Sdim createThumbDisassembler); 853226633Sdim} 854226633Sdim 855234353Sdimstatic const uint16_t GPRDecoderTable[] = { 856226633Sdim ARM::R0, ARM::R1, ARM::R2, ARM::R3, 857226633Sdim ARM::R4, ARM::R5, ARM::R6, ARM::R7, 858226633Sdim ARM::R8, ARM::R9, ARM::R10, ARM::R11, 859226633Sdim ARM::R12, ARM::SP, ARM::LR, ARM::PC 860226633Sdim}; 861226633Sdim 862234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 863226633Sdim uint64_t Address, const void *Decoder) { 864226633Sdim if (RegNo > 15) 865226633Sdim return MCDisassembler::Fail; 866226633Sdim 867226633Sdim unsigned Register = GPRDecoderTable[RegNo]; 868226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 869226633Sdim return MCDisassembler::Success; 870226633Sdim} 871226633Sdim 872226633Sdimstatic DecodeStatus 873234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo, 874226633Sdim uint64_t Address, const void *Decoder) { 875234353Sdim DecodeStatus S = MCDisassembler::Success; 876234353Sdim 877234353Sdim if (RegNo == 15) 878234353Sdim S = MCDisassembler::SoftFail; 879234353Sdim 880234353Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 881234353Sdim 882234353Sdim return S; 883226633Sdim} 884226633Sdim 885234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 886226633Sdim uint64_t Address, const void *Decoder) { 887226633Sdim if (RegNo > 7) 888226633Sdim return MCDisassembler::Fail; 889226633Sdim return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 890226633Sdim} 891226633Sdim 892234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 893226633Sdim uint64_t Address, const void *Decoder) { 894226633Sdim unsigned Register = 0; 895226633Sdim switch (RegNo) { 896226633Sdim case 0: 897226633Sdim Register = ARM::R0; 898206124Srdivacky break; 899226633Sdim case 1: 900226633Sdim Register = ARM::R1; 901226633Sdim break; 902226633Sdim case 2: 903226633Sdim Register = ARM::R2; 904226633Sdim break; 905206124Srdivacky case 3: 906226633Sdim Register = ARM::R3; 907206124Srdivacky break; 908226633Sdim case 9: 909226633Sdim Register = ARM::R9; 910226633Sdim break; 911226633Sdim case 12: 912226633Sdim Register = ARM::R12; 913226633Sdim break; 914206124Srdivacky default: 915226633Sdim return MCDisassembler::Fail; 916206124Srdivacky } 917226633Sdim 918226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 919226633Sdim return MCDisassembler::Success; 920226633Sdim} 921226633Sdim 922234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 923226633Sdim uint64_t Address, const void *Decoder) { 924226633Sdim if (RegNo == 13 || RegNo == 15) return MCDisassembler::Fail; 925226633Sdim return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 926226633Sdim} 927226633Sdim 928234353Sdimstatic const uint16_t SPRDecoderTable[] = { 929226633Sdim ARM::S0, ARM::S1, ARM::S2, ARM::S3, 930226633Sdim ARM::S4, ARM::S5, ARM::S6, ARM::S7, 931226633Sdim ARM::S8, ARM::S9, ARM::S10, ARM::S11, 932226633Sdim ARM::S12, ARM::S13, ARM::S14, ARM::S15, 933226633Sdim ARM::S16, ARM::S17, ARM::S18, ARM::S19, 934226633Sdim ARM::S20, ARM::S21, ARM::S22, ARM::S23, 935226633Sdim ARM::S24, ARM::S25, ARM::S26, ARM::S27, 936226633Sdim ARM::S28, ARM::S29, ARM::S30, ARM::S31 937226633Sdim}; 938226633Sdim 939234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 940226633Sdim uint64_t Address, const void *Decoder) { 941226633Sdim if (RegNo > 31) 942226633Sdim return MCDisassembler::Fail; 943226633Sdim 944226633Sdim unsigned Register = SPRDecoderTable[RegNo]; 945226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 946226633Sdim return MCDisassembler::Success; 947226633Sdim} 948226633Sdim 949234353Sdimstatic const uint16_t DPRDecoderTable[] = { 950226633Sdim ARM::D0, ARM::D1, ARM::D2, ARM::D3, 951226633Sdim ARM::D4, ARM::D5, ARM::D6, ARM::D7, 952226633Sdim ARM::D8, ARM::D9, ARM::D10, ARM::D11, 953226633Sdim ARM::D12, ARM::D13, ARM::D14, ARM::D15, 954226633Sdim ARM::D16, ARM::D17, ARM::D18, ARM::D19, 955226633Sdim ARM::D20, ARM::D21, ARM::D22, ARM::D23, 956226633Sdim ARM::D24, ARM::D25, ARM::D26, ARM::D27, 957226633Sdim ARM::D28, ARM::D29, ARM::D30, ARM::D31 958226633Sdim}; 959226633Sdim 960234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 961226633Sdim uint64_t Address, const void *Decoder) { 962226633Sdim if (RegNo > 31) 963226633Sdim return MCDisassembler::Fail; 964226633Sdim 965226633Sdim unsigned Register = DPRDecoderTable[RegNo]; 966226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 967226633Sdim return MCDisassembler::Success; 968226633Sdim} 969226633Sdim 970234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 971226633Sdim uint64_t Address, const void *Decoder) { 972226633Sdim if (RegNo > 7) 973226633Sdim return MCDisassembler::Fail; 974226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 975226633Sdim} 976226633Sdim 977226633Sdimstatic DecodeStatus 978234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo, 979226633Sdim uint64_t Address, const void *Decoder) { 980226633Sdim if (RegNo > 15) 981226633Sdim return MCDisassembler::Fail; 982226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 983226633Sdim} 984226633Sdim 985234353Sdimstatic const uint16_t QPRDecoderTable[] = { 986226633Sdim ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3, 987226633Sdim ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7, 988226633Sdim ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11, 989226633Sdim ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15 990226633Sdim}; 991226633Sdim 992226633Sdim 993234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 994226633Sdim uint64_t Address, const void *Decoder) { 995226633Sdim if (RegNo > 31) 996226633Sdim return MCDisassembler::Fail; 997226633Sdim RegNo >>= 1; 998226633Sdim 999226633Sdim unsigned Register = QPRDecoderTable[RegNo]; 1000226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1001226633Sdim return MCDisassembler::Success; 1002226633Sdim} 1003226633Sdim 1004234353Sdimstatic const uint16_t DPairDecoderTable[] = { 1005234353Sdim ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6, 1006234353Sdim ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12, 1007234353Sdim ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18, 1008234353Sdim ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24, 1009234353Sdim ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30, 1010234353Sdim ARM::Q15 1011234353Sdim}; 1012234353Sdim 1013234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 1014234353Sdim uint64_t Address, const void *Decoder) { 1015234353Sdim if (RegNo > 30) 1016234353Sdim return MCDisassembler::Fail; 1017234353Sdim 1018234353Sdim unsigned Register = DPairDecoderTable[RegNo]; 1019234353Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1020234353Sdim return MCDisassembler::Success; 1021234353Sdim} 1022234353Sdim 1023234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = { 1024234353Sdim ARM::D0_D2, ARM::D1_D3, ARM::D2_D4, ARM::D3_D5, 1025234353Sdim ARM::D4_D6, ARM::D5_D7, ARM::D6_D8, ARM::D7_D9, 1026234353Sdim ARM::D8_D10, ARM::D9_D11, ARM::D10_D12, ARM::D11_D13, 1027234353Sdim ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17, 1028234353Sdim ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21, 1029234353Sdim ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25, 1030234353Sdim ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29, 1031234353Sdim ARM::D28_D30, ARM::D29_D31 1032234353Sdim}; 1033234353Sdim 1034234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 1035234353Sdim unsigned RegNo, 1036234353Sdim uint64_t Address, 1037234353Sdim const void *Decoder) { 1038234353Sdim if (RegNo > 29) 1039234353Sdim return MCDisassembler::Fail; 1040234353Sdim 1041234353Sdim unsigned Register = DPairSpacedDecoderTable[RegNo]; 1042234353Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1043234353Sdim return MCDisassembler::Success; 1044234353Sdim} 1045234353Sdim 1046234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 1047226633Sdim uint64_t Address, const void *Decoder) { 1048226633Sdim if (Val == 0xF) return MCDisassembler::Fail; 1049226633Sdim // AL predicate is not allowed on Thumb1 branches. 1050226633Sdim if (Inst.getOpcode() == ARM::tBcc && Val == 0xE) 1051226633Sdim return MCDisassembler::Fail; 1052226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 1053226633Sdim if (Val == ARMCC::AL) { 1054226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1055226633Sdim } else 1056226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1057226633Sdim return MCDisassembler::Success; 1058226633Sdim} 1059226633Sdim 1060234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 1061226633Sdim uint64_t Address, const void *Decoder) { 1062226633Sdim if (Val) 1063226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1064226633Sdim else 1065226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1066226633Sdim return MCDisassembler::Success; 1067226633Sdim} 1068226633Sdim 1069234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, 1070226633Sdim uint64_t Address, const void *Decoder) { 1071226633Sdim uint32_t imm = Val & 0xFF; 1072226633Sdim uint32_t rot = (Val & 0xF00) >> 7; 1073226633Sdim uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F)); 1074226633Sdim Inst.addOperand(MCOperand::CreateImm(rot_imm)); 1075226633Sdim return MCDisassembler::Success; 1076226633Sdim} 1077226633Sdim 1078234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val, 1079226633Sdim uint64_t Address, const void *Decoder) { 1080226633Sdim DecodeStatus S = MCDisassembler::Success; 1081226633Sdim 1082226633Sdim unsigned Rm = fieldFromInstruction32(Val, 0, 4); 1083226633Sdim unsigned type = fieldFromInstruction32(Val, 5, 2); 1084226633Sdim unsigned imm = fieldFromInstruction32(Val, 7, 5); 1085226633Sdim 1086226633Sdim // Register-immediate 1087226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1088226633Sdim return MCDisassembler::Fail; 1089226633Sdim 1090226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1091226633Sdim switch (type) { 1092226633Sdim case 0: 1093226633Sdim Shift = ARM_AM::lsl; 1094226633Sdim break; 1095226633Sdim case 1: 1096226633Sdim Shift = ARM_AM::lsr; 1097226633Sdim break; 1098226633Sdim case 2: 1099226633Sdim Shift = ARM_AM::asr; 1100226633Sdim break; 1101226633Sdim case 3: 1102226633Sdim Shift = ARM_AM::ror; 1103226633Sdim break; 1104206124Srdivacky } 1105206124Srdivacky 1106226633Sdim if (Shift == ARM_AM::ror && imm == 0) 1107226633Sdim Shift = ARM_AM::rrx; 1108226633Sdim 1109226633Sdim unsigned Op = Shift | (imm << 3); 1110226633Sdim Inst.addOperand(MCOperand::CreateImm(Op)); 1111226633Sdim 1112226633Sdim return S; 1113226633Sdim} 1114226633Sdim 1115234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val, 1116226633Sdim uint64_t Address, const void *Decoder) { 1117226633Sdim DecodeStatus S = MCDisassembler::Success; 1118226633Sdim 1119226633Sdim unsigned Rm = fieldFromInstruction32(Val, 0, 4); 1120226633Sdim unsigned type = fieldFromInstruction32(Val, 5, 2); 1121226633Sdim unsigned Rs = fieldFromInstruction32(Val, 8, 4); 1122226633Sdim 1123226633Sdim // Register-register 1124226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1125226633Sdim return MCDisassembler::Fail; 1126226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder))) 1127226633Sdim return MCDisassembler::Fail; 1128226633Sdim 1129226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1130226633Sdim switch (type) { 1131226633Sdim case 0: 1132226633Sdim Shift = ARM_AM::lsl; 1133206124Srdivacky break; 1134226633Sdim case 1: 1135226633Sdim Shift = ARM_AM::lsr; 1136206124Srdivacky break; 1137226633Sdim case 2: 1138226633Sdim Shift = ARM_AM::asr; 1139206124Srdivacky break; 1140226633Sdim case 3: 1141226633Sdim Shift = ARM_AM::ror; 1142226633Sdim break; 1143226633Sdim } 1144226633Sdim 1145226633Sdim Inst.addOperand(MCOperand::CreateImm(Shift)); 1146226633Sdim 1147226633Sdim return S; 1148226633Sdim} 1149226633Sdim 1150234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 1151226633Sdim uint64_t Address, const void *Decoder) { 1152226633Sdim DecodeStatus S = MCDisassembler::Success; 1153226633Sdim 1154226633Sdim bool writebackLoad = false; 1155226633Sdim unsigned writebackReg = 0; 1156226633Sdim switch (Inst.getOpcode()) { 1157206124Srdivacky default: 1158226633Sdim break; 1159226633Sdim case ARM::LDMIA_UPD: 1160226633Sdim case ARM::LDMDB_UPD: 1161226633Sdim case ARM::LDMIB_UPD: 1162226633Sdim case ARM::LDMDA_UPD: 1163226633Sdim case ARM::t2LDMIA_UPD: 1164226633Sdim case ARM::t2LDMDB_UPD: 1165226633Sdim writebackLoad = true; 1166226633Sdim writebackReg = Inst.getOperand(0).getReg(); 1167226633Sdim break; 1168226633Sdim } 1169226633Sdim 1170226633Sdim // Empty register lists are not allowed. 1171226633Sdim if (CountPopulation_32(Val) == 0) return MCDisassembler::Fail; 1172226633Sdim for (unsigned i = 0; i < 16; ++i) { 1173226633Sdim if (Val & (1 << i)) { 1174226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder))) 1175226633Sdim return MCDisassembler::Fail; 1176226633Sdim // Writeback not allowed if Rn is in the target list. 1177226633Sdim if (writebackLoad && writebackReg == Inst.end()[-1].getReg()) 1178226633Sdim Check(S, MCDisassembler::SoftFail); 1179206124Srdivacky } 1180206124Srdivacky } 1181206124Srdivacky 1182226633Sdim return S; 1183226633Sdim} 1184226633Sdim 1185234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 1186226633Sdim uint64_t Address, const void *Decoder) { 1187226633Sdim DecodeStatus S = MCDisassembler::Success; 1188226633Sdim 1189226633Sdim unsigned Vd = fieldFromInstruction32(Val, 8, 4); 1190226633Sdim unsigned regs = Val & 0xFF; 1191226633Sdim 1192226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder))) 1193226633Sdim return MCDisassembler::Fail; 1194226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1195226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1196226633Sdim return MCDisassembler::Fail; 1197226633Sdim } 1198226633Sdim 1199226633Sdim return S; 1200226633Sdim} 1201226633Sdim 1202234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 1203226633Sdim uint64_t Address, const void *Decoder) { 1204226633Sdim DecodeStatus S = MCDisassembler::Success; 1205226633Sdim 1206226633Sdim unsigned Vd = fieldFromInstruction32(Val, 8, 4); 1207226633Sdim unsigned regs = (Val & 0xFF) / 2; 1208226633Sdim 1209226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 1210226633Sdim return MCDisassembler::Fail; 1211226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1212226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1213226633Sdim return MCDisassembler::Fail; 1214226633Sdim } 1215226633Sdim 1216226633Sdim return S; 1217226633Sdim} 1218226633Sdim 1219234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val, 1220226633Sdim uint64_t Address, const void *Decoder) { 1221226633Sdim // This operand encodes a mask of contiguous zeros between a specified MSB 1222226633Sdim // and LSB. To decode it, we create the mask of all bits MSB-and-lower, 1223226633Sdim // the mask of all bits LSB-and-lower, and then xor them to create 1224226633Sdim // the mask of that's all ones on [msb, lsb]. Finally we not it to 1225226633Sdim // create the final mask. 1226226633Sdim unsigned msb = fieldFromInstruction32(Val, 5, 5); 1227226633Sdim unsigned lsb = fieldFromInstruction32(Val, 0, 5); 1228226633Sdim 1229226633Sdim DecodeStatus S = MCDisassembler::Success; 1230226633Sdim if (lsb > msb) Check(S, MCDisassembler::SoftFail); 1231226633Sdim 1232226633Sdim uint32_t msb_mask = 0xFFFFFFFF; 1233226633Sdim if (msb != 31) msb_mask = (1U << (msb+1)) - 1; 1234226633Sdim uint32_t lsb_mask = (1U << lsb) - 1; 1235226633Sdim 1236226633Sdim Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask))); 1237226633Sdim return S; 1238226633Sdim} 1239226633Sdim 1240234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 1241226633Sdim uint64_t Address, const void *Decoder) { 1242226633Sdim DecodeStatus S = MCDisassembler::Success; 1243226633Sdim 1244226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 1245226633Sdim unsigned CRd = fieldFromInstruction32(Insn, 12, 4); 1246226633Sdim unsigned coproc = fieldFromInstruction32(Insn, 8, 4); 1247226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 8); 1248226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 1249226633Sdim unsigned U = fieldFromInstruction32(Insn, 23, 1); 1250226633Sdim 1251226633Sdim switch (Inst.getOpcode()) { 1252226633Sdim case ARM::LDC_OFFSET: 1253226633Sdim case ARM::LDC_PRE: 1254226633Sdim case ARM::LDC_POST: 1255226633Sdim case ARM::LDC_OPTION: 1256226633Sdim case ARM::LDCL_OFFSET: 1257226633Sdim case ARM::LDCL_PRE: 1258226633Sdim case ARM::LDCL_POST: 1259226633Sdim case ARM::LDCL_OPTION: 1260226633Sdim case ARM::STC_OFFSET: 1261226633Sdim case ARM::STC_PRE: 1262226633Sdim case ARM::STC_POST: 1263226633Sdim case ARM::STC_OPTION: 1264226633Sdim case ARM::STCL_OFFSET: 1265226633Sdim case ARM::STCL_PRE: 1266226633Sdim case ARM::STCL_POST: 1267226633Sdim case ARM::STCL_OPTION: 1268226633Sdim case ARM::t2LDC_OFFSET: 1269226633Sdim case ARM::t2LDC_PRE: 1270226633Sdim case ARM::t2LDC_POST: 1271226633Sdim case ARM::t2LDC_OPTION: 1272226633Sdim case ARM::t2LDCL_OFFSET: 1273226633Sdim case ARM::t2LDCL_PRE: 1274226633Sdim case ARM::t2LDCL_POST: 1275226633Sdim case ARM::t2LDCL_OPTION: 1276226633Sdim case ARM::t2STC_OFFSET: 1277226633Sdim case ARM::t2STC_PRE: 1278226633Sdim case ARM::t2STC_POST: 1279226633Sdim case ARM::t2STC_OPTION: 1280226633Sdim case ARM::t2STCL_OFFSET: 1281226633Sdim case ARM::t2STCL_PRE: 1282226633Sdim case ARM::t2STCL_POST: 1283226633Sdim case ARM::t2STCL_OPTION: 1284226633Sdim if (coproc == 0xA || coproc == 0xB) 1285226633Sdim return MCDisassembler::Fail; 1286206124Srdivacky break; 1287226633Sdim default: 1288226633Sdim break; 1289226633Sdim } 1290226633Sdim 1291226633Sdim Inst.addOperand(MCOperand::CreateImm(coproc)); 1292226633Sdim Inst.addOperand(MCOperand::CreateImm(CRd)); 1293226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1294226633Sdim return MCDisassembler::Fail; 1295226633Sdim 1296226633Sdim switch (Inst.getOpcode()) { 1297226633Sdim case ARM::t2LDC2_OFFSET: 1298226633Sdim case ARM::t2LDC2L_OFFSET: 1299226633Sdim case ARM::t2LDC2_PRE: 1300226633Sdim case ARM::t2LDC2L_PRE: 1301226633Sdim case ARM::t2STC2_OFFSET: 1302226633Sdim case ARM::t2STC2L_OFFSET: 1303226633Sdim case ARM::t2STC2_PRE: 1304226633Sdim case ARM::t2STC2L_PRE: 1305226633Sdim case ARM::LDC2_OFFSET: 1306226633Sdim case ARM::LDC2L_OFFSET: 1307226633Sdim case ARM::LDC2_PRE: 1308226633Sdim case ARM::LDC2L_PRE: 1309226633Sdim case ARM::STC2_OFFSET: 1310226633Sdim case ARM::STC2L_OFFSET: 1311226633Sdim case ARM::STC2_PRE: 1312226633Sdim case ARM::STC2L_PRE: 1313226633Sdim case ARM::t2LDC_OFFSET: 1314226633Sdim case ARM::t2LDCL_OFFSET: 1315226633Sdim case ARM::t2LDC_PRE: 1316226633Sdim case ARM::t2LDCL_PRE: 1317226633Sdim case ARM::t2STC_OFFSET: 1318226633Sdim case ARM::t2STCL_OFFSET: 1319226633Sdim case ARM::t2STC_PRE: 1320226633Sdim case ARM::t2STCL_PRE: 1321226633Sdim case ARM::LDC_OFFSET: 1322226633Sdim case ARM::LDCL_OFFSET: 1323226633Sdim case ARM::LDC_PRE: 1324226633Sdim case ARM::LDCL_PRE: 1325226633Sdim case ARM::STC_OFFSET: 1326226633Sdim case ARM::STCL_OFFSET: 1327226633Sdim case ARM::STC_PRE: 1328226633Sdim case ARM::STCL_PRE: 1329226633Sdim imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm); 1330226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1331226633Sdim break; 1332226633Sdim case ARM::t2LDC2_POST: 1333226633Sdim case ARM::t2LDC2L_POST: 1334226633Sdim case ARM::t2STC2_POST: 1335226633Sdim case ARM::t2STC2L_POST: 1336226633Sdim case ARM::LDC2_POST: 1337226633Sdim case ARM::LDC2L_POST: 1338226633Sdim case ARM::STC2_POST: 1339226633Sdim case ARM::STC2L_POST: 1340226633Sdim case ARM::t2LDC_POST: 1341226633Sdim case ARM::t2LDCL_POST: 1342226633Sdim case ARM::t2STC_POST: 1343226633Sdim case ARM::t2STCL_POST: 1344226633Sdim case ARM::LDC_POST: 1345226633Sdim case ARM::LDCL_POST: 1346226633Sdim case ARM::STC_POST: 1347226633Sdim case ARM::STCL_POST: 1348226633Sdim imm |= U << 8; 1349226633Sdim // fall through. 1350226633Sdim default: 1351226633Sdim // The 'option' variant doesn't encode 'U' in the immediate since 1352226633Sdim // the immediate is unsigned [0,255]. 1353226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1354226633Sdim break; 1355226633Sdim } 1356226633Sdim 1357226633Sdim switch (Inst.getOpcode()) { 1358226633Sdim case ARM::LDC_OFFSET: 1359226633Sdim case ARM::LDC_PRE: 1360226633Sdim case ARM::LDC_POST: 1361226633Sdim case ARM::LDC_OPTION: 1362226633Sdim case ARM::LDCL_OFFSET: 1363226633Sdim case ARM::LDCL_PRE: 1364226633Sdim case ARM::LDCL_POST: 1365226633Sdim case ARM::LDCL_OPTION: 1366226633Sdim case ARM::STC_OFFSET: 1367226633Sdim case ARM::STC_PRE: 1368226633Sdim case ARM::STC_POST: 1369226633Sdim case ARM::STC_OPTION: 1370226633Sdim case ARM::STCL_OFFSET: 1371226633Sdim case ARM::STCL_PRE: 1372226633Sdim case ARM::STCL_POST: 1373226633Sdim case ARM::STCL_OPTION: 1374226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1375226633Sdim return MCDisassembler::Fail; 1376226633Sdim break; 1377226633Sdim default: 1378226633Sdim break; 1379226633Sdim } 1380226633Sdim 1381226633Sdim return S; 1382226633Sdim} 1383226633Sdim 1384226633Sdimstatic DecodeStatus 1385234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, 1386226633Sdim uint64_t Address, const void *Decoder) { 1387226633Sdim DecodeStatus S = MCDisassembler::Success; 1388226633Sdim 1389226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 1390226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 1391226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 1392226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 12); 1393226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 1394226633Sdim unsigned reg = fieldFromInstruction32(Insn, 25, 1); 1395226633Sdim unsigned P = fieldFromInstruction32(Insn, 24, 1); 1396226633Sdim unsigned W = fieldFromInstruction32(Insn, 21, 1); 1397226633Sdim 1398226633Sdim // On stores, the writeback operand precedes Rt. 1399226633Sdim switch (Inst.getOpcode()) { 1400226633Sdim case ARM::STR_POST_IMM: 1401226633Sdim case ARM::STR_POST_REG: 1402226633Sdim case ARM::STRB_POST_IMM: 1403226633Sdim case ARM::STRB_POST_REG: 1404226633Sdim case ARM::STRT_POST_REG: 1405226633Sdim case ARM::STRT_POST_IMM: 1406226633Sdim case ARM::STRBT_POST_REG: 1407226633Sdim case ARM::STRBT_POST_IMM: 1408226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1409226633Sdim return MCDisassembler::Fail; 1410226633Sdim break; 1411226633Sdim default: 1412226633Sdim break; 1413226633Sdim } 1414226633Sdim 1415226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1416226633Sdim return MCDisassembler::Fail; 1417226633Sdim 1418226633Sdim // On loads, the writeback operand comes after Rt. 1419226633Sdim switch (Inst.getOpcode()) { 1420226633Sdim case ARM::LDR_POST_IMM: 1421226633Sdim case ARM::LDR_POST_REG: 1422226633Sdim case ARM::LDRB_POST_IMM: 1423226633Sdim case ARM::LDRB_POST_REG: 1424226633Sdim case ARM::LDRBT_POST_REG: 1425226633Sdim case ARM::LDRBT_POST_IMM: 1426226633Sdim case ARM::LDRT_POST_REG: 1427226633Sdim case ARM::LDRT_POST_IMM: 1428226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1429226633Sdim return MCDisassembler::Fail; 1430226633Sdim break; 1431226633Sdim default: 1432226633Sdim break; 1433226633Sdim } 1434226633Sdim 1435226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1436226633Sdim return MCDisassembler::Fail; 1437226633Sdim 1438226633Sdim ARM_AM::AddrOpc Op = ARM_AM::add; 1439226633Sdim if (!fieldFromInstruction32(Insn, 23, 1)) 1440226633Sdim Op = ARM_AM::sub; 1441226633Sdim 1442226633Sdim bool writeback = (P == 0) || (W == 1); 1443226633Sdim unsigned idx_mode = 0; 1444226633Sdim if (P && writeback) 1445226633Sdim idx_mode = ARMII::IndexModePre; 1446226633Sdim else if (!P && writeback) 1447226633Sdim idx_mode = ARMII::IndexModePost; 1448226633Sdim 1449226633Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1450226633Sdim S = MCDisassembler::SoftFail; // UNPREDICTABLE 1451226633Sdim 1452226633Sdim if (reg) { 1453226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1454226633Sdim return MCDisassembler::Fail; 1455226633Sdim ARM_AM::ShiftOpc Opc = ARM_AM::lsl; 1456226633Sdim switch( fieldFromInstruction32(Insn, 5, 2)) { 1457226633Sdim case 0: 1458226633Sdim Opc = ARM_AM::lsl; 1459226633Sdim break; 1460226633Sdim case 1: 1461226633Sdim Opc = ARM_AM::lsr; 1462226633Sdim break; 1463226633Sdim case 2: 1464226633Sdim Opc = ARM_AM::asr; 1465226633Sdim break; 1466226633Sdim case 3: 1467226633Sdim Opc = ARM_AM::ror; 1468226633Sdim break; 1469206124Srdivacky default: 1470226633Sdim return MCDisassembler::Fail; 1471226633Sdim } 1472226633Sdim unsigned amt = fieldFromInstruction32(Insn, 7, 5); 1473226633Sdim unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode); 1474226633Sdim 1475226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1476226633Sdim } else { 1477226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1478226633Sdim unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode); 1479226633Sdim Inst.addOperand(MCOperand::CreateImm(tmp)); 1480226633Sdim } 1481226633Sdim 1482226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1483226633Sdim return MCDisassembler::Fail; 1484226633Sdim 1485226633Sdim return S; 1486226633Sdim} 1487226633Sdim 1488234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val, 1489226633Sdim uint64_t Address, const void *Decoder) { 1490226633Sdim DecodeStatus S = MCDisassembler::Success; 1491226633Sdim 1492226633Sdim unsigned Rn = fieldFromInstruction32(Val, 13, 4); 1493226633Sdim unsigned Rm = fieldFromInstruction32(Val, 0, 4); 1494226633Sdim unsigned type = fieldFromInstruction32(Val, 5, 2); 1495226633Sdim unsigned imm = fieldFromInstruction32(Val, 7, 5); 1496226633Sdim unsigned U = fieldFromInstruction32(Val, 12, 1); 1497226633Sdim 1498226633Sdim ARM_AM::ShiftOpc ShOp = ARM_AM::lsl; 1499226633Sdim switch (type) { 1500226633Sdim case 0: 1501226633Sdim ShOp = ARM_AM::lsl; 1502206124Srdivacky break; 1503226633Sdim case 1: 1504226633Sdim ShOp = ARM_AM::lsr; 1505226633Sdim break; 1506226633Sdim case 2: 1507226633Sdim ShOp = ARM_AM::asr; 1508226633Sdim break; 1509226633Sdim case 3: 1510226633Sdim ShOp = ARM_AM::ror; 1511226633Sdim break; 1512226633Sdim } 1513226633Sdim 1514226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1515226633Sdim return MCDisassembler::Fail; 1516226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1517226633Sdim return MCDisassembler::Fail; 1518226633Sdim unsigned shift; 1519226633Sdim if (U) 1520226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp); 1521226633Sdim else 1522226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp); 1523226633Sdim Inst.addOperand(MCOperand::CreateImm(shift)); 1524226633Sdim 1525226633Sdim return S; 1526226633Sdim} 1527226633Sdim 1528226633Sdimstatic DecodeStatus 1529234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn, 1530226633Sdim uint64_t Address, const void *Decoder) { 1531226633Sdim DecodeStatus S = MCDisassembler::Success; 1532226633Sdim 1533226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 1534226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 1535226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 1536226633Sdim unsigned type = fieldFromInstruction32(Insn, 22, 1); 1537226633Sdim unsigned imm = fieldFromInstruction32(Insn, 8, 4); 1538226633Sdim unsigned U = ((~fieldFromInstruction32(Insn, 23, 1)) & 1) << 8; 1539226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 1540226633Sdim unsigned W = fieldFromInstruction32(Insn, 21, 1); 1541226633Sdim unsigned P = fieldFromInstruction32(Insn, 24, 1); 1542234353Sdim unsigned Rt2 = Rt + 1; 1543226633Sdim 1544226633Sdim bool writeback = (W == 1) | (P == 0); 1545226633Sdim 1546226633Sdim // For {LD,ST}RD, Rt must be even, else undefined. 1547226633Sdim switch (Inst.getOpcode()) { 1548226633Sdim case ARM::STRD: 1549226633Sdim case ARM::STRD_PRE: 1550226633Sdim case ARM::STRD_POST: 1551226633Sdim case ARM::LDRD: 1552226633Sdim case ARM::LDRD_PRE: 1553226633Sdim case ARM::LDRD_POST: 1554234353Sdim if (Rt & 0x1) S = MCDisassembler::SoftFail; 1555226633Sdim break; 1556226633Sdim default: 1557226633Sdim break; 1558226633Sdim } 1559234353Sdim switch (Inst.getOpcode()) { 1560234353Sdim case ARM::STRD: 1561234353Sdim case ARM::STRD_PRE: 1562234353Sdim case ARM::STRD_POST: 1563234353Sdim if (P == 0 && W == 1) 1564234353Sdim S = MCDisassembler::SoftFail; 1565234353Sdim 1566234353Sdim if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2)) 1567234353Sdim S = MCDisassembler::SoftFail; 1568234353Sdim if (type && Rm == 15) 1569234353Sdim S = MCDisassembler::SoftFail; 1570234353Sdim if (Rt2 == 15) 1571234353Sdim S = MCDisassembler::SoftFail; 1572234353Sdim if (!type && fieldFromInstruction32(Insn, 8, 4)) 1573234353Sdim S = MCDisassembler::SoftFail; 1574234353Sdim break; 1575234353Sdim case ARM::STRH: 1576234353Sdim case ARM::STRH_PRE: 1577234353Sdim case ARM::STRH_POST: 1578234353Sdim if (Rt == 15) 1579234353Sdim S = MCDisassembler::SoftFail; 1580234353Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1581234353Sdim S = MCDisassembler::SoftFail; 1582234353Sdim if (!type && Rm == 15) 1583234353Sdim S = MCDisassembler::SoftFail; 1584234353Sdim break; 1585234353Sdim case ARM::LDRD: 1586234353Sdim case ARM::LDRD_PRE: 1587234353Sdim case ARM::LDRD_POST: 1588234353Sdim if (type && Rn == 15){ 1589234353Sdim if (Rt2 == 15) 1590234353Sdim S = MCDisassembler::SoftFail; 1591234353Sdim break; 1592234353Sdim } 1593234353Sdim if (P == 0 && W == 1) 1594234353Sdim S = MCDisassembler::SoftFail; 1595234353Sdim if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2)) 1596234353Sdim S = MCDisassembler::SoftFail; 1597234353Sdim if (!type && writeback && Rn == 15) 1598234353Sdim S = MCDisassembler::SoftFail; 1599234353Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 1600234353Sdim S = MCDisassembler::SoftFail; 1601234353Sdim break; 1602234353Sdim case ARM::LDRH: 1603234353Sdim case ARM::LDRH_PRE: 1604234353Sdim case ARM::LDRH_POST: 1605234353Sdim if (type && Rn == 15){ 1606234353Sdim if (Rt == 15) 1607234353Sdim S = MCDisassembler::SoftFail; 1608234353Sdim break; 1609234353Sdim } 1610234353Sdim if (Rt == 15) 1611234353Sdim S = MCDisassembler::SoftFail; 1612234353Sdim if (!type && Rm == 15) 1613234353Sdim S = MCDisassembler::SoftFail; 1614234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 1615234353Sdim S = MCDisassembler::SoftFail; 1616234353Sdim break; 1617234353Sdim case ARM::LDRSH: 1618234353Sdim case ARM::LDRSH_PRE: 1619234353Sdim case ARM::LDRSH_POST: 1620234353Sdim case ARM::LDRSB: 1621234353Sdim case ARM::LDRSB_PRE: 1622234353Sdim case ARM::LDRSB_POST: 1623234353Sdim if (type && Rn == 15){ 1624234353Sdim if (Rt == 15) 1625234353Sdim S = MCDisassembler::SoftFail; 1626234353Sdim break; 1627234353Sdim } 1628234353Sdim if (type && (Rt == 15 || (writeback && Rn == Rt))) 1629234353Sdim S = MCDisassembler::SoftFail; 1630234353Sdim if (!type && (Rt == 15 || Rm == 15)) 1631234353Sdim S = MCDisassembler::SoftFail; 1632234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 1633234353Sdim S = MCDisassembler::SoftFail; 1634234353Sdim break; 1635234353Sdim default: 1636234353Sdim break; 1637234353Sdim } 1638226633Sdim 1639226633Sdim if (writeback) { // Writeback 1640226633Sdim if (P) 1641226633Sdim U |= ARMII::IndexModePre << 9; 1642226633Sdim else 1643226633Sdim U |= ARMII::IndexModePost << 9; 1644226633Sdim 1645226633Sdim // On stores, the writeback operand precedes Rt. 1646226633Sdim switch (Inst.getOpcode()) { 1647226633Sdim case ARM::STRD: 1648226633Sdim case ARM::STRD_PRE: 1649226633Sdim case ARM::STRD_POST: 1650226633Sdim case ARM::STRH: 1651226633Sdim case ARM::STRH_PRE: 1652226633Sdim case ARM::STRH_POST: 1653226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1654226633Sdim return MCDisassembler::Fail; 1655226633Sdim break; 1656226633Sdim default: 1657226633Sdim break; 1658226633Sdim } 1659226633Sdim } 1660226633Sdim 1661226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1662226633Sdim return MCDisassembler::Fail; 1663226633Sdim switch (Inst.getOpcode()) { 1664226633Sdim case ARM::STRD: 1665226633Sdim case ARM::STRD_PRE: 1666226633Sdim case ARM::STRD_POST: 1667226633Sdim case ARM::LDRD: 1668226633Sdim case ARM::LDRD_PRE: 1669226633Sdim case ARM::LDRD_POST: 1670226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 1671226633Sdim return MCDisassembler::Fail; 1672226633Sdim break; 1673226633Sdim default: 1674226633Sdim break; 1675226633Sdim } 1676226633Sdim 1677226633Sdim if (writeback) { 1678226633Sdim // On loads, the writeback operand comes after Rt. 1679226633Sdim switch (Inst.getOpcode()) { 1680226633Sdim case ARM::LDRD: 1681226633Sdim case ARM::LDRD_PRE: 1682226633Sdim case ARM::LDRD_POST: 1683226633Sdim case ARM::LDRH: 1684226633Sdim case ARM::LDRH_PRE: 1685226633Sdim case ARM::LDRH_POST: 1686226633Sdim case ARM::LDRSH: 1687226633Sdim case ARM::LDRSH_PRE: 1688226633Sdim case ARM::LDRSH_POST: 1689226633Sdim case ARM::LDRSB: 1690226633Sdim case ARM::LDRSB_PRE: 1691226633Sdim case ARM::LDRSB_POST: 1692226633Sdim case ARM::LDRHTr: 1693226633Sdim case ARM::LDRSBTr: 1694226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1695226633Sdim return MCDisassembler::Fail; 1696226633Sdim break; 1697226633Sdim default: 1698226633Sdim break; 1699226633Sdim } 1700226633Sdim } 1701226633Sdim 1702226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1703226633Sdim return MCDisassembler::Fail; 1704226633Sdim 1705226633Sdim if (type) { 1706226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1707226633Sdim Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm)); 1708226633Sdim } else { 1709226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1710226633Sdim return MCDisassembler::Fail; 1711226633Sdim Inst.addOperand(MCOperand::CreateImm(U)); 1712226633Sdim } 1713226633Sdim 1714226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1715226633Sdim return MCDisassembler::Fail; 1716226633Sdim 1717226633Sdim return S; 1718226633Sdim} 1719226633Sdim 1720234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn, 1721226633Sdim uint64_t Address, const void *Decoder) { 1722226633Sdim DecodeStatus S = MCDisassembler::Success; 1723226633Sdim 1724226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 1725226633Sdim unsigned mode = fieldFromInstruction32(Insn, 23, 2); 1726226633Sdim 1727226633Sdim switch (mode) { 1728226633Sdim case 0: 1729226633Sdim mode = ARM_AM::da; 1730226633Sdim break; 1731226633Sdim case 1: 1732226633Sdim mode = ARM_AM::ia; 1733226633Sdim break; 1734226633Sdim case 2: 1735226633Sdim mode = ARM_AM::db; 1736226633Sdim break; 1737226633Sdim case 3: 1738226633Sdim mode = ARM_AM::ib; 1739226633Sdim break; 1740226633Sdim } 1741226633Sdim 1742226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1743226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1744226633Sdim return MCDisassembler::Fail; 1745226633Sdim 1746226633Sdim return S; 1747226633Sdim} 1748226633Sdim 1749234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst, 1750226633Sdim unsigned Insn, 1751226633Sdim uint64_t Address, const void *Decoder) { 1752226633Sdim DecodeStatus S = MCDisassembler::Success; 1753226633Sdim 1754226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 1755226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 1756226633Sdim unsigned reglist = fieldFromInstruction32(Insn, 0, 16); 1757226633Sdim 1758226633Sdim if (pred == 0xF) { 1759226633Sdim switch (Inst.getOpcode()) { 1760226633Sdim case ARM::LDMDA: 1761226633Sdim Inst.setOpcode(ARM::RFEDA); 1762226633Sdim break; 1763226633Sdim case ARM::LDMDA_UPD: 1764226633Sdim Inst.setOpcode(ARM::RFEDA_UPD); 1765226633Sdim break; 1766226633Sdim case ARM::LDMDB: 1767226633Sdim Inst.setOpcode(ARM::RFEDB); 1768226633Sdim break; 1769226633Sdim case ARM::LDMDB_UPD: 1770226633Sdim Inst.setOpcode(ARM::RFEDB_UPD); 1771226633Sdim break; 1772226633Sdim case ARM::LDMIA: 1773226633Sdim Inst.setOpcode(ARM::RFEIA); 1774226633Sdim break; 1775226633Sdim case ARM::LDMIA_UPD: 1776226633Sdim Inst.setOpcode(ARM::RFEIA_UPD); 1777226633Sdim break; 1778226633Sdim case ARM::LDMIB: 1779226633Sdim Inst.setOpcode(ARM::RFEIB); 1780226633Sdim break; 1781226633Sdim case ARM::LDMIB_UPD: 1782226633Sdim Inst.setOpcode(ARM::RFEIB_UPD); 1783226633Sdim break; 1784226633Sdim case ARM::STMDA: 1785226633Sdim Inst.setOpcode(ARM::SRSDA); 1786226633Sdim break; 1787226633Sdim case ARM::STMDA_UPD: 1788226633Sdim Inst.setOpcode(ARM::SRSDA_UPD); 1789226633Sdim break; 1790226633Sdim case ARM::STMDB: 1791226633Sdim Inst.setOpcode(ARM::SRSDB); 1792226633Sdim break; 1793226633Sdim case ARM::STMDB_UPD: 1794226633Sdim Inst.setOpcode(ARM::SRSDB_UPD); 1795226633Sdim break; 1796226633Sdim case ARM::STMIA: 1797226633Sdim Inst.setOpcode(ARM::SRSIA); 1798226633Sdim break; 1799226633Sdim case ARM::STMIA_UPD: 1800226633Sdim Inst.setOpcode(ARM::SRSIA_UPD); 1801226633Sdim break; 1802226633Sdim case ARM::STMIB: 1803226633Sdim Inst.setOpcode(ARM::SRSIB); 1804226633Sdim break; 1805226633Sdim case ARM::STMIB_UPD: 1806226633Sdim Inst.setOpcode(ARM::SRSIB_UPD); 1807226633Sdim break; 1808206124Srdivacky default: 1809226633Sdim if (!Check(S, MCDisassembler::Fail)) return MCDisassembler::Fail; 1810226633Sdim } 1811226633Sdim 1812226633Sdim // For stores (which become SRS's, the only operand is the mode. 1813226633Sdim if (fieldFromInstruction32(Insn, 20, 1) == 0) { 1814226633Sdim Inst.addOperand( 1815226633Sdim MCOperand::CreateImm(fieldFromInstruction32(Insn, 0, 4))); 1816226633Sdim return S; 1817226633Sdim } 1818226633Sdim 1819226633Sdim return DecodeRFEInstruction(Inst, Insn, Address, Decoder); 1820226633Sdim } 1821226633Sdim 1822226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1823226633Sdim return MCDisassembler::Fail; 1824226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1825226633Sdim return MCDisassembler::Fail; // Tied 1826226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1827226633Sdim return MCDisassembler::Fail; 1828226633Sdim if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder))) 1829226633Sdim return MCDisassembler::Fail; 1830226633Sdim 1831226633Sdim return S; 1832226633Sdim} 1833226633Sdim 1834234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 1835226633Sdim uint64_t Address, const void *Decoder) { 1836226633Sdim unsigned imod = fieldFromInstruction32(Insn, 18, 2); 1837226633Sdim unsigned M = fieldFromInstruction32(Insn, 17, 1); 1838226633Sdim unsigned iflags = fieldFromInstruction32(Insn, 6, 3); 1839226633Sdim unsigned mode = fieldFromInstruction32(Insn, 0, 5); 1840226633Sdim 1841226633Sdim DecodeStatus S = MCDisassembler::Success; 1842226633Sdim 1843226633Sdim // imod == '01' --> UNPREDICTABLE 1844226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 1845226633Sdim // return failure here. The '01' imod value is unprintable, so there's 1846226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 1847226633Sdim 1848226633Sdim if (imod == 1) return MCDisassembler::Fail; 1849226633Sdim 1850226633Sdim if (imod && M) { 1851226633Sdim Inst.setOpcode(ARM::CPS3p); 1852226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1853226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1854226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1855226633Sdim } else if (imod && !M) { 1856226633Sdim Inst.setOpcode(ARM::CPS2p); 1857226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1858226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1859226633Sdim if (mode) S = MCDisassembler::SoftFail; 1860226633Sdim } else if (!imod && M) { 1861226633Sdim Inst.setOpcode(ARM::CPS1p); 1862226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1863226633Sdim if (iflags) S = MCDisassembler::SoftFail; 1864226633Sdim } else { 1865226633Sdim // imod == '00' && M == '0' --> UNPREDICTABLE 1866226633Sdim Inst.setOpcode(ARM::CPS1p); 1867226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1868226633Sdim S = MCDisassembler::SoftFail; 1869226633Sdim } 1870226633Sdim 1871226633Sdim return S; 1872226633Sdim} 1873226633Sdim 1874234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 1875226633Sdim uint64_t Address, const void *Decoder) { 1876226633Sdim unsigned imod = fieldFromInstruction32(Insn, 9, 2); 1877226633Sdim unsigned M = fieldFromInstruction32(Insn, 8, 1); 1878226633Sdim unsigned iflags = fieldFromInstruction32(Insn, 5, 3); 1879226633Sdim unsigned mode = fieldFromInstruction32(Insn, 0, 5); 1880226633Sdim 1881226633Sdim DecodeStatus S = MCDisassembler::Success; 1882226633Sdim 1883226633Sdim // imod == '01' --> UNPREDICTABLE 1884226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 1885226633Sdim // return failure here. The '01' imod value is unprintable, so there's 1886226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 1887226633Sdim 1888226633Sdim if (imod == 1) return MCDisassembler::Fail; 1889226633Sdim 1890226633Sdim if (imod && M) { 1891226633Sdim Inst.setOpcode(ARM::t2CPS3p); 1892226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1893226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1894226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1895226633Sdim } else if (imod && !M) { 1896226633Sdim Inst.setOpcode(ARM::t2CPS2p); 1897226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1898226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1899226633Sdim if (mode) S = MCDisassembler::SoftFail; 1900226633Sdim } else if (!imod && M) { 1901226633Sdim Inst.setOpcode(ARM::t2CPS1p); 1902226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1903226633Sdim if (iflags) S = MCDisassembler::SoftFail; 1904226633Sdim } else { 1905226633Sdim // imod == '00' && M == '0' --> UNPREDICTABLE 1906226633Sdim Inst.setOpcode(ARM::t2CPS1p); 1907226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1908226633Sdim S = MCDisassembler::SoftFail; 1909226633Sdim } 1910226633Sdim 1911226633Sdim return S; 1912226633Sdim} 1913226633Sdim 1914234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 1915226633Sdim uint64_t Address, const void *Decoder) { 1916226633Sdim DecodeStatus S = MCDisassembler::Success; 1917226633Sdim 1918226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 8, 4); 1919226633Sdim unsigned imm = 0; 1920226633Sdim 1921226633Sdim imm |= (fieldFromInstruction32(Insn, 0, 8) << 0); 1922226633Sdim imm |= (fieldFromInstruction32(Insn, 12, 3) << 8); 1923226633Sdim imm |= (fieldFromInstruction32(Insn, 16, 4) << 12); 1924226633Sdim imm |= (fieldFromInstruction32(Insn, 26, 1) << 11); 1925226633Sdim 1926226633Sdim if (Inst.getOpcode() == ARM::t2MOVTi16) 1927226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 1928226633Sdim return MCDisassembler::Fail; 1929226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 1930226633Sdim return MCDisassembler::Fail; 1931226633Sdim 1932226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 1933226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1934226633Sdim 1935226633Sdim return S; 1936226633Sdim} 1937226633Sdim 1938234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 1939226633Sdim uint64_t Address, const void *Decoder) { 1940226633Sdim DecodeStatus S = MCDisassembler::Success; 1941226633Sdim 1942226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 1943226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 1944226633Sdim unsigned imm = 0; 1945226633Sdim 1946226633Sdim imm |= (fieldFromInstruction32(Insn, 0, 12) << 0); 1947226633Sdim imm |= (fieldFromInstruction32(Insn, 16, 4) << 12); 1948226633Sdim 1949226633Sdim if (Inst.getOpcode() == ARM::MOVTi16) 1950226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 1951226633Sdim return MCDisassembler::Fail; 1952226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 1953226633Sdim return MCDisassembler::Fail; 1954226633Sdim 1955226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 1956226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1957226633Sdim 1958226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1959226633Sdim return MCDisassembler::Fail; 1960226633Sdim 1961226633Sdim return S; 1962226633Sdim} 1963226633Sdim 1964234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 1965226633Sdim uint64_t Address, const void *Decoder) { 1966226633Sdim DecodeStatus S = MCDisassembler::Success; 1967226633Sdim 1968226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 16, 4); 1969226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 0, 4); 1970226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 8, 4); 1971226633Sdim unsigned Ra = fieldFromInstruction32(Insn, 12, 4); 1972226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 1973226633Sdim 1974226633Sdim if (pred == 0xF) 1975226633Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 1976226633Sdim 1977226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 1978226633Sdim return MCDisassembler::Fail; 1979226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 1980226633Sdim return MCDisassembler::Fail; 1981226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1982226633Sdim return MCDisassembler::Fail; 1983226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder))) 1984226633Sdim return MCDisassembler::Fail; 1985226633Sdim 1986226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1987226633Sdim return MCDisassembler::Fail; 1988226633Sdim 1989226633Sdim return S; 1990226633Sdim} 1991226633Sdim 1992234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 1993226633Sdim uint64_t Address, const void *Decoder) { 1994226633Sdim DecodeStatus S = MCDisassembler::Success; 1995226633Sdim 1996226633Sdim unsigned add = fieldFromInstruction32(Val, 12, 1); 1997226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 12); 1998226633Sdim unsigned Rn = fieldFromInstruction32(Val, 13, 4); 1999226633Sdim 2000226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2001226633Sdim return MCDisassembler::Fail; 2002226633Sdim 2003226633Sdim if (!add) imm *= -1; 2004226633Sdim if (imm == 0 && !add) imm = INT32_MIN; 2005226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2006226633Sdim if (Rn == 15) 2007226633Sdim tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder); 2008226633Sdim 2009226633Sdim return S; 2010226633Sdim} 2011226633Sdim 2012234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 2013226633Sdim uint64_t Address, const void *Decoder) { 2014226633Sdim DecodeStatus S = MCDisassembler::Success; 2015226633Sdim 2016226633Sdim unsigned Rn = fieldFromInstruction32(Val, 9, 4); 2017226633Sdim unsigned U = fieldFromInstruction32(Val, 8, 1); 2018226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 8); 2019226633Sdim 2020226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2021226633Sdim return MCDisassembler::Fail; 2022226633Sdim 2023226633Sdim if (U) 2024226633Sdim Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm))); 2025226633Sdim else 2026226633Sdim Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm))); 2027226633Sdim 2028226633Sdim return S; 2029226633Sdim} 2030226633Sdim 2031234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 2032226633Sdim uint64_t Address, const void *Decoder) { 2033226633Sdim return DecodeGPRRegisterClass(Inst, Val, Address, Decoder); 2034226633Sdim} 2035226633Sdim 2036226633Sdimstatic DecodeStatus 2037234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn, 2038234353Sdim uint64_t Address, const void *Decoder) { 2039234353Sdim DecodeStatus S = MCDisassembler::Success; 2040234353Sdim unsigned imm = (fieldFromInstruction32(Insn, 0, 11) << 0) | 2041234353Sdim (fieldFromInstruction32(Insn, 11, 1) << 18) | 2042234353Sdim (fieldFromInstruction32(Insn, 13, 1) << 17) | 2043234353Sdim (fieldFromInstruction32(Insn, 16, 6) << 11) | 2044234353Sdim (fieldFromInstruction32(Insn, 26, 1) << 19); 2045234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<20>(imm<<1) + 4, 2046234353Sdim true, 4, Inst, Decoder)) 2047234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<20>(imm << 1))); 2048234353Sdim return S; 2049234353Sdim} 2050234353Sdim 2051234353Sdimstatic DecodeStatus 2052234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn, 2053226633Sdim uint64_t Address, const void *Decoder) { 2054226633Sdim DecodeStatus S = MCDisassembler::Success; 2055226633Sdim 2056226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 2057226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 24) << 2; 2058226633Sdim 2059226633Sdim if (pred == 0xF) { 2060226633Sdim Inst.setOpcode(ARM::BLXi); 2061226633Sdim imm |= fieldFromInstruction32(Insn, 24, 1) << 1; 2062234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2063234353Sdim true, 4, Inst, Decoder)) 2064226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); 2065226633Sdim return S; 2066226633Sdim } 2067226633Sdim 2068234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2069234353Sdim true, 4, Inst, Decoder)) 2070226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); 2071226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2072226633Sdim return MCDisassembler::Fail; 2073226633Sdim 2074226633Sdim return S; 2075226633Sdim} 2076226633Sdim 2077226633Sdim 2078234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 2079226633Sdim uint64_t Address, const void *Decoder) { 2080226633Sdim DecodeStatus S = MCDisassembler::Success; 2081226633Sdim 2082226633Sdim unsigned Rm = fieldFromInstruction32(Val, 0, 4); 2083226633Sdim unsigned align = fieldFromInstruction32(Val, 4, 2); 2084226633Sdim 2085226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2086226633Sdim return MCDisassembler::Fail; 2087226633Sdim if (!align) 2088226633Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2089226633Sdim else 2090226633Sdim Inst.addOperand(MCOperand::CreateImm(4 << align)); 2091226633Sdim 2092226633Sdim return S; 2093226633Sdim} 2094226633Sdim 2095234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn, 2096226633Sdim uint64_t Address, const void *Decoder) { 2097226633Sdim DecodeStatus S = MCDisassembler::Success; 2098226633Sdim 2099226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2100226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2101226633Sdim unsigned wb = fieldFromInstruction32(Insn, 16, 4); 2102226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2103226633Sdim Rn |= fieldFromInstruction32(Insn, 4, 2) << 4; 2104226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2105226633Sdim 2106226633Sdim // First output register 2107234353Sdim switch (Inst.getOpcode()) { 2108234353Sdim case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8: 2109234353Sdim case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register: 2110234353Sdim case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register: 2111234353Sdim case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register: 2112234353Sdim case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register: 2113234353Sdim case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8: 2114234353Sdim case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register: 2115234353Sdim case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register: 2116234353Sdim case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register: 2117234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2118234353Sdim return MCDisassembler::Fail; 2119234353Sdim break; 2120234353Sdim case ARM::VLD2b16: 2121234353Sdim case ARM::VLD2b32: 2122234353Sdim case ARM::VLD2b8: 2123234353Sdim case ARM::VLD2b16wb_fixed: 2124234353Sdim case ARM::VLD2b16wb_register: 2125234353Sdim case ARM::VLD2b32wb_fixed: 2126234353Sdim case ARM::VLD2b32wb_register: 2127234353Sdim case ARM::VLD2b8wb_fixed: 2128234353Sdim case ARM::VLD2b8wb_register: 2129234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2130234353Sdim return MCDisassembler::Fail; 2131234353Sdim break; 2132234353Sdim default: 2133234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2134234353Sdim return MCDisassembler::Fail; 2135234353Sdim } 2136226633Sdim 2137226633Sdim // Second output register 2138226633Sdim switch (Inst.getOpcode()) { 2139226633Sdim case ARM::VLD3d8: 2140226633Sdim case ARM::VLD3d16: 2141226633Sdim case ARM::VLD3d32: 2142226633Sdim case ARM::VLD3d8_UPD: 2143226633Sdim case ARM::VLD3d16_UPD: 2144226633Sdim case ARM::VLD3d32_UPD: 2145226633Sdim case ARM::VLD4d8: 2146226633Sdim case ARM::VLD4d16: 2147226633Sdim case ARM::VLD4d32: 2148226633Sdim case ARM::VLD4d8_UPD: 2149226633Sdim case ARM::VLD4d16_UPD: 2150226633Sdim case ARM::VLD4d32_UPD: 2151226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2152226633Sdim return MCDisassembler::Fail; 2153206124Srdivacky break; 2154226633Sdim case ARM::VLD3q8: 2155226633Sdim case ARM::VLD3q16: 2156226633Sdim case ARM::VLD3q32: 2157226633Sdim case ARM::VLD3q8_UPD: 2158226633Sdim case ARM::VLD3q16_UPD: 2159226633Sdim case ARM::VLD3q32_UPD: 2160226633Sdim case ARM::VLD4q8: 2161226633Sdim case ARM::VLD4q16: 2162226633Sdim case ARM::VLD4q32: 2163226633Sdim case ARM::VLD4q8_UPD: 2164226633Sdim case ARM::VLD4q16_UPD: 2165226633Sdim case ARM::VLD4q32_UPD: 2166226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2167226633Sdim return MCDisassembler::Fail; 2168206124Srdivacky default: 2169226633Sdim break; 2170226633Sdim } 2171226633Sdim 2172226633Sdim // Third output register 2173226633Sdim switch(Inst.getOpcode()) { 2174226633Sdim case ARM::VLD3d8: 2175226633Sdim case ARM::VLD3d16: 2176226633Sdim case ARM::VLD3d32: 2177226633Sdim case ARM::VLD3d8_UPD: 2178226633Sdim case ARM::VLD3d16_UPD: 2179226633Sdim case ARM::VLD3d32_UPD: 2180226633Sdim case ARM::VLD4d8: 2181226633Sdim case ARM::VLD4d16: 2182226633Sdim case ARM::VLD4d32: 2183226633Sdim case ARM::VLD4d8_UPD: 2184226633Sdim case ARM::VLD4d16_UPD: 2185226633Sdim case ARM::VLD4d32_UPD: 2186226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2187226633Sdim return MCDisassembler::Fail; 2188226633Sdim break; 2189226633Sdim case ARM::VLD3q8: 2190226633Sdim case ARM::VLD3q16: 2191226633Sdim case ARM::VLD3q32: 2192226633Sdim case ARM::VLD3q8_UPD: 2193226633Sdim case ARM::VLD3q16_UPD: 2194226633Sdim case ARM::VLD3q32_UPD: 2195226633Sdim case ARM::VLD4q8: 2196226633Sdim case ARM::VLD4q16: 2197226633Sdim case ARM::VLD4q32: 2198226633Sdim case ARM::VLD4q8_UPD: 2199226633Sdim case ARM::VLD4q16_UPD: 2200226633Sdim case ARM::VLD4q32_UPD: 2201226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2202226633Sdim return MCDisassembler::Fail; 2203226633Sdim break; 2204226633Sdim default: 2205226633Sdim break; 2206226633Sdim } 2207226633Sdim 2208226633Sdim // Fourth output register 2209226633Sdim switch (Inst.getOpcode()) { 2210226633Sdim case ARM::VLD4d8: 2211226633Sdim case ARM::VLD4d16: 2212226633Sdim case ARM::VLD4d32: 2213226633Sdim case ARM::VLD4d8_UPD: 2214226633Sdim case ARM::VLD4d16_UPD: 2215226633Sdim case ARM::VLD4d32_UPD: 2216226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 2217226633Sdim return MCDisassembler::Fail; 2218226633Sdim break; 2219226633Sdim case ARM::VLD4q8: 2220226633Sdim case ARM::VLD4q16: 2221226633Sdim case ARM::VLD4q32: 2222226633Sdim case ARM::VLD4q8_UPD: 2223226633Sdim case ARM::VLD4q16_UPD: 2224226633Sdim case ARM::VLD4q32_UPD: 2225226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2226226633Sdim return MCDisassembler::Fail; 2227226633Sdim break; 2228226633Sdim default: 2229226633Sdim break; 2230226633Sdim } 2231226633Sdim 2232226633Sdim // Writeback operand 2233226633Sdim switch (Inst.getOpcode()) { 2234234353Sdim case ARM::VLD1d8wb_fixed: 2235234353Sdim case ARM::VLD1d16wb_fixed: 2236234353Sdim case ARM::VLD1d32wb_fixed: 2237234353Sdim case ARM::VLD1d64wb_fixed: 2238234353Sdim case ARM::VLD1d8wb_register: 2239234353Sdim case ARM::VLD1d16wb_register: 2240234353Sdim case ARM::VLD1d32wb_register: 2241234353Sdim case ARM::VLD1d64wb_register: 2242234353Sdim case ARM::VLD1q8wb_fixed: 2243234353Sdim case ARM::VLD1q16wb_fixed: 2244234353Sdim case ARM::VLD1q32wb_fixed: 2245234353Sdim case ARM::VLD1q64wb_fixed: 2246234353Sdim case ARM::VLD1q8wb_register: 2247234353Sdim case ARM::VLD1q16wb_register: 2248234353Sdim case ARM::VLD1q32wb_register: 2249234353Sdim case ARM::VLD1q64wb_register: 2250234353Sdim case ARM::VLD1d8Twb_fixed: 2251234353Sdim case ARM::VLD1d8Twb_register: 2252234353Sdim case ARM::VLD1d16Twb_fixed: 2253234353Sdim case ARM::VLD1d16Twb_register: 2254234353Sdim case ARM::VLD1d32Twb_fixed: 2255234353Sdim case ARM::VLD1d32Twb_register: 2256234353Sdim case ARM::VLD1d64Twb_fixed: 2257234353Sdim case ARM::VLD1d64Twb_register: 2258234353Sdim case ARM::VLD1d8Qwb_fixed: 2259234353Sdim case ARM::VLD1d8Qwb_register: 2260234353Sdim case ARM::VLD1d16Qwb_fixed: 2261234353Sdim case ARM::VLD1d16Qwb_register: 2262234353Sdim case ARM::VLD1d32Qwb_fixed: 2263234353Sdim case ARM::VLD1d32Qwb_register: 2264234353Sdim case ARM::VLD1d64Qwb_fixed: 2265234353Sdim case ARM::VLD1d64Qwb_register: 2266234353Sdim case ARM::VLD2d8wb_fixed: 2267234353Sdim case ARM::VLD2d16wb_fixed: 2268234353Sdim case ARM::VLD2d32wb_fixed: 2269234353Sdim case ARM::VLD2q8wb_fixed: 2270234353Sdim case ARM::VLD2q16wb_fixed: 2271234353Sdim case ARM::VLD2q32wb_fixed: 2272234353Sdim case ARM::VLD2d8wb_register: 2273234353Sdim case ARM::VLD2d16wb_register: 2274234353Sdim case ARM::VLD2d32wb_register: 2275234353Sdim case ARM::VLD2q8wb_register: 2276234353Sdim case ARM::VLD2q16wb_register: 2277234353Sdim case ARM::VLD2q32wb_register: 2278234353Sdim case ARM::VLD2b8wb_fixed: 2279234353Sdim case ARM::VLD2b16wb_fixed: 2280234353Sdim case ARM::VLD2b32wb_fixed: 2281234353Sdim case ARM::VLD2b8wb_register: 2282234353Sdim case ARM::VLD2b16wb_register: 2283234353Sdim case ARM::VLD2b32wb_register: 2284234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2285234353Sdim break; 2286226633Sdim case ARM::VLD3d8_UPD: 2287226633Sdim case ARM::VLD3d16_UPD: 2288226633Sdim case ARM::VLD3d32_UPD: 2289226633Sdim case ARM::VLD3q8_UPD: 2290226633Sdim case ARM::VLD3q16_UPD: 2291226633Sdim case ARM::VLD3q32_UPD: 2292226633Sdim case ARM::VLD4d8_UPD: 2293226633Sdim case ARM::VLD4d16_UPD: 2294226633Sdim case ARM::VLD4d32_UPD: 2295226633Sdim case ARM::VLD4q8_UPD: 2296226633Sdim case ARM::VLD4q16_UPD: 2297226633Sdim case ARM::VLD4q32_UPD: 2298226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2299226633Sdim return MCDisassembler::Fail; 2300226633Sdim break; 2301226633Sdim default: 2302226633Sdim break; 2303226633Sdim } 2304226633Sdim 2305226633Sdim // AddrMode6 Base (register+alignment) 2306226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2307226633Sdim return MCDisassembler::Fail; 2308226633Sdim 2309226633Sdim // AddrMode6 Offset (register) 2310234353Sdim switch (Inst.getOpcode()) { 2311234353Sdim default: 2312234353Sdim // The below have been updated to have explicit am6offset split 2313234353Sdim // between fixed and register offset. For those instructions not 2314234353Sdim // yet updated, we need to add an additional reg0 operand for the 2315234353Sdim // fixed variant. 2316234353Sdim // 2317234353Sdim // The fixed offset encodes as Rm == 0xd, so we check for that. 2318234353Sdim if (Rm == 0xd) { 2319234353Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2320234353Sdim break; 2321234353Sdim } 2322234353Sdim // Fall through to handle the register offset variant. 2323234353Sdim case ARM::VLD1d8wb_fixed: 2324234353Sdim case ARM::VLD1d16wb_fixed: 2325234353Sdim case ARM::VLD1d32wb_fixed: 2326234353Sdim case ARM::VLD1d64wb_fixed: 2327234353Sdim case ARM::VLD1d8Twb_fixed: 2328234353Sdim case ARM::VLD1d16Twb_fixed: 2329234353Sdim case ARM::VLD1d32Twb_fixed: 2330234353Sdim case ARM::VLD1d64Twb_fixed: 2331234353Sdim case ARM::VLD1d8Qwb_fixed: 2332234353Sdim case ARM::VLD1d16Qwb_fixed: 2333234353Sdim case ARM::VLD1d32Qwb_fixed: 2334234353Sdim case ARM::VLD1d64Qwb_fixed: 2335234353Sdim case ARM::VLD1d8wb_register: 2336234353Sdim case ARM::VLD1d16wb_register: 2337234353Sdim case ARM::VLD1d32wb_register: 2338234353Sdim case ARM::VLD1d64wb_register: 2339234353Sdim case ARM::VLD1q8wb_fixed: 2340234353Sdim case ARM::VLD1q16wb_fixed: 2341234353Sdim case ARM::VLD1q32wb_fixed: 2342234353Sdim case ARM::VLD1q64wb_fixed: 2343234353Sdim case ARM::VLD1q8wb_register: 2344234353Sdim case ARM::VLD1q16wb_register: 2345234353Sdim case ARM::VLD1q32wb_register: 2346234353Sdim case ARM::VLD1q64wb_register: 2347234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2348234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2349234353Sdim // increment and we need to add the register operand to the instruction. 2350234353Sdim if (Rm != 0xD && Rm != 0xF && 2351234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2352226633Sdim return MCDisassembler::Fail; 2353234353Sdim break; 2354234353Sdim case ARM::VLD2d8wb_fixed: 2355234353Sdim case ARM::VLD2d16wb_fixed: 2356234353Sdim case ARM::VLD2d32wb_fixed: 2357234353Sdim case ARM::VLD2b8wb_fixed: 2358234353Sdim case ARM::VLD2b16wb_fixed: 2359234353Sdim case ARM::VLD2b32wb_fixed: 2360234353Sdim case ARM::VLD2q8wb_fixed: 2361234353Sdim case ARM::VLD2q16wb_fixed: 2362234353Sdim case ARM::VLD2q32wb_fixed: 2363234353Sdim break; 2364226633Sdim } 2365226633Sdim 2366226633Sdim return S; 2367226633Sdim} 2368226633Sdim 2369234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn, 2370226633Sdim uint64_t Address, const void *Decoder) { 2371226633Sdim DecodeStatus S = MCDisassembler::Success; 2372226633Sdim 2373226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2374226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2375226633Sdim unsigned wb = fieldFromInstruction32(Insn, 16, 4); 2376226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2377226633Sdim Rn |= fieldFromInstruction32(Insn, 4, 2) << 4; 2378226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2379226633Sdim 2380226633Sdim // Writeback Operand 2381226633Sdim switch (Inst.getOpcode()) { 2382234353Sdim case ARM::VST1d8wb_fixed: 2383234353Sdim case ARM::VST1d16wb_fixed: 2384234353Sdim case ARM::VST1d32wb_fixed: 2385234353Sdim case ARM::VST1d64wb_fixed: 2386234353Sdim case ARM::VST1d8wb_register: 2387234353Sdim case ARM::VST1d16wb_register: 2388234353Sdim case ARM::VST1d32wb_register: 2389234353Sdim case ARM::VST1d64wb_register: 2390234353Sdim case ARM::VST1q8wb_fixed: 2391234353Sdim case ARM::VST1q16wb_fixed: 2392234353Sdim case ARM::VST1q32wb_fixed: 2393234353Sdim case ARM::VST1q64wb_fixed: 2394234353Sdim case ARM::VST1q8wb_register: 2395234353Sdim case ARM::VST1q16wb_register: 2396234353Sdim case ARM::VST1q32wb_register: 2397234353Sdim case ARM::VST1q64wb_register: 2398234353Sdim case ARM::VST1d8Twb_fixed: 2399234353Sdim case ARM::VST1d16Twb_fixed: 2400234353Sdim case ARM::VST1d32Twb_fixed: 2401234353Sdim case ARM::VST1d64Twb_fixed: 2402234353Sdim case ARM::VST1d8Twb_register: 2403234353Sdim case ARM::VST1d16Twb_register: 2404234353Sdim case ARM::VST1d32Twb_register: 2405234353Sdim case ARM::VST1d64Twb_register: 2406234353Sdim case ARM::VST1d8Qwb_fixed: 2407234353Sdim case ARM::VST1d16Qwb_fixed: 2408234353Sdim case ARM::VST1d32Qwb_fixed: 2409234353Sdim case ARM::VST1d64Qwb_fixed: 2410234353Sdim case ARM::VST1d8Qwb_register: 2411234353Sdim case ARM::VST1d16Qwb_register: 2412234353Sdim case ARM::VST1d32Qwb_register: 2413234353Sdim case ARM::VST1d64Qwb_register: 2414234353Sdim case ARM::VST2d8wb_fixed: 2415234353Sdim case ARM::VST2d16wb_fixed: 2416234353Sdim case ARM::VST2d32wb_fixed: 2417234353Sdim case ARM::VST2d8wb_register: 2418234353Sdim case ARM::VST2d16wb_register: 2419234353Sdim case ARM::VST2d32wb_register: 2420234353Sdim case ARM::VST2q8wb_fixed: 2421234353Sdim case ARM::VST2q16wb_fixed: 2422234353Sdim case ARM::VST2q32wb_fixed: 2423234353Sdim case ARM::VST2q8wb_register: 2424234353Sdim case ARM::VST2q16wb_register: 2425234353Sdim case ARM::VST2q32wb_register: 2426234353Sdim case ARM::VST2b8wb_fixed: 2427234353Sdim case ARM::VST2b16wb_fixed: 2428234353Sdim case ARM::VST2b32wb_fixed: 2429234353Sdim case ARM::VST2b8wb_register: 2430234353Sdim case ARM::VST2b16wb_register: 2431234353Sdim case ARM::VST2b32wb_register: 2432234353Sdim if (Rm == 0xF) 2433234353Sdim return MCDisassembler::Fail; 2434234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2435234353Sdim break; 2436226633Sdim case ARM::VST3d8_UPD: 2437226633Sdim case ARM::VST3d16_UPD: 2438226633Sdim case ARM::VST3d32_UPD: 2439226633Sdim case ARM::VST3q8_UPD: 2440226633Sdim case ARM::VST3q16_UPD: 2441226633Sdim case ARM::VST3q32_UPD: 2442226633Sdim case ARM::VST4d8_UPD: 2443226633Sdim case ARM::VST4d16_UPD: 2444226633Sdim case ARM::VST4d32_UPD: 2445226633Sdim case ARM::VST4q8_UPD: 2446226633Sdim case ARM::VST4q16_UPD: 2447226633Sdim case ARM::VST4q32_UPD: 2448226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2449226633Sdim return MCDisassembler::Fail; 2450226633Sdim break; 2451226633Sdim default: 2452226633Sdim break; 2453226633Sdim } 2454226633Sdim 2455226633Sdim // AddrMode6 Base (register+alignment) 2456226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2457226633Sdim return MCDisassembler::Fail; 2458226633Sdim 2459226633Sdim // AddrMode6 Offset (register) 2460234353Sdim switch (Inst.getOpcode()) { 2461234353Sdim default: 2462234353Sdim if (Rm == 0xD) 2463234353Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2464234353Sdim else if (Rm != 0xF) { 2465234353Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2466234353Sdim return MCDisassembler::Fail; 2467234353Sdim } 2468234353Sdim break; 2469234353Sdim case ARM::VST1d8wb_fixed: 2470234353Sdim case ARM::VST1d16wb_fixed: 2471234353Sdim case ARM::VST1d32wb_fixed: 2472234353Sdim case ARM::VST1d64wb_fixed: 2473234353Sdim case ARM::VST1q8wb_fixed: 2474234353Sdim case ARM::VST1q16wb_fixed: 2475234353Sdim case ARM::VST1q32wb_fixed: 2476234353Sdim case ARM::VST1q64wb_fixed: 2477234353Sdim case ARM::VST1d8Twb_fixed: 2478234353Sdim case ARM::VST1d16Twb_fixed: 2479234353Sdim case ARM::VST1d32Twb_fixed: 2480234353Sdim case ARM::VST1d64Twb_fixed: 2481234353Sdim case ARM::VST1d8Qwb_fixed: 2482234353Sdim case ARM::VST1d16Qwb_fixed: 2483234353Sdim case ARM::VST1d32Qwb_fixed: 2484234353Sdim case ARM::VST1d64Qwb_fixed: 2485234353Sdim case ARM::VST2d8wb_fixed: 2486234353Sdim case ARM::VST2d16wb_fixed: 2487234353Sdim case ARM::VST2d32wb_fixed: 2488234353Sdim case ARM::VST2q8wb_fixed: 2489234353Sdim case ARM::VST2q16wb_fixed: 2490234353Sdim case ARM::VST2q32wb_fixed: 2491234353Sdim case ARM::VST2b8wb_fixed: 2492234353Sdim case ARM::VST2b16wb_fixed: 2493234353Sdim case ARM::VST2b32wb_fixed: 2494234353Sdim break; 2495226633Sdim } 2496226633Sdim 2497234353Sdim 2498226633Sdim // First input register 2499234353Sdim switch (Inst.getOpcode()) { 2500234353Sdim case ARM::VST1q16: 2501234353Sdim case ARM::VST1q32: 2502234353Sdim case ARM::VST1q64: 2503234353Sdim case ARM::VST1q8: 2504234353Sdim case ARM::VST1q16wb_fixed: 2505234353Sdim case ARM::VST1q16wb_register: 2506234353Sdim case ARM::VST1q32wb_fixed: 2507234353Sdim case ARM::VST1q32wb_register: 2508234353Sdim case ARM::VST1q64wb_fixed: 2509234353Sdim case ARM::VST1q64wb_register: 2510234353Sdim case ARM::VST1q8wb_fixed: 2511234353Sdim case ARM::VST1q8wb_register: 2512234353Sdim case ARM::VST2d16: 2513234353Sdim case ARM::VST2d32: 2514234353Sdim case ARM::VST2d8: 2515234353Sdim case ARM::VST2d16wb_fixed: 2516234353Sdim case ARM::VST2d16wb_register: 2517234353Sdim case ARM::VST2d32wb_fixed: 2518234353Sdim case ARM::VST2d32wb_register: 2519234353Sdim case ARM::VST2d8wb_fixed: 2520234353Sdim case ARM::VST2d8wb_register: 2521234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2522234353Sdim return MCDisassembler::Fail; 2523234353Sdim break; 2524234353Sdim case ARM::VST2b16: 2525234353Sdim case ARM::VST2b32: 2526234353Sdim case ARM::VST2b8: 2527234353Sdim case ARM::VST2b16wb_fixed: 2528234353Sdim case ARM::VST2b16wb_register: 2529234353Sdim case ARM::VST2b32wb_fixed: 2530234353Sdim case ARM::VST2b32wb_register: 2531234353Sdim case ARM::VST2b8wb_fixed: 2532234353Sdim case ARM::VST2b8wb_register: 2533234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2534234353Sdim return MCDisassembler::Fail; 2535234353Sdim break; 2536234353Sdim default: 2537234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2538234353Sdim return MCDisassembler::Fail; 2539234353Sdim } 2540226633Sdim 2541226633Sdim // Second input register 2542226633Sdim switch (Inst.getOpcode()) { 2543226633Sdim case ARM::VST3d8: 2544226633Sdim case ARM::VST3d16: 2545226633Sdim case ARM::VST3d32: 2546226633Sdim case ARM::VST3d8_UPD: 2547226633Sdim case ARM::VST3d16_UPD: 2548226633Sdim case ARM::VST3d32_UPD: 2549226633Sdim case ARM::VST4d8: 2550226633Sdim case ARM::VST4d16: 2551226633Sdim case ARM::VST4d32: 2552226633Sdim case ARM::VST4d8_UPD: 2553226633Sdim case ARM::VST4d16_UPD: 2554226633Sdim case ARM::VST4d32_UPD: 2555226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2556226633Sdim return MCDisassembler::Fail; 2557226633Sdim break; 2558226633Sdim case ARM::VST3q8: 2559226633Sdim case ARM::VST3q16: 2560226633Sdim case ARM::VST3q32: 2561226633Sdim case ARM::VST3q8_UPD: 2562226633Sdim case ARM::VST3q16_UPD: 2563226633Sdim case ARM::VST3q32_UPD: 2564226633Sdim case ARM::VST4q8: 2565226633Sdim case ARM::VST4q16: 2566226633Sdim case ARM::VST4q32: 2567226633Sdim case ARM::VST4q8_UPD: 2568226633Sdim case ARM::VST4q16_UPD: 2569226633Sdim case ARM::VST4q32_UPD: 2570226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2571226633Sdim return MCDisassembler::Fail; 2572226633Sdim break; 2573226633Sdim default: 2574226633Sdim break; 2575226633Sdim } 2576226633Sdim 2577226633Sdim // Third input register 2578226633Sdim switch (Inst.getOpcode()) { 2579226633Sdim case ARM::VST3d8: 2580226633Sdim case ARM::VST3d16: 2581226633Sdim case ARM::VST3d32: 2582226633Sdim case ARM::VST3d8_UPD: 2583226633Sdim case ARM::VST3d16_UPD: 2584226633Sdim case ARM::VST3d32_UPD: 2585226633Sdim case ARM::VST4d8: 2586226633Sdim case ARM::VST4d16: 2587226633Sdim case ARM::VST4d32: 2588226633Sdim case ARM::VST4d8_UPD: 2589226633Sdim case ARM::VST4d16_UPD: 2590226633Sdim case ARM::VST4d32_UPD: 2591226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2592226633Sdim return MCDisassembler::Fail; 2593226633Sdim break; 2594226633Sdim case ARM::VST3q8: 2595226633Sdim case ARM::VST3q16: 2596226633Sdim case ARM::VST3q32: 2597226633Sdim case ARM::VST3q8_UPD: 2598226633Sdim case ARM::VST3q16_UPD: 2599226633Sdim case ARM::VST3q32_UPD: 2600226633Sdim case ARM::VST4q8: 2601226633Sdim case ARM::VST4q16: 2602226633Sdim case ARM::VST4q32: 2603226633Sdim case ARM::VST4q8_UPD: 2604226633Sdim case ARM::VST4q16_UPD: 2605226633Sdim case ARM::VST4q32_UPD: 2606226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2607226633Sdim return MCDisassembler::Fail; 2608226633Sdim break; 2609226633Sdim default: 2610226633Sdim break; 2611226633Sdim } 2612226633Sdim 2613226633Sdim // Fourth input register 2614226633Sdim switch (Inst.getOpcode()) { 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+3)%32, Address, Decoder))) 2622226633Sdim return MCDisassembler::Fail; 2623226633Sdim break; 2624226633Sdim case ARM::VST4q8: 2625226633Sdim case ARM::VST4q16: 2626226633Sdim case ARM::VST4q32: 2627226633Sdim case ARM::VST4q8_UPD: 2628226633Sdim case ARM::VST4q16_UPD: 2629226633Sdim case ARM::VST4q32_UPD: 2630226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2631226633Sdim return MCDisassembler::Fail; 2632226633Sdim break; 2633226633Sdim default: 2634226633Sdim break; 2635226633Sdim } 2636226633Sdim 2637226633Sdim return S; 2638226633Sdim} 2639226633Sdim 2640234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn, 2641226633Sdim uint64_t Address, const void *Decoder) { 2642226633Sdim DecodeStatus S = MCDisassembler::Success; 2643226633Sdim 2644226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2645226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2646226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2647226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2648226633Sdim unsigned align = fieldFromInstruction32(Insn, 4, 1); 2649226633Sdim unsigned size = fieldFromInstruction32(Insn, 6, 2); 2650226633Sdim 2651226633Sdim align *= (1 << size); 2652226633Sdim 2653234353Sdim switch (Inst.getOpcode()) { 2654234353Sdim case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8: 2655234353Sdim case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register: 2656234353Sdim case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register: 2657234353Sdim case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register: 2658234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2659226633Sdim return MCDisassembler::Fail; 2660234353Sdim break; 2661234353Sdim default: 2662234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2663234353Sdim return MCDisassembler::Fail; 2664234353Sdim break; 2665226633Sdim } 2666226633Sdim if (Rm != 0xF) { 2667226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2668226633Sdim return MCDisassembler::Fail; 2669226633Sdim } 2670226633Sdim 2671226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2672226633Sdim return MCDisassembler::Fail; 2673226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2674226633Sdim 2675234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2676234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2677234353Sdim // increment and we need to add the register operand to the instruction. 2678234353Sdim if (Rm != 0xD && Rm != 0xF && 2679234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2680234353Sdim return MCDisassembler::Fail; 2681226633Sdim 2682226633Sdim return S; 2683226633Sdim} 2684226633Sdim 2685234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, 2686226633Sdim uint64_t Address, const void *Decoder) { 2687226633Sdim DecodeStatus S = MCDisassembler::Success; 2688226633Sdim 2689226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2690226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2691226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2692226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2693226633Sdim unsigned align = fieldFromInstruction32(Insn, 4, 1); 2694226633Sdim unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2); 2695226633Sdim align *= 2*size; 2696226633Sdim 2697234353Sdim switch (Inst.getOpcode()) { 2698234353Sdim case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8: 2699234353Sdim case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register: 2700234353Sdim case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register: 2701234353Sdim case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register: 2702234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2703226633Sdim return MCDisassembler::Fail; 2704234353Sdim break; 2705234353Sdim case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2: 2706234353Sdim case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register: 2707234353Sdim case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register: 2708234353Sdim case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register: 2709234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2710234353Sdim return MCDisassembler::Fail; 2711234353Sdim break; 2712234353Sdim default: 2713234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2714234353Sdim return MCDisassembler::Fail; 2715234353Sdim break; 2716226633Sdim } 2717226633Sdim 2718234353Sdim if (Rm != 0xF) 2719234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2720234353Sdim 2721226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2722226633Sdim return MCDisassembler::Fail; 2723226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2724226633Sdim 2725234982Sdim if (Rm != 0xD && Rm != 0xF) { 2726226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2727226633Sdim return MCDisassembler::Fail; 2728226633Sdim } 2729226633Sdim 2730226633Sdim return S; 2731226633Sdim} 2732226633Sdim 2733234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn, 2734226633Sdim uint64_t Address, const void *Decoder) { 2735226633Sdim DecodeStatus S = MCDisassembler::Success; 2736226633Sdim 2737226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2738226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2739226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2740226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2741226633Sdim unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1; 2742226633Sdim 2743226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2744226633Sdim return MCDisassembler::Fail; 2745226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 2746226633Sdim return MCDisassembler::Fail; 2747226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 2748226633Sdim return MCDisassembler::Fail; 2749226633Sdim if (Rm != 0xF) { 2750226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2751226633Sdim return MCDisassembler::Fail; 2752226633Sdim } 2753226633Sdim 2754226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2755226633Sdim return MCDisassembler::Fail; 2756226633Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2757226633Sdim 2758226633Sdim if (Rm == 0xD) 2759226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2760226633Sdim else if (Rm != 0xF) { 2761226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2762226633Sdim return MCDisassembler::Fail; 2763226633Sdim } 2764226633Sdim 2765226633Sdim return S; 2766226633Sdim} 2767226633Sdim 2768234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn, 2769226633Sdim uint64_t Address, const void *Decoder) { 2770226633Sdim DecodeStatus S = MCDisassembler::Success; 2771226633Sdim 2772226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2773226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2774226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2775226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2776226633Sdim unsigned size = fieldFromInstruction32(Insn, 6, 2); 2777226633Sdim unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1; 2778226633Sdim unsigned align = fieldFromInstruction32(Insn, 4, 1); 2779226633Sdim 2780226633Sdim if (size == 0x3) { 2781226633Sdim size = 4; 2782226633Sdim align = 16; 2783226633Sdim } else { 2784226633Sdim if (size == 2) { 2785226633Sdim size = 1 << size; 2786226633Sdim align *= 8; 2787226633Sdim } else { 2788226633Sdim size = 1 << size; 2789226633Sdim align *= 4*size; 2790206124Srdivacky } 2791206124Srdivacky } 2792206124Srdivacky 2793226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2794226633Sdim return MCDisassembler::Fail; 2795226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 2796226633Sdim return MCDisassembler::Fail; 2797226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 2798226633Sdim return MCDisassembler::Fail; 2799226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder))) 2800226633Sdim return MCDisassembler::Fail; 2801226633Sdim if (Rm != 0xF) { 2802226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2803226633Sdim return MCDisassembler::Fail; 2804226633Sdim } 2805226633Sdim 2806226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2807226633Sdim return MCDisassembler::Fail; 2808226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2809226633Sdim 2810226633Sdim if (Rm == 0xD) 2811226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2812226633Sdim else if (Rm != 0xF) { 2813226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2814226633Sdim return MCDisassembler::Fail; 2815226633Sdim } 2816226633Sdim 2817226633Sdim return S; 2818206124Srdivacky} 2819206124Srdivacky 2820226633Sdimstatic DecodeStatus 2821234353SdimDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn, 2822226633Sdim uint64_t Address, const void *Decoder) { 2823226633Sdim DecodeStatus S = MCDisassembler::Success; 2824206124Srdivacky 2825226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2826226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2827226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 4); 2828226633Sdim imm |= fieldFromInstruction32(Insn, 16, 3) << 4; 2829226633Sdim imm |= fieldFromInstruction32(Insn, 24, 1) << 7; 2830226633Sdim imm |= fieldFromInstruction32(Insn, 8, 4) << 8; 2831226633Sdim imm |= fieldFromInstruction32(Insn, 5, 1) << 12; 2832226633Sdim unsigned Q = fieldFromInstruction32(Insn, 6, 1); 2833206124Srdivacky 2834226633Sdim if (Q) { 2835226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 2836226633Sdim return MCDisassembler::Fail; 2837226633Sdim } else { 2838226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2839226633Sdim return MCDisassembler::Fail; 2840226633Sdim } 2841206124Srdivacky 2842226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2843206124Srdivacky 2844226633Sdim switch (Inst.getOpcode()) { 2845226633Sdim case ARM::VORRiv4i16: 2846226633Sdim case ARM::VORRiv2i32: 2847226633Sdim case ARM::VBICiv4i16: 2848226633Sdim case ARM::VBICiv2i32: 2849226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2850226633Sdim return MCDisassembler::Fail; 2851226633Sdim break; 2852226633Sdim case ARM::VORRiv8i16: 2853226633Sdim case ARM::VORRiv4i32: 2854226633Sdim case ARM::VBICiv8i16: 2855226633Sdim case ARM::VBICiv4i32: 2856226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 2857226633Sdim return MCDisassembler::Fail; 2858226633Sdim break; 2859226633Sdim default: 2860226633Sdim break; 2861226633Sdim } 2862206124Srdivacky 2863226633Sdim return S; 2864226633Sdim} 2865226633Sdim 2866234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn, 2867226633Sdim uint64_t Address, const void *Decoder) { 2868226633Sdim DecodeStatus S = MCDisassembler::Success; 2869226633Sdim 2870226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2871226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2872226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2873226633Sdim Rm |= fieldFromInstruction32(Insn, 5, 1) << 4; 2874226633Sdim unsigned size = fieldFromInstruction32(Insn, 18, 2); 2875226633Sdim 2876226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 2877226633Sdim return MCDisassembler::Fail; 2878226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 2879226633Sdim return MCDisassembler::Fail; 2880226633Sdim Inst.addOperand(MCOperand::CreateImm(8 << size)); 2881226633Sdim 2882226633Sdim return S; 2883226633Sdim} 2884226633Sdim 2885234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 2886226633Sdim uint64_t Address, const void *Decoder) { 2887226633Sdim Inst.addOperand(MCOperand::CreateImm(8 - Val)); 2888226633Sdim return MCDisassembler::Success; 2889226633Sdim} 2890226633Sdim 2891234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 2892226633Sdim uint64_t Address, const void *Decoder) { 2893226633Sdim Inst.addOperand(MCOperand::CreateImm(16 - Val)); 2894226633Sdim return MCDisassembler::Success; 2895226633Sdim} 2896226633Sdim 2897234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 2898226633Sdim uint64_t Address, const void *Decoder) { 2899226633Sdim Inst.addOperand(MCOperand::CreateImm(32 - Val)); 2900226633Sdim return MCDisassembler::Success; 2901226633Sdim} 2902226633Sdim 2903234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 2904226633Sdim uint64_t Address, const void *Decoder) { 2905226633Sdim Inst.addOperand(MCOperand::CreateImm(64 - Val)); 2906226633Sdim return MCDisassembler::Success; 2907226633Sdim} 2908226633Sdim 2909234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 2910226633Sdim uint64_t Address, const void *Decoder) { 2911226633Sdim DecodeStatus S = MCDisassembler::Success; 2912226633Sdim 2913226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 2914226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 2915226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 2916226633Sdim Rn |= fieldFromInstruction32(Insn, 7, 1) << 4; 2917226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 2918226633Sdim Rm |= fieldFromInstruction32(Insn, 5, 1) << 4; 2919226633Sdim unsigned op = fieldFromInstruction32(Insn, 6, 1); 2920226633Sdim 2921226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2922226633Sdim return MCDisassembler::Fail; 2923226633Sdim if (op) { 2924226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2925226633Sdim return MCDisassembler::Fail; // Writeback 2926206124Srdivacky } 2927226633Sdim 2928234353Sdim switch (Inst.getOpcode()) { 2929234353Sdim case ARM::VTBL2: 2930234353Sdim case ARM::VTBX2: 2931234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder))) 2932234353Sdim return MCDisassembler::Fail; 2933234353Sdim break; 2934234353Sdim default: 2935234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder))) 2936234353Sdim return MCDisassembler::Fail; 2937226633Sdim } 2938226633Sdim 2939226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 2940226633Sdim return MCDisassembler::Fail; 2941226633Sdim 2942226633Sdim return S; 2943206124Srdivacky} 2944206124Srdivacky 2945234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 2946226633Sdim uint64_t Address, const void *Decoder) { 2947226633Sdim DecodeStatus S = MCDisassembler::Success; 2948221345Sdim 2949226633Sdim unsigned dst = fieldFromInstruction16(Insn, 8, 3); 2950226633Sdim unsigned imm = fieldFromInstruction16(Insn, 0, 8); 2951221345Sdim 2952226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder))) 2953226633Sdim return MCDisassembler::Fail; 2954226633Sdim 2955226633Sdim switch(Inst.getOpcode()) { 2956226633Sdim default: 2957226633Sdim return MCDisassembler::Fail; 2958226633Sdim case ARM::tADR: 2959226633Sdim break; // tADR does not explicitly represent the PC as an operand. 2960226633Sdim case ARM::tADDrSPi: 2961226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 2962226633Sdim break; 2963221345Sdim } 2964226633Sdim 2965226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2966226633Sdim return S; 2967221345Sdim} 2968221345Sdim 2969234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 2970226633Sdim uint64_t Address, const void *Decoder) { 2971234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4, 2972234353Sdim true, 2, Inst, Decoder)) 2973234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1))); 2974226633Sdim return MCDisassembler::Success; 2975226633Sdim} 2976206124Srdivacky 2977234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 2978226633Sdim uint64_t Address, const void *Decoder) { 2979234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4, 2980234353Sdim true, 4, Inst, Decoder)) 2981234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val))); 2982226633Sdim return MCDisassembler::Success; 2983226633Sdim} 2984206124Srdivacky 2985234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 2986226633Sdim uint64_t Address, const void *Decoder) { 2987234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<7>(Val<<1) + 4, 2988234353Sdim true, 2, Inst, Decoder)) 2989234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1))); 2990226633Sdim return MCDisassembler::Success; 2991226633Sdim} 2992206124Srdivacky 2993234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 2994226633Sdim uint64_t Address, const void *Decoder) { 2995226633Sdim DecodeStatus S = MCDisassembler::Success; 2996206124Srdivacky 2997226633Sdim unsigned Rn = fieldFromInstruction32(Val, 0, 3); 2998226633Sdim unsigned Rm = fieldFromInstruction32(Val, 3, 3); 2999226633Sdim 3000226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3001226633Sdim return MCDisassembler::Fail; 3002226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder))) 3003226633Sdim return MCDisassembler::Fail; 3004226633Sdim 3005226633Sdim return S; 3006226633Sdim} 3007226633Sdim 3008234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 3009226633Sdim uint64_t Address, const void *Decoder) { 3010226633Sdim DecodeStatus S = MCDisassembler::Success; 3011226633Sdim 3012226633Sdim unsigned Rn = fieldFromInstruction32(Val, 0, 3); 3013226633Sdim unsigned imm = fieldFromInstruction32(Val, 3, 5); 3014226633Sdim 3015226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3016226633Sdim return MCDisassembler::Fail; 3017226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3018226633Sdim 3019226633Sdim return S; 3020226633Sdim} 3021226633Sdim 3022234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 3023226633Sdim uint64_t Address, const void *Decoder) { 3024226633Sdim unsigned imm = Val << 2; 3025226633Sdim 3026226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3027226633Sdim tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder); 3028226633Sdim 3029226633Sdim return MCDisassembler::Success; 3030226633Sdim} 3031226633Sdim 3032234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 3033226633Sdim uint64_t Address, const void *Decoder) { 3034226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3035226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3036226633Sdim 3037226633Sdim return MCDisassembler::Success; 3038226633Sdim} 3039226633Sdim 3040234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 3041226633Sdim uint64_t Address, const void *Decoder) { 3042226633Sdim DecodeStatus S = MCDisassembler::Success; 3043226633Sdim 3044226633Sdim unsigned Rn = fieldFromInstruction32(Val, 6, 4); 3045226633Sdim unsigned Rm = fieldFromInstruction32(Val, 2, 4); 3046226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 2); 3047226633Sdim 3048226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3049226633Sdim return MCDisassembler::Fail; 3050226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3051226633Sdim return MCDisassembler::Fail; 3052226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3053226633Sdim 3054226633Sdim return S; 3055226633Sdim} 3056226633Sdim 3057234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn, 3058226633Sdim uint64_t Address, const void *Decoder) { 3059226633Sdim DecodeStatus S = MCDisassembler::Success; 3060226633Sdim 3061226633Sdim switch (Inst.getOpcode()) { 3062226633Sdim case ARM::t2PLDs: 3063226633Sdim case ARM::t2PLDWs: 3064226633Sdim case ARM::t2PLIs: 3065226633Sdim break; 3066226633Sdim default: { 3067226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3068226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 3069226633Sdim return MCDisassembler::Fail; 3070206124Srdivacky } 3071226633Sdim } 3072206124Srdivacky 3073226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3074226633Sdim if (Rn == 0xF) { 3075226633Sdim switch (Inst.getOpcode()) { 3076226633Sdim case ARM::t2LDRBs: 3077226633Sdim Inst.setOpcode(ARM::t2LDRBpci); 3078226633Sdim break; 3079226633Sdim case ARM::t2LDRHs: 3080226633Sdim Inst.setOpcode(ARM::t2LDRHpci); 3081226633Sdim break; 3082226633Sdim case ARM::t2LDRSHs: 3083226633Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3084226633Sdim break; 3085226633Sdim case ARM::t2LDRSBs: 3086226633Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3087226633Sdim break; 3088226633Sdim case ARM::t2PLDs: 3089226633Sdim Inst.setOpcode(ARM::t2PLDi12); 3090226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::PC)); 3091226633Sdim break; 3092226633Sdim default: 3093226633Sdim return MCDisassembler::Fail; 3094206124Srdivacky } 3095206124Srdivacky 3096226633Sdim int imm = fieldFromInstruction32(Insn, 0, 12); 3097226633Sdim if (!fieldFromInstruction32(Insn, 23, 1)) imm *= -1; 3098226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3099221345Sdim 3100226633Sdim return S; 3101226633Sdim } 3102226633Sdim 3103226633Sdim unsigned addrmode = fieldFromInstruction32(Insn, 4, 2); 3104226633Sdim addrmode |= fieldFromInstruction32(Insn, 0, 4) << 2; 3105226633Sdim addrmode |= fieldFromInstruction32(Insn, 16, 4) << 6; 3106226633Sdim if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder))) 3107226633Sdim return MCDisassembler::Fail; 3108226633Sdim 3109226633Sdim return S; 3110226633Sdim} 3111226633Sdim 3112234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 3113226633Sdim uint64_t Address, const void *Decoder) { 3114226633Sdim int imm = Val & 0xFF; 3115226633Sdim if (!(Val & 0x100)) imm *= -1; 3116226633Sdim Inst.addOperand(MCOperand::CreateImm(imm << 2)); 3117226633Sdim 3118226633Sdim return MCDisassembler::Success; 3119226633Sdim} 3120226633Sdim 3121234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 3122226633Sdim uint64_t Address, const void *Decoder) { 3123226633Sdim DecodeStatus S = MCDisassembler::Success; 3124226633Sdim 3125226633Sdim unsigned Rn = fieldFromInstruction32(Val, 9, 4); 3126226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 9); 3127226633Sdim 3128226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3129226633Sdim return MCDisassembler::Fail; 3130226633Sdim if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder))) 3131226633Sdim return MCDisassembler::Fail; 3132226633Sdim 3133226633Sdim return S; 3134226633Sdim} 3135226633Sdim 3136234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 3137226633Sdim uint64_t Address, const void *Decoder) { 3138226633Sdim DecodeStatus S = MCDisassembler::Success; 3139226633Sdim 3140226633Sdim unsigned Rn = fieldFromInstruction32(Val, 8, 4); 3141226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 8); 3142226633Sdim 3143226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 3144226633Sdim return MCDisassembler::Fail; 3145226633Sdim 3146226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3147226633Sdim 3148226633Sdim return S; 3149226633Sdim} 3150226633Sdim 3151234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 3152226633Sdim uint64_t Address, const void *Decoder) { 3153226633Sdim int imm = Val & 0xFF; 3154226633Sdim if (Val == 0) 3155226633Sdim imm = INT32_MIN; 3156226633Sdim else if (!(Val & 0x100)) 3157226633Sdim imm *= -1; 3158226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3159226633Sdim 3160226633Sdim return MCDisassembler::Success; 3161226633Sdim} 3162226633Sdim 3163226633Sdim 3164234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 3165226633Sdim uint64_t Address, const void *Decoder) { 3166226633Sdim DecodeStatus S = MCDisassembler::Success; 3167226633Sdim 3168226633Sdim unsigned Rn = fieldFromInstruction32(Val, 9, 4); 3169226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 9); 3170226633Sdim 3171226633Sdim // Some instructions always use an additive offset. 3172226633Sdim switch (Inst.getOpcode()) { 3173226633Sdim case ARM::t2LDRT: 3174226633Sdim case ARM::t2LDRBT: 3175226633Sdim case ARM::t2LDRHT: 3176226633Sdim case ARM::t2LDRSBT: 3177226633Sdim case ARM::t2LDRSHT: 3178226633Sdim case ARM::t2STRT: 3179226633Sdim case ARM::t2STRBT: 3180226633Sdim case ARM::t2STRHT: 3181226633Sdim imm |= 0x100; 3182226633Sdim break; 3183226633Sdim default: 3184226633Sdim break; 3185226633Sdim } 3186226633Sdim 3187226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3188226633Sdim return MCDisassembler::Fail; 3189226633Sdim if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder))) 3190226633Sdim return MCDisassembler::Fail; 3191226633Sdim 3192226633Sdim return S; 3193226633Sdim} 3194226633Sdim 3195234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn, 3196226633Sdim uint64_t Address, const void *Decoder) { 3197226633Sdim DecodeStatus S = MCDisassembler::Success; 3198226633Sdim 3199226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3200226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3201226633Sdim unsigned addr = fieldFromInstruction32(Insn, 0, 8); 3202226633Sdim addr |= fieldFromInstruction32(Insn, 9, 1) << 8; 3203226633Sdim addr |= Rn << 9; 3204226633Sdim unsigned load = fieldFromInstruction32(Insn, 20, 1); 3205226633Sdim 3206226633Sdim if (!load) { 3207226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3208226633Sdim return MCDisassembler::Fail; 3209226633Sdim } 3210226633Sdim 3211226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 3212226633Sdim return MCDisassembler::Fail; 3213226633Sdim 3214226633Sdim if (load) { 3215226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3216226633Sdim return MCDisassembler::Fail; 3217226633Sdim } 3218226633Sdim 3219226633Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder))) 3220226633Sdim return MCDisassembler::Fail; 3221226633Sdim 3222226633Sdim return S; 3223226633Sdim} 3224226633Sdim 3225234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 3226226633Sdim uint64_t Address, const void *Decoder) { 3227226633Sdim DecodeStatus S = MCDisassembler::Success; 3228226633Sdim 3229226633Sdim unsigned Rn = fieldFromInstruction32(Val, 13, 4); 3230226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 12); 3231226633Sdim 3232226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3233226633Sdim return MCDisassembler::Fail; 3234226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3235226633Sdim 3236226633Sdim return S; 3237226633Sdim} 3238226633Sdim 3239226633Sdim 3240234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn, 3241226633Sdim uint64_t Address, const void *Decoder) { 3242226633Sdim unsigned imm = fieldFromInstruction16(Insn, 0, 7); 3243226633Sdim 3244226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3245226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3246226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3247226633Sdim 3248226633Sdim return MCDisassembler::Success; 3249226633Sdim} 3250226633Sdim 3251234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 3252226633Sdim uint64_t Address, const void *Decoder) { 3253226633Sdim DecodeStatus S = MCDisassembler::Success; 3254226633Sdim 3255226633Sdim if (Inst.getOpcode() == ARM::tADDrSP) { 3256226633Sdim unsigned Rdm = fieldFromInstruction16(Insn, 0, 3); 3257226633Sdim Rdm |= fieldFromInstruction16(Insn, 7, 1) << 3; 3258226633Sdim 3259226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 3260226633Sdim return MCDisassembler::Fail; 3261226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 3262226633Sdim return MCDisassembler::Fail; 3263226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3264226633Sdim } else if (Inst.getOpcode() == ARM::tADDspr) { 3265226633Sdim unsigned Rm = fieldFromInstruction16(Insn, 3, 4); 3266226633Sdim 3267226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3268226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3269226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3270226633Sdim return MCDisassembler::Fail; 3271226633Sdim } 3272226633Sdim 3273226633Sdim return S; 3274226633Sdim} 3275226633Sdim 3276234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 3277226633Sdim uint64_t Address, const void *Decoder) { 3278226633Sdim unsigned imod = fieldFromInstruction16(Insn, 4, 1) | 0x2; 3279226633Sdim unsigned flags = fieldFromInstruction16(Insn, 0, 3); 3280226633Sdim 3281226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 3282226633Sdim Inst.addOperand(MCOperand::CreateImm(flags)); 3283226633Sdim 3284226633Sdim return MCDisassembler::Success; 3285226633Sdim} 3286226633Sdim 3287234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 3288226633Sdim uint64_t Address, const void *Decoder) { 3289226633Sdim DecodeStatus S = MCDisassembler::Success; 3290226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3291226633Sdim unsigned add = fieldFromInstruction32(Insn, 4, 1); 3292226633Sdim 3293234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 3294226633Sdim return MCDisassembler::Fail; 3295226633Sdim Inst.addOperand(MCOperand::CreateImm(add)); 3296226633Sdim 3297226633Sdim return S; 3298226633Sdim} 3299226633Sdim 3300234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val, 3301226633Sdim uint64_t Address, const void *Decoder) { 3302234353Sdim if (!tryAddingSymbolicOperand(Address, 3303226633Sdim (Address & ~2u) + SignExtend32<22>(Val << 1) + 4, 3304226633Sdim true, 4, Inst, Decoder)) 3305226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1))); 3306226633Sdim return MCDisassembler::Success; 3307226633Sdim} 3308226633Sdim 3309234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val, 3310226633Sdim uint64_t Address, const void *Decoder) { 3311226633Sdim if (Val == 0xA || Val == 0xB) 3312226633Sdim return MCDisassembler::Fail; 3313226633Sdim 3314226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3315226633Sdim return MCDisassembler::Success; 3316226633Sdim} 3317226633Sdim 3318226633Sdimstatic DecodeStatus 3319234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn, 3320226633Sdim uint64_t Address, const void *Decoder) { 3321226633Sdim DecodeStatus S = MCDisassembler::Success; 3322226633Sdim 3323226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3324226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3325226633Sdim 3326226633Sdim if (Rn == ARM::SP) S = MCDisassembler::SoftFail; 3327226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3328226633Sdim return MCDisassembler::Fail; 3329226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3330226633Sdim return MCDisassembler::Fail; 3331226633Sdim return S; 3332226633Sdim} 3333226633Sdim 3334226633Sdimstatic DecodeStatus 3335234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn, 3336226633Sdim uint64_t Address, const void *Decoder) { 3337226633Sdim DecodeStatus S = MCDisassembler::Success; 3338226633Sdim 3339226633Sdim unsigned pred = fieldFromInstruction32(Insn, 22, 4); 3340226633Sdim if (pred == 0xE || pred == 0xF) { 3341226633Sdim unsigned opc = fieldFromInstruction32(Insn, 4, 28); 3342226633Sdim switch (opc) { 3343226633Sdim default: 3344226633Sdim return MCDisassembler::Fail; 3345226633Sdim case 0xf3bf8f4: 3346226633Sdim Inst.setOpcode(ARM::t2DSB); 3347226633Sdim break; 3348226633Sdim case 0xf3bf8f5: 3349226633Sdim Inst.setOpcode(ARM::t2DMB); 3350226633Sdim break; 3351226633Sdim case 0xf3bf8f6: 3352226633Sdim Inst.setOpcode(ARM::t2ISB); 3353226633Sdim break; 3354221345Sdim } 3355206124Srdivacky 3356226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 4); 3357226633Sdim return DecodeMemBarrierOption(Inst, imm, Address, Decoder); 3358226633Sdim } 3359226633Sdim 3360226633Sdim unsigned brtarget = fieldFromInstruction32(Insn, 0, 11) << 1; 3361226633Sdim brtarget |= fieldFromInstruction32(Insn, 11, 1) << 19; 3362226633Sdim brtarget |= fieldFromInstruction32(Insn, 13, 1) << 18; 3363226633Sdim brtarget |= fieldFromInstruction32(Insn, 16, 6) << 12; 3364226633Sdim brtarget |= fieldFromInstruction32(Insn, 26, 1) << 20; 3365226633Sdim 3366226633Sdim if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder))) 3367226633Sdim return MCDisassembler::Fail; 3368226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3369226633Sdim return MCDisassembler::Fail; 3370226633Sdim 3371226633Sdim return S; 3372226633Sdim} 3373226633Sdim 3374226633Sdim// Decode a shifted immediate operand. These basically consist 3375226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either 3376226633Sdim// a splat operation or a rotation. 3377234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 3378226633Sdim uint64_t Address, const void *Decoder) { 3379226633Sdim unsigned ctrl = fieldFromInstruction32(Val, 10, 2); 3380226633Sdim if (ctrl == 0) { 3381226633Sdim unsigned byte = fieldFromInstruction32(Val, 8, 2); 3382226633Sdim unsigned imm = fieldFromInstruction32(Val, 0, 8); 3383226633Sdim switch (byte) { 3384226633Sdim case 0: 3385226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3386226633Sdim break; 3387226633Sdim case 1: 3388226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm)); 3389226633Sdim break; 3390226633Sdim case 2: 3391226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8))); 3392226633Sdim break; 3393226633Sdim case 3: 3394226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) | 3395226633Sdim (imm << 8) | imm)); 3396226633Sdim break; 3397221345Sdim } 3398226633Sdim } else { 3399226633Sdim unsigned unrot = fieldFromInstruction32(Val, 0, 7) | 0x80; 3400226633Sdim unsigned rot = fieldFromInstruction32(Val, 7, 5); 3401226633Sdim unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31)); 3402226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3403226633Sdim } 3404221345Sdim 3405226633Sdim return MCDisassembler::Success; 3406226633Sdim} 3407206124Srdivacky 3408226633Sdimstatic DecodeStatus 3409234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val, 3410226633Sdim uint64_t Address, const void *Decoder){ 3411234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<8>(Val<<1) + 4, 3412234353Sdim true, 2, Inst, Decoder)) 3413234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<8>(Val << 1))); 3414226633Sdim return MCDisassembler::Success; 3415226633Sdim} 3416226633Sdim 3417234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 3418226633Sdim uint64_t Address, const void *Decoder){ 3419234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4, 3420234353Sdim true, 4, Inst, Decoder)) 3421234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1))); 3422226633Sdim return MCDisassembler::Success; 3423226633Sdim} 3424226633Sdim 3425234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val, 3426226633Sdim uint64_t Address, const void *Decoder) { 3427226633Sdim switch (Val) { 3428226633Sdim default: 3429226633Sdim return MCDisassembler::Fail; 3430226633Sdim case 0xF: // SY 3431226633Sdim case 0xE: // ST 3432226633Sdim case 0xB: // ISH 3433226633Sdim case 0xA: // ISHST 3434226633Sdim case 0x7: // NSH 3435226633Sdim case 0x6: // NSHST 3436226633Sdim case 0x3: // OSH 3437226633Sdim case 0x2: // OSHST 3438226633Sdim break; 3439206124Srdivacky } 3440206124Srdivacky 3441226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3442226633Sdim return MCDisassembler::Success; 3443206124Srdivacky} 3444206124Srdivacky 3445234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, 3446226633Sdim uint64_t Address, const void *Decoder) { 3447226633Sdim if (!Val) return MCDisassembler::Fail; 3448226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3449226633Sdim return MCDisassembler::Success; 3450226633Sdim} 3451206124Srdivacky 3452234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 3453226633Sdim uint64_t Address, const void *Decoder) { 3454226633Sdim DecodeStatus S = MCDisassembler::Success; 3455206124Srdivacky 3456226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3457226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3458226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 3459206124Srdivacky 3460226633Sdim if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; 3461206274Srdivacky 3462226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3463226633Sdim return MCDisassembler::Fail; 3464226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 3465226633Sdim return MCDisassembler::Fail; 3466226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3467226633Sdim return MCDisassembler::Fail; 3468226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3469226633Sdim return MCDisassembler::Fail; 3470206124Srdivacky 3471226633Sdim return S; 3472226633Sdim} 3473206124Srdivacky 3474206124Srdivacky 3475234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 3476226633Sdim uint64_t Address, const void *Decoder){ 3477226633Sdim DecodeStatus S = MCDisassembler::Success; 3478221345Sdim 3479226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3480226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 0, 4); 3481226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3482226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 3483206124Srdivacky 3484226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 3485226633Sdim return MCDisassembler::Fail; 3486226633Sdim 3487226633Sdim if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; 3488226633Sdim if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail; 3489226633Sdim 3490226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3491226633Sdim return MCDisassembler::Fail; 3492226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 3493226633Sdim return MCDisassembler::Fail; 3494226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3495226633Sdim return MCDisassembler::Fail; 3496226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3497226633Sdim return MCDisassembler::Fail; 3498226633Sdim 3499226633Sdim return S; 3500206124Srdivacky} 3501206124Srdivacky 3502234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 3503226633Sdim uint64_t Address, const void *Decoder) { 3504226633Sdim DecodeStatus S = MCDisassembler::Success; 3505206274Srdivacky 3506226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3507226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3508226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 12); 3509226633Sdim imm |= fieldFromInstruction32(Insn, 16, 4) << 13; 3510226633Sdim imm |= fieldFromInstruction32(Insn, 23, 1) << 12; 3511226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 3512206124Srdivacky 3513226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3514206124Srdivacky 3515226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3516226633Sdim return MCDisassembler::Fail; 3517226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3518226633Sdim return MCDisassembler::Fail; 3519226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 3520226633Sdim return MCDisassembler::Fail; 3521226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3522226633Sdim return MCDisassembler::Fail; 3523206124Srdivacky 3524226633Sdim return S; 3525226633Sdim} 3526206124Srdivacky 3527234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 3528226633Sdim uint64_t Address, const void *Decoder) { 3529226633Sdim DecodeStatus S = MCDisassembler::Success; 3530226633Sdim 3531226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3532226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3533226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 12); 3534226633Sdim imm |= fieldFromInstruction32(Insn, 16, 4) << 13; 3535226633Sdim imm |= fieldFromInstruction32(Insn, 23, 1) << 12; 3536226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 3537226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3538226633Sdim 3539226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3540226633Sdim if (Rm == 0xF) S = MCDisassembler::SoftFail; 3541226633Sdim 3542226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3543226633Sdim return MCDisassembler::Fail; 3544226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3545226633Sdim return MCDisassembler::Fail; 3546226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 3547226633Sdim return MCDisassembler::Fail; 3548226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3549226633Sdim return MCDisassembler::Fail; 3550226633Sdim 3551226633Sdim return S; 3552226633Sdim} 3553226633Sdim 3554226633Sdim 3555234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 3556226633Sdim uint64_t Address, const void *Decoder) { 3557226633Sdim DecodeStatus S = MCDisassembler::Success; 3558226633Sdim 3559226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3560226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3561226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 12); 3562226633Sdim imm |= fieldFromInstruction32(Insn, 16, 4) << 13; 3563226633Sdim imm |= fieldFromInstruction32(Insn, 23, 1) << 12; 3564226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 3565226633Sdim 3566226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3567226633Sdim 3568226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3569226633Sdim return MCDisassembler::Fail; 3570226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3571226633Sdim return MCDisassembler::Fail; 3572226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 3573226633Sdim return MCDisassembler::Fail; 3574226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3575226633Sdim return MCDisassembler::Fail; 3576226633Sdim 3577226633Sdim return S; 3578226633Sdim} 3579226633Sdim 3580234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 3581226633Sdim uint64_t Address, const void *Decoder) { 3582226633Sdim DecodeStatus S = MCDisassembler::Success; 3583226633Sdim 3584226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3585226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 3586226633Sdim unsigned imm = fieldFromInstruction32(Insn, 0, 12); 3587226633Sdim imm |= fieldFromInstruction32(Insn, 16, 4) << 13; 3588226633Sdim imm |= fieldFromInstruction32(Insn, 23, 1) << 12; 3589226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 3590226633Sdim 3591226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 3592226633Sdim 3593226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3594226633Sdim return MCDisassembler::Fail; 3595226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3596226633Sdim return MCDisassembler::Fail; 3597226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 3598226633Sdim return MCDisassembler::Fail; 3599226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3600226633Sdim return MCDisassembler::Fail; 3601226633Sdim 3602226633Sdim return S; 3603226633Sdim} 3604226633Sdim 3605234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 3606226633Sdim uint64_t Address, const void *Decoder) { 3607226633Sdim DecodeStatus S = MCDisassembler::Success; 3608226633Sdim 3609226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3610226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3611226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3612226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3613226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3614226633Sdim 3615226633Sdim unsigned align = 0; 3616226633Sdim unsigned index = 0; 3617226633Sdim switch (size) { 3618226633Sdim default: 3619226633Sdim return MCDisassembler::Fail; 3620226633Sdim case 0: 3621226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3622226633Sdim return MCDisassembler::Fail; // UNDEFINED 3623226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 3624226633Sdim break; 3625226633Sdim case 1: 3626226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3627226633Sdim return MCDisassembler::Fail; // UNDEFINED 3628226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 3629226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3630226633Sdim align = 2; 3631226633Sdim break; 3632226633Sdim case 2: 3633226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 3634226633Sdim return MCDisassembler::Fail; // UNDEFINED 3635226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 3636226633Sdim if (fieldFromInstruction32(Insn, 4, 2) != 0) 3637226633Sdim align = 4; 3638206124Srdivacky } 3639206124Srdivacky 3640226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3641226633Sdim return MCDisassembler::Fail; 3642226633Sdim if (Rm != 0xF) { // Writeback 3643226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3644226633Sdim return MCDisassembler::Fail; 3645226633Sdim } 3646226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3647226633Sdim return MCDisassembler::Fail; 3648226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3649226633Sdim if (Rm != 0xF) { 3650226633Sdim if (Rm != 0xD) { 3651226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3652226633Sdim return MCDisassembler::Fail; 3653226633Sdim } else 3654226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3655226633Sdim } 3656206124Srdivacky 3657226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3658226633Sdim return MCDisassembler::Fail; 3659226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3660206124Srdivacky 3661226633Sdim return S; 3662226633Sdim} 3663206124Srdivacky 3664234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 3665226633Sdim uint64_t Address, const void *Decoder) { 3666226633Sdim DecodeStatus S = MCDisassembler::Success; 3667206124Srdivacky 3668226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3669226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3670226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3671226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3672226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3673207618Srdivacky 3674226633Sdim unsigned align = 0; 3675226633Sdim unsigned index = 0; 3676226633Sdim switch (size) { 3677226633Sdim default: 3678226633Sdim return MCDisassembler::Fail; 3679226633Sdim case 0: 3680226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3681226633Sdim return MCDisassembler::Fail; // UNDEFINED 3682226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 3683226633Sdim break; 3684226633Sdim case 1: 3685226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3686226633Sdim return MCDisassembler::Fail; // UNDEFINED 3687226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 3688226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3689226633Sdim align = 2; 3690226633Sdim break; 3691226633Sdim case 2: 3692226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 3693226633Sdim return MCDisassembler::Fail; // UNDEFINED 3694226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 3695226633Sdim if (fieldFromInstruction32(Insn, 4, 2) != 0) 3696226633Sdim align = 4; 3697226633Sdim } 3698221345Sdim 3699226633Sdim if (Rm != 0xF) { // Writeback 3700226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3701226633Sdim return MCDisassembler::Fail; 3702226633Sdim } 3703226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3704226633Sdim return MCDisassembler::Fail; 3705226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3706226633Sdim if (Rm != 0xF) { 3707226633Sdim if (Rm != 0xD) { 3708226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3709226633Sdim return MCDisassembler::Fail; 3710226633Sdim } else 3711226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3712226633Sdim } 3713206124Srdivacky 3714226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3715226633Sdim return MCDisassembler::Fail; 3716226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3717226633Sdim 3718226633Sdim return S; 3719206124Srdivacky} 3720206124Srdivacky 3721226633Sdim 3722234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 3723226633Sdim uint64_t Address, const void *Decoder) { 3724226633Sdim DecodeStatus S = MCDisassembler::Success; 3725226633Sdim 3726226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3727226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3728226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3729226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3730226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3731226633Sdim 3732226633Sdim unsigned align = 0; 3733226633Sdim unsigned index = 0; 3734226633Sdim unsigned inc = 1; 3735226633Sdim switch (size) { 3736226633Sdim default: 3737226633Sdim return MCDisassembler::Fail; 3738226633Sdim case 0: 3739226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 3740226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3741226633Sdim align = 2; 3742226633Sdim break; 3743226633Sdim case 1: 3744226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 3745226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3746226633Sdim align = 4; 3747226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3748226633Sdim inc = 2; 3749226633Sdim break; 3750226633Sdim case 2: 3751226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3752226633Sdim return MCDisassembler::Fail; // UNDEFINED 3753226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 3754226633Sdim if (fieldFromInstruction32(Insn, 4, 1) != 0) 3755226633Sdim align = 8; 3756226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 3757226633Sdim inc = 2; 3758226633Sdim break; 3759207618Srdivacky } 3760226633Sdim 3761226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3762226633Sdim return MCDisassembler::Fail; 3763226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3764226633Sdim return MCDisassembler::Fail; 3765226633Sdim if (Rm != 0xF) { // Writeback 3766226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3767226633Sdim return MCDisassembler::Fail; 3768226633Sdim } 3769226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3770226633Sdim return MCDisassembler::Fail; 3771226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3772226633Sdim if (Rm != 0xF) { 3773226633Sdim if (Rm != 0xD) { 3774226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3775226633Sdim return MCDisassembler::Fail; 3776226633Sdim } else 3777226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3778226633Sdim } 3779226633Sdim 3780226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3781226633Sdim return MCDisassembler::Fail; 3782226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3783226633Sdim return MCDisassembler::Fail; 3784226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3785226633Sdim 3786226633Sdim return S; 3787206124Srdivacky} 3788206124Srdivacky 3789234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 3790226633Sdim uint64_t Address, const void *Decoder) { 3791226633Sdim DecodeStatus S = MCDisassembler::Success; 3792207618Srdivacky 3793226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3794226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3795226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3796226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3797226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3798226633Sdim 3799226633Sdim unsigned align = 0; 3800226633Sdim unsigned index = 0; 3801226633Sdim unsigned inc = 1; 3802226633Sdim switch (size) { 3803226633Sdim default: 3804226633Sdim return MCDisassembler::Fail; 3805226633Sdim case 0: 3806226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 3807226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3808226633Sdim align = 2; 3809226633Sdim break; 3810226633Sdim case 1: 3811226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 3812226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3813226633Sdim align = 4; 3814226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3815226633Sdim inc = 2; 3816226633Sdim break; 3817226633Sdim case 2: 3818226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3819226633Sdim return MCDisassembler::Fail; // UNDEFINED 3820226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 3821226633Sdim if (fieldFromInstruction32(Insn, 4, 1) != 0) 3822226633Sdim align = 8; 3823226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 3824226633Sdim inc = 2; 3825226633Sdim break; 3826207618Srdivacky } 3827226633Sdim 3828226633Sdim if (Rm != 0xF) { // Writeback 3829226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3830226633Sdim return MCDisassembler::Fail; 3831207618Srdivacky } 3832226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3833226633Sdim return MCDisassembler::Fail; 3834226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3835226633Sdim if (Rm != 0xF) { 3836226633Sdim if (Rm != 0xD) { 3837226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3838226633Sdim return MCDisassembler::Fail; 3839226633Sdim } else 3840226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3841226633Sdim } 3842207618Srdivacky 3843226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3844226633Sdim return MCDisassembler::Fail; 3845226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3846226633Sdim return MCDisassembler::Fail; 3847226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3848207618Srdivacky 3849226633Sdim return S; 3850206124Srdivacky} 3851206124Srdivacky 3852226633Sdim 3853234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 3854226633Sdim uint64_t Address, const void *Decoder) { 3855226633Sdim DecodeStatus S = MCDisassembler::Success; 3856226633Sdim 3857226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3858226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3859226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3860226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3861226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3862226633Sdim 3863226633Sdim unsigned align = 0; 3864226633Sdim unsigned index = 0; 3865226633Sdim unsigned inc = 1; 3866226633Sdim switch (size) { 3867226633Sdim default: 3868226633Sdim return MCDisassembler::Fail; 3869226633Sdim case 0: 3870226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3871226633Sdim return MCDisassembler::Fail; // UNDEFINED 3872226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 3873226633Sdim break; 3874226633Sdim case 1: 3875226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3876226633Sdim return MCDisassembler::Fail; // UNDEFINED 3877226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 3878226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3879226633Sdim inc = 2; 3880226633Sdim break; 3881226633Sdim case 2: 3882226633Sdim if (fieldFromInstruction32(Insn, 4, 2)) 3883226633Sdim return MCDisassembler::Fail; // UNDEFINED 3884226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 3885226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 3886226633Sdim inc = 2; 3887226633Sdim break; 3888206124Srdivacky } 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 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 3895226633Sdim return MCDisassembler::Fail; 3896226633Sdim 3897226633Sdim if (Rm != 0xF) { // Writeback 3898226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3899226633Sdim return MCDisassembler::Fail; 3900226633Sdim } 3901226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3902226633Sdim return MCDisassembler::Fail; 3903226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3904226633Sdim if (Rm != 0xF) { 3905226633Sdim if (Rm != 0xD) { 3906226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3907226633Sdim return MCDisassembler::Fail; 3908226633Sdim } else 3909226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3910226633Sdim } 3911226633Sdim 3912226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3913226633Sdim return MCDisassembler::Fail; 3914226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3915226633Sdim return MCDisassembler::Fail; 3916226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 3917226633Sdim return MCDisassembler::Fail; 3918226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3919226633Sdim 3920226633Sdim return S; 3921206124Srdivacky} 3922206124Srdivacky 3923234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 3924226633Sdim uint64_t Address, const void *Decoder) { 3925226633Sdim DecodeStatus S = MCDisassembler::Success; 3926226633Sdim 3927226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3928226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3929226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3930226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3931226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3932226633Sdim 3933226633Sdim unsigned align = 0; 3934226633Sdim unsigned index = 0; 3935226633Sdim unsigned inc = 1; 3936226633Sdim switch (size) { 3937226633Sdim default: 3938226633Sdim return MCDisassembler::Fail; 3939226633Sdim case 0: 3940226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3941226633Sdim return MCDisassembler::Fail; // UNDEFINED 3942226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 3943226633Sdim break; 3944226633Sdim case 1: 3945226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 3946226633Sdim return MCDisassembler::Fail; // UNDEFINED 3947226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 3948226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 3949226633Sdim inc = 2; 3950226633Sdim break; 3951226633Sdim case 2: 3952226633Sdim if (fieldFromInstruction32(Insn, 4, 2)) 3953226633Sdim return MCDisassembler::Fail; // UNDEFINED 3954226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 3955226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 3956226633Sdim inc = 2; 3957226633Sdim break; 3958226633Sdim } 3959226633Sdim 3960226633Sdim if (Rm != 0xF) { // Writeback 3961226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3962226633Sdim return MCDisassembler::Fail; 3963226633Sdim } 3964226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3965226633Sdim return MCDisassembler::Fail; 3966226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3967226633Sdim if (Rm != 0xF) { 3968226633Sdim if (Rm != 0xD) { 3969226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3970226633Sdim return MCDisassembler::Fail; 3971226633Sdim } else 3972226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3973226633Sdim } 3974226633Sdim 3975226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3976226633Sdim return MCDisassembler::Fail; 3977226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 3978226633Sdim return MCDisassembler::Fail; 3979226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 3980226633Sdim return MCDisassembler::Fail; 3981226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 3982226633Sdim 3983226633Sdim return S; 3984206124Srdivacky} 3985206124Srdivacky 3986226633Sdim 3987234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 3988226633Sdim uint64_t Address, const void *Decoder) { 3989226633Sdim DecodeStatus S = MCDisassembler::Success; 3990226633Sdim 3991226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 3992226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 3993226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 3994226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 3995226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 3996226633Sdim 3997226633Sdim unsigned align = 0; 3998226633Sdim unsigned index = 0; 3999226633Sdim unsigned inc = 1; 4000226633Sdim switch (size) { 4001226633Sdim default: 4002226633Sdim return MCDisassembler::Fail; 4003226633Sdim case 0: 4004226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 4005226633Sdim align = 4; 4006226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 4007226633Sdim break; 4008226633Sdim case 1: 4009226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 4010226633Sdim align = 8; 4011226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 4012226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 4013226633Sdim inc = 2; 4014226633Sdim break; 4015226633Sdim case 2: 4016226633Sdim if (fieldFromInstruction32(Insn, 4, 2)) 4017226633Sdim align = 4 << fieldFromInstruction32(Insn, 4, 2); 4018226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 4019226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 4020226633Sdim inc = 2; 4021226633Sdim break; 4022226633Sdim } 4023226633Sdim 4024226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4025226633Sdim return MCDisassembler::Fail; 4026226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4027226633Sdim return MCDisassembler::Fail; 4028226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4029226633Sdim return MCDisassembler::Fail; 4030226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4031226633Sdim return MCDisassembler::Fail; 4032226633Sdim 4033226633Sdim if (Rm != 0xF) { // Writeback 4034226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4035226633Sdim return MCDisassembler::Fail; 4036226633Sdim } 4037226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4038226633Sdim return MCDisassembler::Fail; 4039226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4040226633Sdim if (Rm != 0xF) { 4041226633Sdim if (Rm != 0xD) { 4042226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4043226633Sdim return MCDisassembler::Fail; 4044226633Sdim } else 4045226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4046226633Sdim } 4047226633Sdim 4048226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4049226633Sdim return MCDisassembler::Fail; 4050226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4051226633Sdim return MCDisassembler::Fail; 4052226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4053226633Sdim return MCDisassembler::Fail; 4054226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4055226633Sdim return MCDisassembler::Fail; 4056226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4057226633Sdim 4058226633Sdim return S; 4059206124Srdivacky} 4060206124Srdivacky 4061234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 4062226633Sdim uint64_t Address, const void *Decoder) { 4063226633Sdim DecodeStatus S = MCDisassembler::Success; 4064226633Sdim 4065226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 4066226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 4067226633Sdim unsigned Rd = fieldFromInstruction32(Insn, 12, 4); 4068226633Sdim Rd |= fieldFromInstruction32(Insn, 22, 1) << 4; 4069226633Sdim unsigned size = fieldFromInstruction32(Insn, 10, 2); 4070226633Sdim 4071226633Sdim unsigned align = 0; 4072226633Sdim unsigned index = 0; 4073226633Sdim unsigned inc = 1; 4074226633Sdim switch (size) { 4075226633Sdim default: 4076226633Sdim return MCDisassembler::Fail; 4077226633Sdim case 0: 4078226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 4079226633Sdim align = 4; 4080226633Sdim index = fieldFromInstruction32(Insn, 5, 3); 4081226633Sdim break; 4082226633Sdim case 1: 4083226633Sdim if (fieldFromInstruction32(Insn, 4, 1)) 4084226633Sdim align = 8; 4085226633Sdim index = fieldFromInstruction32(Insn, 6, 2); 4086226633Sdim if (fieldFromInstruction32(Insn, 5, 1)) 4087226633Sdim inc = 2; 4088226633Sdim break; 4089226633Sdim case 2: 4090226633Sdim if (fieldFromInstruction32(Insn, 4, 2)) 4091226633Sdim align = 4 << fieldFromInstruction32(Insn, 4, 2); 4092226633Sdim index = fieldFromInstruction32(Insn, 7, 1); 4093226633Sdim if (fieldFromInstruction32(Insn, 6, 1)) 4094226633Sdim inc = 2; 4095226633Sdim break; 4096226633Sdim } 4097226633Sdim 4098226633Sdim if (Rm != 0xF) { // Writeback 4099226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4100226633Sdim return MCDisassembler::Fail; 4101226633Sdim } 4102226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4103226633Sdim return MCDisassembler::Fail; 4104226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4105226633Sdim if (Rm != 0xF) { 4106226633Sdim if (Rm != 0xD) { 4107226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4108226633Sdim return MCDisassembler::Fail; 4109226633Sdim } else 4110226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4111226633Sdim } 4112226633Sdim 4113226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4114226633Sdim return MCDisassembler::Fail; 4115226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4116226633Sdim return MCDisassembler::Fail; 4117226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4118226633Sdim return MCDisassembler::Fail; 4119226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4120226633Sdim return MCDisassembler::Fail; 4121226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4122226633Sdim 4123226633Sdim return S; 4124206124Srdivacky} 4125206124Srdivacky 4126234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 4127226633Sdim uint64_t Address, const void *Decoder) { 4128226633Sdim DecodeStatus S = MCDisassembler::Success; 4129226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 4130226633Sdim unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4); 4131226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 4132226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 4133226633Sdim Rm |= fieldFromInstruction32(Insn, 5, 1) << 4; 4134226633Sdim 4135226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 4136226633Sdim S = MCDisassembler::SoftFail; 4137226633Sdim 4138226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 4139226633Sdim return MCDisassembler::Fail; 4140226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 4141226633Sdim return MCDisassembler::Fail; 4142226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 4143226633Sdim return MCDisassembler::Fail; 4144226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 4145226633Sdim return MCDisassembler::Fail; 4146226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4147226633Sdim return MCDisassembler::Fail; 4148226633Sdim 4149226633Sdim return S; 4150207618Srdivacky} 4151207618Srdivacky 4152234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 4153226633Sdim uint64_t Address, const void *Decoder) { 4154226633Sdim DecodeStatus S = MCDisassembler::Success; 4155226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 4156226633Sdim unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4); 4157226633Sdim unsigned Rm = fieldFromInstruction32(Insn, 0, 4); 4158226633Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 4159226633Sdim Rm |= fieldFromInstruction32(Insn, 5, 1) << 4; 4160226633Sdim 4161226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 4162226633Sdim S = MCDisassembler::SoftFail; 4163226633Sdim 4164226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 4165226633Sdim return MCDisassembler::Fail; 4166226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 4167226633Sdim return MCDisassembler::Fail; 4168226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 4169226633Sdim return MCDisassembler::Fail; 4170226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 4171226633Sdim return MCDisassembler::Fail; 4172226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4173226633Sdim return MCDisassembler::Fail; 4174226633Sdim 4175226633Sdim return S; 4176207618Srdivacky} 4177226633Sdim 4178234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, 4179226633Sdim uint64_t Address, const void *Decoder) { 4180226633Sdim DecodeStatus S = MCDisassembler::Success; 4181226633Sdim unsigned pred = fieldFromInstruction16(Insn, 4, 4); 4182226633Sdim // The InstPrinter needs to have the low bit of the predicate in 4183226633Sdim // the mask operand to be able to print it properly. 4184226633Sdim unsigned mask = fieldFromInstruction16(Insn, 0, 5); 4185226633Sdim 4186226633Sdim if (pred == 0xF) { 4187226633Sdim pred = 0xE; 4188226633Sdim S = MCDisassembler::SoftFail; 4189226633Sdim } 4190226633Sdim 4191226633Sdim if ((mask & 0xF) == 0) { 4192226633Sdim // Preserve the high bit of the mask, which is the low bit of 4193226633Sdim // the predicate. 4194226633Sdim mask &= 0x10; 4195226633Sdim mask |= 0x8; 4196226633Sdim S = MCDisassembler::SoftFail; 4197226633Sdim } 4198226633Sdim 4199226633Sdim Inst.addOperand(MCOperand::CreateImm(pred)); 4200226633Sdim Inst.addOperand(MCOperand::CreateImm(mask)); 4201226633Sdim return S; 4202226633Sdim} 4203226633Sdim 4204226633Sdimstatic DecodeStatus 4205234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn, 4206226633Sdim uint64_t Address, const void *Decoder) { 4207226633Sdim DecodeStatus S = MCDisassembler::Success; 4208226633Sdim 4209226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 4210226633Sdim unsigned Rt2 = fieldFromInstruction32(Insn, 8, 4); 4211226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 4212226633Sdim unsigned addr = fieldFromInstruction32(Insn, 0, 8); 4213226633Sdim unsigned W = fieldFromInstruction32(Insn, 21, 1); 4214226633Sdim unsigned U = fieldFromInstruction32(Insn, 23, 1); 4215226633Sdim unsigned P = fieldFromInstruction32(Insn, 24, 1); 4216226633Sdim bool writeback = (W == 1) | (P == 0); 4217226633Sdim 4218226633Sdim addr |= (U << 8) | (Rn << 9); 4219226633Sdim 4220226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 4221226633Sdim Check(S, MCDisassembler::SoftFail); 4222226633Sdim if (Rt == Rt2) 4223226633Sdim Check(S, MCDisassembler::SoftFail); 4224226633Sdim 4225226633Sdim // Rt 4226226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4227226633Sdim return MCDisassembler::Fail; 4228226633Sdim // Rt2 4229226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 4230226633Sdim return MCDisassembler::Fail; 4231226633Sdim // Writeback operand 4232226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4233226633Sdim return MCDisassembler::Fail; 4234226633Sdim // addr 4235226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 4236226633Sdim return MCDisassembler::Fail; 4237226633Sdim 4238226633Sdim return S; 4239226633Sdim} 4240226633Sdim 4241226633Sdimstatic DecodeStatus 4242234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn, 4243226633Sdim uint64_t Address, const void *Decoder) { 4244226633Sdim DecodeStatus S = MCDisassembler::Success; 4245226633Sdim 4246226633Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 4247226633Sdim unsigned Rt2 = fieldFromInstruction32(Insn, 8, 4); 4248226633Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 4249226633Sdim unsigned addr = fieldFromInstruction32(Insn, 0, 8); 4250226633Sdim unsigned W = fieldFromInstruction32(Insn, 21, 1); 4251226633Sdim unsigned U = fieldFromInstruction32(Insn, 23, 1); 4252226633Sdim unsigned P = fieldFromInstruction32(Insn, 24, 1); 4253226633Sdim bool writeback = (W == 1) | (P == 0); 4254226633Sdim 4255226633Sdim addr |= (U << 8) | (Rn << 9); 4256226633Sdim 4257226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 4258226633Sdim Check(S, MCDisassembler::SoftFail); 4259226633Sdim 4260226633Sdim // Writeback operand 4261226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4262226633Sdim return MCDisassembler::Fail; 4263226633Sdim // Rt 4264226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4265226633Sdim return MCDisassembler::Fail; 4266226633Sdim // Rt2 4267226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 4268226633Sdim return MCDisassembler::Fail; 4269226633Sdim // addr 4270226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 4271226633Sdim return MCDisassembler::Fail; 4272226633Sdim 4273226633Sdim return S; 4274226633Sdim} 4275226633Sdim 4276234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, 4277226633Sdim uint64_t Address, const void *Decoder) { 4278226633Sdim unsigned sign1 = fieldFromInstruction32(Insn, 21, 1); 4279226633Sdim unsigned sign2 = fieldFromInstruction32(Insn, 23, 1); 4280226633Sdim if (sign1 != sign2) return MCDisassembler::Fail; 4281226633Sdim 4282226633Sdim unsigned Val = fieldFromInstruction32(Insn, 0, 8); 4283226633Sdim Val |= fieldFromInstruction32(Insn, 12, 3) << 8; 4284226633Sdim Val |= fieldFromInstruction32(Insn, 26, 1) << 11; 4285226633Sdim Val |= sign1 << 12; 4286226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val))); 4287226633Sdim 4288226633Sdim return MCDisassembler::Success; 4289226633Sdim} 4290226633Sdim 4291234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val, 4292226633Sdim uint64_t Address, 4293226633Sdim const void *Decoder) { 4294226633Sdim DecodeStatus S = MCDisassembler::Success; 4295226633Sdim 4296226633Sdim // Shift of "asr #32" is not allowed in Thumb2 mode. 4297226633Sdim if (Val == 0x20) S = MCDisassembler::SoftFail; 4298226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 4299226633Sdim return S; 4300226633Sdim} 4301226633Sdim 4302234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 4303234353Sdim uint64_t Address, const void *Decoder) { 4304234353Sdim unsigned Rt = fieldFromInstruction32(Insn, 12, 4); 4305234353Sdim unsigned Rt2 = fieldFromInstruction32(Insn, 0, 4); 4306234353Sdim unsigned Rn = fieldFromInstruction32(Insn, 16, 4); 4307234353Sdim unsigned pred = fieldFromInstruction32(Insn, 28, 4); 4308234353Sdim 4309234353Sdim if (pred == 0xF) 4310234353Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 4311234353Sdim 4312234353Sdim DecodeStatus S = MCDisassembler::Success; 4313234982Sdim 4314234982Sdim if (Rt == Rn || Rn == Rt2) 4315234982Sdim S = MCDisassembler::SoftFail; 4316234982Sdim 4317234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4318234353Sdim return MCDisassembler::Fail; 4319234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 4320234353Sdim return MCDisassembler::Fail; 4321234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4322234353Sdim return MCDisassembler::Fail; 4323234353Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4324234353Sdim return MCDisassembler::Fail; 4325234353Sdim 4326234353Sdim return S; 4327234353Sdim} 4328234353Sdim 4329234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 4330234353Sdim uint64_t Address, const void *Decoder) { 4331234353Sdim unsigned Vd = (fieldFromInstruction32(Insn, 12, 4) << 0); 4332234353Sdim Vd |= (fieldFromInstruction32(Insn, 22, 1) << 4); 4333234353Sdim unsigned Vm = (fieldFromInstruction32(Insn, 0, 4) << 0); 4334234353Sdim Vm |= (fieldFromInstruction32(Insn, 5, 1) << 4); 4335234353Sdim unsigned imm = fieldFromInstruction32(Insn, 16, 6); 4336234353Sdim unsigned cmode = fieldFromInstruction32(Insn, 8, 4); 4337234353Sdim 4338234353Sdim DecodeStatus S = MCDisassembler::Success; 4339234353Sdim 4340234353Sdim // VMOVv2f32 is ambiguous with these decodings. 4341234353Sdim if (!(imm & 0x38) && cmode == 0xF) { 4342234353Sdim Inst.setOpcode(ARM::VMOVv2f32); 4343234353Sdim return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); 4344234353Sdim } 4345234353Sdim 4346234353Sdim if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail); 4347234353Sdim 4348234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 4349234353Sdim return MCDisassembler::Fail; 4350234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder))) 4351234353Sdim return MCDisassembler::Fail; 4352234353Sdim Inst.addOperand(MCOperand::CreateImm(64 - imm)); 4353234353Sdim 4354234353Sdim return S; 4355234353Sdim} 4356234353Sdim 4357234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 4358234353Sdim uint64_t Address, const void *Decoder) { 4359234353Sdim unsigned Vd = (fieldFromInstruction32(Insn, 12, 4) << 0); 4360234353Sdim Vd |= (fieldFromInstruction32(Insn, 22, 1) << 4); 4361234353Sdim unsigned Vm = (fieldFromInstruction32(Insn, 0, 4) << 0); 4362234353Sdim Vm |= (fieldFromInstruction32(Insn, 5, 1) << 4); 4363234353Sdim unsigned imm = fieldFromInstruction32(Insn, 16, 6); 4364234353Sdim unsigned cmode = fieldFromInstruction32(Insn, 8, 4); 4365234353Sdim 4366234353Sdim DecodeStatus S = MCDisassembler::Success; 4367234353Sdim 4368234353Sdim // VMOVv4f32 is ambiguous with these decodings. 4369234353Sdim if (!(imm & 0x38) && cmode == 0xF) { 4370234353Sdim Inst.setOpcode(ARM::VMOVv4f32); 4371234353Sdim return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); 4372234353Sdim } 4373234353Sdim 4374234353Sdim if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail); 4375234353Sdim 4376234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder))) 4377234353Sdim return MCDisassembler::Fail; 4378234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder))) 4379234353Sdim return MCDisassembler::Fail; 4380234353Sdim Inst.addOperand(MCOperand::CreateImm(64 - imm)); 4381234353Sdim 4382234353Sdim return S; 4383234353Sdim} 4384234353Sdim 4385234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 4386234353Sdim uint64_t Address, const void *Decoder) { 4387234353Sdim DecodeStatus S = MCDisassembler::Success; 4388234353Sdim 4389234353Sdim unsigned Rn = fieldFromInstruction32(Val, 16, 4); 4390234353Sdim unsigned Rt = fieldFromInstruction32(Val, 12, 4); 4391234353Sdim unsigned Rm = fieldFromInstruction32(Val, 0, 4); 4392234353Sdim Rm |= (fieldFromInstruction32(Val, 23, 1) << 4); 4393234353Sdim unsigned Cond = fieldFromInstruction32(Val, 28, 4); 4394234353Sdim 4395234353Sdim if (fieldFromInstruction32(Val, 8, 4) != 0 || Rn == Rt) 4396234353Sdim S = MCDisassembler::SoftFail; 4397234353Sdim 4398234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4399234353Sdim return MCDisassembler::Fail; 4400234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4401234353Sdim return MCDisassembler::Fail; 4402234353Sdim if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder))) 4403234353Sdim return MCDisassembler::Fail; 4404234353Sdim if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder))) 4405234353Sdim return MCDisassembler::Fail; 4406234353Sdim if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder))) 4407234353Sdim return MCDisassembler::Fail; 4408234353Sdim 4409234353Sdim return S; 4410234353Sdim} 4411234353Sdim 4412234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, 4413234982Sdim uint64_t Address, const void *Decoder) { 4414234982Sdim 4415234982Sdim DecodeStatus S = MCDisassembler::Success; 4416234982Sdim 4417234982Sdim unsigned CRm = fieldFromInstruction32(Val, 0, 4); 4418234982Sdim unsigned opc1 = fieldFromInstruction32(Val, 4, 4); 4419234982Sdim unsigned cop = fieldFromInstruction32(Val, 8, 4); 4420234982Sdim unsigned Rt = fieldFromInstruction32(Val, 12, 4); 4421234982Sdim unsigned Rt2 = fieldFromInstruction32(Val, 16, 4); 4422234982Sdim 4423234982Sdim if ((cop & ~0x1) == 0xa) 4424234982Sdim return MCDisassembler::Fail; 4425234982Sdim 4426234982Sdim if (Rt == Rt2) 4427234982Sdim S = MCDisassembler::SoftFail; 4428234982Sdim 4429234982Sdim Inst.addOperand(MCOperand::CreateImm(cop)); 4430234982Sdim Inst.addOperand(MCOperand::CreateImm(opc1)); 4431234982Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4432234982Sdim return MCDisassembler::Fail; 4433234982Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 4434234982Sdim return MCDisassembler::Fail; 4435234982Sdim Inst.addOperand(MCOperand::CreateImm(CRm)); 4436234982Sdim 4437234982Sdim return S; 4438234982Sdim} 4439234982Sdim 4440