1234353Sdim//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===// 2206124Srdivacky// 3206124Srdivacky// The LLVM Compiler Infrastructure 4206124Srdivacky// 5206124Srdivacky// This file is distributed under the University of Illinois Open Source 6206124Srdivacky// License. See LICENSE.TXT for details. 7206124Srdivacky// 8206124Srdivacky//===----------------------------------------------------------------------===// 9206124Srdivacky 10206124Srdivacky#define DEBUG_TYPE "arm-disassembler" 11206124Srdivacky 12249423Sdim#include "llvm/MC/MCDisassembler.h" 13226633Sdim#include "MCTargetDesc/ARMAddressingModes.h" 14249423Sdim#include "MCTargetDesc/ARMBaseInfo.h" 15226633Sdim#include "MCTargetDesc/ARMMCExpr.h" 16249423Sdim#include "llvm/MC/MCContext.h" 17249423Sdim#include "llvm/MC/MCExpr.h" 18249423Sdim#include "llvm/MC/MCFixedLenDisassembler.h" 19206124Srdivacky#include "llvm/MC/MCInst.h" 20234353Sdim#include "llvm/MC/MCInstrDesc.h" 21234353Sdim#include "llvm/MC/MCSubtargetInfo.h" 22206124Srdivacky#include "llvm/Support/Debug.h" 23206124Srdivacky#include "llvm/Support/ErrorHandling.h" 24239462Sdim#include "llvm/Support/LEB128.h" 25249423Sdim#include "llvm/Support/MemoryObject.h" 26226633Sdim#include "llvm/Support/TargetRegistry.h" 27206124Srdivacky#include "llvm/Support/raw_ostream.h" 28239462Sdim#include <vector> 29206124Srdivacky 30226633Sdimusing namespace llvm; 31212904Sdim 32226633Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus; 33206124Srdivacky 34226633Sdimnamespace { 35239462Sdim // Handles the condition code status of instructions in IT blocks 36239462Sdim class ITStatus 37239462Sdim { 38239462Sdim public: 39239462Sdim // Returns the condition code for instruction in IT block 40239462Sdim unsigned getITCC() { 41239462Sdim unsigned CC = ARMCC::AL; 42239462Sdim if (instrInITBlock()) 43239462Sdim CC = ITStates.back(); 44239462Sdim return CC; 45239462Sdim } 46239462Sdim 47239462Sdim // Advances the IT block state to the next T or E 48239462Sdim void advanceITState() { 49239462Sdim ITStates.pop_back(); 50239462Sdim } 51239462Sdim 52239462Sdim // Returns true if the current instruction is in an IT block 53239462Sdim bool instrInITBlock() { 54239462Sdim return !ITStates.empty(); 55239462Sdim } 56239462Sdim 57239462Sdim // Returns true if current instruction is the last instruction in an IT block 58239462Sdim bool instrLastInITBlock() { 59239462Sdim return ITStates.size() == 1; 60239462Sdim } 61239462Sdim 62239462Sdim // Called when decoding an IT instruction. Sets the IT state for the following 63239462Sdim // instructions that for the IT block. Firstcond and Mask correspond to the 64239462Sdim // fields in the IT instruction encoding. 65239462Sdim void setITState(char Firstcond, char Mask) { 66239462Sdim // (3 - the number of trailing zeros) is the number of then / else. 67239462Sdim unsigned CondBit0 = Firstcond & 1; 68263508Sdim unsigned NumTZ = countTrailingZeros<uint8_t>(Mask); 69239462Sdim unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf); 70239462Sdim assert(NumTZ <= 3 && "Invalid IT mask!"); 71239462Sdim // push condition codes onto the stack the correct order for the pops 72239462Sdim for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) { 73239462Sdim bool T = ((Mask >> Pos) & 1) == CondBit0; 74239462Sdim if (T) 75239462Sdim ITStates.push_back(CCBits); 76239462Sdim else 77239462Sdim ITStates.push_back(CCBits ^ 1); 78239462Sdim } 79239462Sdim ITStates.push_back(CCBits); 80239462Sdim } 81239462Sdim 82239462Sdim private: 83239462Sdim std::vector<unsigned char> ITStates; 84239462Sdim }; 85239462Sdim} 86239462Sdim 87239462Sdimnamespace { 88226633Sdim/// ARMDisassembler - ARM disassembler for all ARM platforms. 89226633Sdimclass ARMDisassembler : public MCDisassembler { 90226633Sdimpublic: 91226633Sdim /// Constructor - Initializes the disassembler. 92226633Sdim /// 93226633Sdim ARMDisassembler(const MCSubtargetInfo &STI) : 94226633Sdim MCDisassembler(STI) { 95226633Sdim } 96226633Sdim 97226633Sdim ~ARMDisassembler() { 98226633Sdim } 99226633Sdim 100226633Sdim /// getInstruction - See MCDisassembler. 101226633Sdim DecodeStatus getInstruction(MCInst &instr, 102226633Sdim uint64_t &size, 103226633Sdim const MemoryObject ®ion, 104226633Sdim uint64_t address, 105226633Sdim raw_ostream &vStream, 106226633Sdim raw_ostream &cStream) const; 107226633Sdim}; 108226633Sdim 109226633Sdim/// ThumbDisassembler - Thumb disassembler for all Thumb platforms. 110226633Sdimclass ThumbDisassembler : public MCDisassembler { 111226633Sdimpublic: 112226633Sdim /// Constructor - Initializes the disassembler. 113226633Sdim /// 114226633Sdim ThumbDisassembler(const MCSubtargetInfo &STI) : 115226633Sdim MCDisassembler(STI) { 116226633Sdim } 117226633Sdim 118226633Sdim ~ThumbDisassembler() { 119226633Sdim } 120226633Sdim 121226633Sdim /// getInstruction - See MCDisassembler. 122226633Sdim DecodeStatus getInstruction(MCInst &instr, 123226633Sdim uint64_t &size, 124226633Sdim const MemoryObject ®ion, 125226633Sdim uint64_t address, 126226633Sdim raw_ostream &vStream, 127226633Sdim raw_ostream &cStream) const; 128226633Sdim 129226633Sdimprivate: 130239462Sdim mutable ITStatus ITBlock; 131226633Sdim DecodeStatus AddThumbPredicate(MCInst&) const; 132226633Sdim void UpdateThumbVFPPredicate(MCInst&) const; 133226633Sdim}; 134226633Sdim} 135226633Sdim 136226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) { 137226633Sdim switch (In) { 138226633Sdim case MCDisassembler::Success: 139226633Sdim // Out stays the same. 140226633Sdim return true; 141226633Sdim case MCDisassembler::SoftFail: 142226633Sdim Out = In; 143226633Sdim return true; 144226633Sdim case MCDisassembler::Fail: 145226633Sdim Out = In; 146226633Sdim return false; 147226633Sdim } 148234353Sdim llvm_unreachable("Invalid DecodeStatus!"); 149226633Sdim} 150226633Sdim 151226633Sdim 152226633Sdim// Forward declare these because the autogenerated code will reference them. 153226633Sdim// Definitions are further down. 154234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 155226633Sdim uint64_t Address, const void *Decoder); 156234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, 157226633Sdim unsigned RegNo, uint64_t Address, 158226633Sdim const void *Decoder); 159263508Sdimstatic DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst, 160263508Sdim unsigned RegNo, uint64_t Address, 161263508Sdim const void *Decoder); 162234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 163226633Sdim uint64_t Address, const void *Decoder); 164234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 165226633Sdim uint64_t Address, const void *Decoder); 166234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 167226633Sdim uint64_t Address, const void *Decoder); 168263508Sdimstatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo, 169263508Sdim uint64_t Address, const void *Decoder); 170234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 171226633Sdim uint64_t Address, const void *Decoder); 172234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 173226633Sdim uint64_t Address, const void *Decoder); 174234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 175226633Sdim uint64_t Address, const void *Decoder); 176234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, 177226633Sdim unsigned RegNo, 178226633Sdim uint64_t Address, 179226633Sdim const void *Decoder); 180234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 181226633Sdim uint64_t Address, const void *Decoder); 182234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 183234353Sdim uint64_t Address, const void *Decoder); 184234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 185234353Sdim unsigned RegNo, uint64_t Address, 186234353Sdim const void *Decoder); 187226633Sdim 188234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 189226633Sdim uint64_t Address, const void *Decoder); 190234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 191226633Sdim uint64_t Address, const void *Decoder); 192234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, 193226633Sdim uint64_t Address, const void *Decoder); 194234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 195226633Sdim uint64_t Address, const void *Decoder); 196234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 197226633Sdim uint64_t Address, const void *Decoder); 198234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 199226633Sdim uint64_t Address, const void *Decoder); 200226633Sdim 201234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn, 202226633Sdim uint64_t Address, const void *Decoder); 203234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 204226633Sdim uint64_t Address, const void *Decoder); 205234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst, 206226633Sdim unsigned Insn, 207226633Sdim uint64_t Address, 208226633Sdim const void *Decoder); 209234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn, 210226633Sdim uint64_t Address, const void *Decoder); 211234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn, 212226633Sdim uint64_t Address, const void *Decoder); 213234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn, 214226633Sdim uint64_t Address, const void *Decoder); 215234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn, 216226633Sdim uint64_t Address, const void *Decoder); 217226633Sdim 218234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst, 219226633Sdim unsigned Insn, 220226633Sdim uint64_t Adddress, 221226633Sdim const void *Decoder); 222234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 223226633Sdim uint64_t Address, const void *Decoder); 224234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 225226633Sdim uint64_t Address, const void *Decoder); 226234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 227226633Sdim uint64_t Address, const void *Decoder); 228234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 229226633Sdim uint64_t Address, const void *Decoder); 230234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 231226633Sdim uint64_t Address, const void *Decoder); 232234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 233226633Sdim uint64_t Address, const void *Decoder); 234234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 235226633Sdim uint64_t Address, const void *Decoder); 236234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 237226633Sdim uint64_t Address, const void *Decoder); 238234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn, 239226633Sdim uint64_t Address, const void *Decoder); 240234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn, 241226633Sdim uint64_t Address, const void *Decoder); 242234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 243226633Sdim uint64_t Address, const void *Decoder); 244263508Sdimstatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val, 245263508Sdim uint64_t Address, const void *Decoder); 246263508Sdimstatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val, 247263508Sdim uint64_t Address, const void *Decoder); 248263508Sdimstatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val, 249263508Sdim uint64_t Address, const void *Decoder); 250263508Sdimstatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val, 251263508Sdim uint64_t Address, const void *Decoder); 252234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val, 253226633Sdim uint64_t Address, const void *Decoder); 254234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val, 255226633Sdim uint64_t Address, const void *Decoder); 256234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val, 257226633Sdim uint64_t Address, const void *Decoder); 258234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val, 259226633Sdim uint64_t Address, const void *Decoder); 260234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val, 261226633Sdim uint64_t Address, const void *Decoder); 262234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val, 263226633Sdim uint64_t Address, const void *Decoder); 264234353Sdimstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val, 265226633Sdim uint64_t Address, const void *Decoder); 266234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val, 267226633Sdim uint64_t Address, const void *Decoder); 268234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 269226633Sdim uint64_t Address, const void *Decoder); 270234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 271226633Sdim uint64_t Address, const void *Decoder); 272234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 273226633Sdim uint64_t Address, const void *Decoder); 274234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 275226633Sdim uint64_t Address, const void *Decoder); 276234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 277226633Sdim uint64_t Address, const void *Decoder); 278234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 279226633Sdim uint64_t Address, const void *Decoder); 280234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn, 281226633Sdim uint64_t Address, const void *Decoder); 282234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn, 283226633Sdim uint64_t Address, const void *Decoder); 284263508Sdimstatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn, 285263508Sdim uint64_t Address, const void *Decoder); 286234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, 287226633Sdim uint64_t Address, const void *Decoder); 288234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 289226633Sdim uint64_t Address, const void *Decoder); 290234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 291226633Sdim uint64_t Address, const void *Decoder); 292234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 293226633Sdim uint64_t Address, const void *Decoder); 294234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 295226633Sdim uint64_t Address, const void *Decoder); 296234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 297226633Sdim uint64_t Address, const void *Decoder); 298234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 299226633Sdim uint64_t Address, const void *Decoder); 300234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 301226633Sdim uint64_t Address, const void *Decoder); 302234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 303226633Sdim uint64_t Address, const void *Decoder); 304234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 305226633Sdim uint64_t Address, const void *Decoder); 306234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 307226633Sdim uint64_t Address, const void *Decoder); 308234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 309226633Sdim uint64_t Address, const void *Decoder); 310234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 311226633Sdim uint64_t Address, const void *Decoder); 312234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 313226633Sdim uint64_t Address, const void *Decoder); 314234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 315226633Sdim uint64_t Address, const void *Decoder); 316234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 317226633Sdim uint64_t Address, const void *Decoder); 318234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 319226633Sdim uint64_t Address, const void *Decoder); 320234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 321234353Sdim uint64_t Address, const void *Decoder); 322234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 323234353Sdim uint64_t Address, const void *Decoder); 324234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 325234353Sdim uint64_t Address, const void *Decoder); 326226633Sdim 327234353Sdim 328234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 329226633Sdim uint64_t Address, const void *Decoder); 330234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 331226633Sdim uint64_t Address, const void *Decoder); 332234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 333226633Sdim uint64_t Address, const void *Decoder); 334234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 335226633Sdim uint64_t Address, const void *Decoder); 336234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 337226633Sdim uint64_t Address, const void *Decoder); 338234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 339226633Sdim uint64_t Address, const void *Decoder); 340234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 341226633Sdim uint64_t Address, const void *Decoder); 342234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 343226633Sdim uint64_t Address, const void *Decoder); 344234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 345226633Sdim uint64_t Address, const void *Decoder); 346234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val, 347226633Sdim uint64_t Address, const void *Decoder); 348263508Sdimstatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn, 349263508Sdim uint64_t Address, const void* Decoder); 350263508Sdimstatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn, 351263508Sdim uint64_t Address, const void* Decoder); 352263508Sdimstatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, 353263508Sdim uint64_t Address, const void* Decoder); 354263508Sdimstatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn, 355263508Sdim uint64_t Address, const void* Decoder); 356234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 357226633Sdim uint64_t Address, const void *Decoder); 358234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 359226633Sdim uint64_t Address, const void *Decoder); 360234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 361226633Sdim uint64_t Address, const void *Decoder); 362234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 363226633Sdim uint64_t Address, const void *Decoder); 364234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 365226633Sdim uint64_t Address, const void *Decoder); 366234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val, 367226633Sdim uint64_t Address, const void *Decoder); 368234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 369226633Sdim uint64_t Address, const void *Decoder); 370234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 371226633Sdim uint64_t Address, const void *Decoder); 372263508Sdimstatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn, 373263508Sdim uint64_t Address, const void *Decoder); 374234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn, 375226633Sdim uint64_t Address, const void *Decoder); 376234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 377226633Sdim uint64_t Address, const void *Decoder); 378234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val, 379226633Sdim uint64_t Address, const void *Decoder); 380234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val, 381226633Sdim uint64_t Address, const void *Decoder); 382234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 383226633Sdim uint64_t Address, const void *Decoder); 384234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val, 385226633Sdim uint64_t Address, const void *Decoder); 386234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 387226633Sdim uint64_t Address, const void *Decoder); 388234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, 389226633Sdim uint64_t Address, const void *Decoder); 390234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn, 391226633Sdim uint64_t Address, const void *Decoder); 392234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn, 393226633Sdim uint64_t Address, const void *Decoder); 394234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, 395226633Sdim uint64_t Address, const void *Decoder); 396234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val, 397226633Sdim uint64_t Address, const void *Decoder); 398234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, 399226633Sdim uint64_t Address, const void *Decoder); 400226633Sdim 401234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 402234353Sdim uint64_t Address, const void *Decoder); 403234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, 404234982Sdim uint64_t Address, const void *Decoder); 405226633Sdim#include "ARMGenDisassemblerTables.inc" 406206124Srdivacky 407226633Sdimstatic MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) { 408226633Sdim return new ARMDisassembler(STI); 409226633Sdim} 410207618Srdivacky 411226633Sdimstatic MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) { 412226633Sdim return new ThumbDisassembler(STI); 413226633Sdim} 414226633Sdim 415226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 416226633Sdim const MemoryObject &Region, 417226633Sdim uint64_t Address, 418226633Sdim raw_ostream &os, 419226633Sdim raw_ostream &cs) const { 420226633Sdim CommentStream = &cs; 421226633Sdim 422226633Sdim uint8_t bytes[4]; 423226633Sdim 424226633Sdim assert(!(STI.getFeatureBits() & ARM::ModeThumb) && 425226633Sdim "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!"); 426226633Sdim 427226633Sdim // We want to read exactly 4 bytes of data. 428263508Sdim if (Region.readBytes(Address, 4, bytes) == -1) { 429226633Sdim Size = 0; 430226633Sdim return MCDisassembler::Fail; 431206124Srdivacky } 432226633Sdim 433226633Sdim // Encoded as a small-endian 32-bit word in the stream. 434226633Sdim uint32_t insn = (bytes[3] << 24) | 435226633Sdim (bytes[2] << 16) | 436226633Sdim (bytes[1] << 8) | 437226633Sdim (bytes[0] << 0); 438226633Sdim 439226633Sdim // Calling the auto-generated decoder function. 440239462Sdim DecodeStatus result = decodeInstruction(DecoderTableARM32, MI, insn, 441239462Sdim Address, this, STI); 442226633Sdim if (result != MCDisassembler::Fail) { 443226633Sdim Size = 4; 444226633Sdim return result; 445226633Sdim } 446226633Sdim 447226633Sdim // VFP and NEON instructions, similarly, are shared between ARM 448226633Sdim // and Thumb modes. 449226633Sdim MI.clear(); 450239462Sdim result = decodeInstruction(DecoderTableVFP32, MI, insn, Address, this, STI); 451226633Sdim if (result != MCDisassembler::Fail) { 452226633Sdim Size = 4; 453226633Sdim return result; 454226633Sdim } 455226633Sdim 456226633Sdim MI.clear(); 457263508Sdim result = decodeInstruction(DecoderTableVFPV832, MI, insn, Address, this, STI); 458263508Sdim if (result != MCDisassembler::Fail) { 459263508Sdim Size = 4; 460263508Sdim return result; 461263508Sdim } 462263508Sdim 463263508Sdim MI.clear(); 464239462Sdim result = decodeInstruction(DecoderTableNEONData32, MI, insn, Address, 465239462Sdim this, STI); 466226633Sdim if (result != MCDisassembler::Fail) { 467226633Sdim Size = 4; 468226633Sdim // Add a fake predicate operand, because we share these instruction 469226633Sdim // definitions with Thumb2 where these instructions are predicable. 470226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 471226633Sdim return MCDisassembler::Fail; 472226633Sdim return result; 473226633Sdim } 474226633Sdim 475226633Sdim MI.clear(); 476239462Sdim result = decodeInstruction(DecoderTableNEONLoadStore32, MI, insn, Address, 477239462Sdim this, STI); 478226633Sdim if (result != MCDisassembler::Fail) { 479226633Sdim Size = 4; 480226633Sdim // Add a fake predicate operand, because we share these instruction 481226633Sdim // definitions with Thumb2 where these instructions are predicable. 482226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 483226633Sdim return MCDisassembler::Fail; 484226633Sdim return result; 485226633Sdim } 486226633Sdim 487226633Sdim MI.clear(); 488239462Sdim result = decodeInstruction(DecoderTableNEONDup32, MI, insn, Address, 489239462Sdim this, STI); 490226633Sdim if (result != MCDisassembler::Fail) { 491226633Sdim Size = 4; 492226633Sdim // Add a fake predicate operand, because we share these instruction 493226633Sdim // definitions with Thumb2 where these instructions are predicable. 494226633Sdim if (!DecodePredicateOperand(MI, 0xE, Address, this)) 495226633Sdim return MCDisassembler::Fail; 496226633Sdim return result; 497226633Sdim } 498226633Sdim 499226633Sdim MI.clear(); 500263508Sdim result = decodeInstruction(DecoderTablev8NEON32, MI, insn, Address, 501263508Sdim this, STI); 502263508Sdim if (result != MCDisassembler::Fail) { 503263508Sdim Size = 4; 504263508Sdim return result; 505263508Sdim } 506226633Sdim 507263508Sdim MI.clear(); 508263508Sdim result = decodeInstruction(DecoderTablev8Crypto32, MI, insn, Address, 509263508Sdim this, STI); 510263508Sdim if (result != MCDisassembler::Fail) { 511263508Sdim Size = 4; 512263508Sdim return result; 513263508Sdim } 514263508Sdim 515263508Sdim MI.clear(); 516226633Sdim Size = 0; 517226633Sdim return MCDisassembler::Fail; 518206124Srdivacky} 519206124Srdivacky 520226633Sdimnamespace llvm { 521234353Sdimextern const MCInstrDesc ARMInsts[]; 522226633Sdim} 523206124Srdivacky 524226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 525226633Sdim/// immediate Value in the MCInst. The immediate Value has had any PC 526226633Sdim/// adjustment made by the caller. If the instruction is a branch instruction 527226633Sdim/// then isBranch is true, else false. If the getOpInfo() function was set as 528226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called 529226633Sdim/// to get any symbolic information at the Address for this instruction. If 530226633Sdim/// that returns non-zero then the symbolic information it returns is used to 531226633Sdim/// create an MCExpr and that is added as an operand to the MCInst. If 532226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for 533226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else 534226633Sdim/// an MCExpr with Value is created. This function returns true if it adds an 535226633Sdim/// operand to the MCInst and false otherwise. 536226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value, 537226633Sdim bool isBranch, uint64_t InstSize, 538226633Sdim MCInst &MI, const void *Decoder) { 539226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 540263508Sdim // FIXME: Does it make sense for value to be negative? 541263508Sdim return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch, 542263508Sdim /* Offset */ 0, InstSize); 543226633Sdim} 544226633Sdim 545226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being 546226633Sdim/// referenced by a load instruction with the base register that is the Pc. 547226633Sdim/// These can often be values in a literal pool near the Address of the 548226633Sdim/// instruction. The Address of the instruction and its immediate Value are 549226633Sdim/// used as a possible literal pool entry. The SymbolLookUp call back will 550239462Sdim/// return the name of a symbol referenced by the literal pool's entry if 551226633Sdim/// the referenced address is that of a symbol. Or it will return a pointer to 552226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry 553226633Sdim/// is an address into a section with 'C' string literals. 554226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value, 555234353Sdim const void *Decoder) { 556226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 557263508Sdim Dis->tryAddingPcLoadReferenceComment(Value, Address); 558226633Sdim} 559206124Srdivacky 560226633Sdim// Thumb1 instructions don't have explicit S bits. Rather, they 561226633Sdim// implicitly set CPSR. Since it's not represented in the encoding, the 562226633Sdim// auto-generated decoder won't inject the CPSR operand. We need to fix 563226633Sdim// that as a post-pass. 564226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) { 565226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 566226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 567226633Sdim MCInst::iterator I = MI.begin(); 568226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 569226633Sdim if (I == MI.end()) break; 570226633Sdim if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) { 571226633Sdim if (i > 0 && OpInfo[i-1].isPredicate()) continue; 572226633Sdim MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); 573226633Sdim return; 574226633Sdim } 575226633Sdim } 576206124Srdivacky 577226633Sdim MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); 578226633Sdim} 579206124Srdivacky 580226633Sdim// Most Thumb instructions don't have explicit predicates in the 581226633Sdim// encoding, but rather get their predicates from IT context. We need 582226633Sdim// to fix up the predicate operands using this context information as a 583226633Sdim// post-pass. 584226633SdimMCDisassembler::DecodeStatus 585226633SdimThumbDisassembler::AddThumbPredicate(MCInst &MI) const { 586226633Sdim MCDisassembler::DecodeStatus S = Success; 587206124Srdivacky 588226633Sdim // A few instructions actually have predicates encoded in them. Don't 589226633Sdim // try to overwrite it if we're seeing one of those. 590226633Sdim switch (MI.getOpcode()) { 591226633Sdim case ARM::tBcc: 592226633Sdim case ARM::t2Bcc: 593226633Sdim case ARM::tCBZ: 594226633Sdim case ARM::tCBNZ: 595226633Sdim case ARM::tCPS: 596226633Sdim case ARM::t2CPS3p: 597226633Sdim case ARM::t2CPS2p: 598226633Sdim case ARM::t2CPS1p: 599226633Sdim case ARM::tMOVSr: 600226633Sdim case ARM::tSETEND: 601226633Sdim // Some instructions (mostly conditional branches) are not 602226633Sdim // allowed in IT blocks. 603239462Sdim if (ITBlock.instrInITBlock()) 604226633Sdim S = SoftFail; 605226633Sdim else 606226633Sdim return Success; 607226633Sdim break; 608226633Sdim case ARM::tB: 609226633Sdim case ARM::t2B: 610226633Sdim case ARM::t2TBB: 611226633Sdim case ARM::t2TBH: 612226633Sdim // Some instructions (mostly unconditional branches) can 613226633Sdim // only appears at the end of, or outside of, an IT. 614239462Sdim if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock()) 615226633Sdim S = SoftFail; 616226633Sdim break; 617226633Sdim default: 618226633Sdim break; 619226633Sdim } 620226633Sdim 621226633Sdim // If we're in an IT block, base the predicate on that. Otherwise, 622226633Sdim // assume a predicate of AL. 623226633Sdim unsigned CC; 624239462Sdim CC = ITBlock.getITCC(); 625239462Sdim if (CC == 0xF) 626226633Sdim CC = ARMCC::AL; 627239462Sdim if (ITBlock.instrInITBlock()) 628239462Sdim ITBlock.advanceITState(); 629226633Sdim 630226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 631226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 632226633Sdim MCInst::iterator I = MI.begin(); 633226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 634226633Sdim if (I == MI.end()) break; 635226633Sdim if (OpInfo[i].isPredicate()) { 636226633Sdim I = MI.insert(I, MCOperand::CreateImm(CC)); 637226633Sdim ++I; 638226633Sdim if (CC == ARMCC::AL) 639226633Sdim MI.insert(I, MCOperand::CreateReg(0)); 640226633Sdim else 641226633Sdim MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 642226633Sdim return S; 643226633Sdim } 644226633Sdim } 645226633Sdim 646226633Sdim I = MI.insert(I, MCOperand::CreateImm(CC)); 647226633Sdim ++I; 648226633Sdim if (CC == ARMCC::AL) 649226633Sdim MI.insert(I, MCOperand::CreateReg(0)); 650226633Sdim else 651226633Sdim MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 652226633Sdim 653226633Sdim return S; 654226633Sdim} 655226633Sdim 656226633Sdim// Thumb VFP instructions are a special case. Because we share their 657226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM 658226633Sdim// mode, the auto-generated decoder will give them an (incorrect) 659226633Sdim// predicate operand. We need to rewrite these operands based on the IT 660226633Sdim// context as a post-pass. 661226633Sdimvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const { 662226633Sdim unsigned CC; 663239462Sdim CC = ITBlock.getITCC(); 664239462Sdim if (ITBlock.instrInITBlock()) 665239462Sdim ITBlock.advanceITState(); 666226633Sdim 667226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 668226633Sdim MCInst::iterator I = MI.begin(); 669226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 670226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 671226633Sdim if (OpInfo[i].isPredicate() ) { 672226633Sdim I->setImm(CC); 673226633Sdim ++I; 674226633Sdim if (CC == ARMCC::AL) 675226633Sdim I->setReg(0); 676226633Sdim else 677226633Sdim I->setReg(ARM::CPSR); 678226633Sdim return; 679226633Sdim } 680226633Sdim } 681226633Sdim} 682226633Sdim 683226633SdimDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 684226633Sdim const MemoryObject &Region, 685226633Sdim uint64_t Address, 686226633Sdim raw_ostream &os, 687226633Sdim raw_ostream &cs) const { 688226633Sdim CommentStream = &cs; 689226633Sdim 690226633Sdim uint8_t bytes[4]; 691226633Sdim 692226633Sdim assert((STI.getFeatureBits() & ARM::ModeThumb) && 693226633Sdim "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!"); 694226633Sdim 695226633Sdim // We want to read exactly 2 bytes of data. 696263508Sdim if (Region.readBytes(Address, 2, bytes) == -1) { 697226633Sdim Size = 0; 698226633Sdim return MCDisassembler::Fail; 699226633Sdim } 700226633Sdim 701226633Sdim uint16_t insn16 = (bytes[1] << 8) | bytes[0]; 702239462Sdim DecodeStatus result = decodeInstruction(DecoderTableThumb16, MI, insn16, 703239462Sdim Address, this, STI); 704226633Sdim if (result != MCDisassembler::Fail) { 705226633Sdim Size = 2; 706226633Sdim Check(result, AddThumbPredicate(MI)); 707226633Sdim return result; 708226633Sdim } 709226633Sdim 710226633Sdim MI.clear(); 711239462Sdim result = decodeInstruction(DecoderTableThumbSBit16, MI, insn16, 712239462Sdim Address, this, STI); 713226633Sdim if (result) { 714226633Sdim Size = 2; 715239462Sdim bool InITBlock = ITBlock.instrInITBlock(); 716226633Sdim Check(result, AddThumbPredicate(MI)); 717226633Sdim AddThumb1SBit(MI, InITBlock); 718226633Sdim return result; 719226633Sdim } 720226633Sdim 721226633Sdim MI.clear(); 722239462Sdim result = decodeInstruction(DecoderTableThumb216, MI, insn16, 723239462Sdim Address, this, STI); 724226633Sdim if (result != MCDisassembler::Fail) { 725226633Sdim Size = 2; 726226633Sdim 727226633Sdim // Nested IT blocks are UNPREDICTABLE. Must be checked before we add 728226633Sdim // the Thumb predicate. 729239462Sdim if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock()) 730226633Sdim result = MCDisassembler::SoftFail; 731226633Sdim 732226633Sdim Check(result, AddThumbPredicate(MI)); 733226633Sdim 734226633Sdim // If we find an IT instruction, we need to parse its condition 735226633Sdim // code and mask operands so that we can apply them correctly 736226633Sdim // to the subsequent instructions. 737226633Sdim if (MI.getOpcode() == ARM::t2IT) { 738226633Sdim 739239462Sdim unsigned Firstcond = MI.getOperand(0).getImm(); 740226633Sdim unsigned Mask = MI.getOperand(1).getImm(); 741239462Sdim ITBlock.setITState(Firstcond, Mask); 742226633Sdim } 743226633Sdim 744226633Sdim return result; 745226633Sdim } 746226633Sdim 747226633Sdim // We want to read exactly 4 bytes of data. 748263508Sdim if (Region.readBytes(Address, 4, bytes) == -1) { 749226633Sdim Size = 0; 750226633Sdim return MCDisassembler::Fail; 751226633Sdim } 752226633Sdim 753226633Sdim uint32_t insn32 = (bytes[3] << 8) | 754226633Sdim (bytes[2] << 0) | 755226633Sdim (bytes[1] << 24) | 756226633Sdim (bytes[0] << 16); 757226633Sdim MI.clear(); 758239462Sdim result = decodeInstruction(DecoderTableThumb32, MI, insn32, Address, 759239462Sdim this, STI); 760226633Sdim if (result != MCDisassembler::Fail) { 761226633Sdim Size = 4; 762239462Sdim bool InITBlock = ITBlock.instrInITBlock(); 763226633Sdim Check(result, AddThumbPredicate(MI)); 764226633Sdim AddThumb1SBit(MI, InITBlock); 765226633Sdim return result; 766226633Sdim } 767226633Sdim 768226633Sdim MI.clear(); 769239462Sdim result = decodeInstruction(DecoderTableThumb232, MI, insn32, Address, 770239462Sdim this, STI); 771226633Sdim if (result != MCDisassembler::Fail) { 772226633Sdim Size = 4; 773226633Sdim Check(result, AddThumbPredicate(MI)); 774226633Sdim return result; 775226633Sdim } 776226633Sdim 777263508Sdim if (fieldFromInstruction(insn32, 28, 4) == 0xE) { 778263508Sdim MI.clear(); 779263508Sdim result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI); 780263508Sdim if (result != MCDisassembler::Fail) { 781263508Sdim Size = 4; 782263508Sdim UpdateThumbVFPPredicate(MI); 783263508Sdim return result; 784263508Sdim } 785226633Sdim } 786226633Sdim 787226633Sdim MI.clear(); 788263508Sdim result = decodeInstruction(DecoderTableVFPV832, MI, insn32, Address, this, STI); 789226633Sdim if (result != MCDisassembler::Fail) { 790226633Sdim Size = 4; 791226633Sdim return result; 792226633Sdim } 793226633Sdim 794263508Sdim if (fieldFromInstruction(insn32, 28, 4) == 0xE) { 795263508Sdim MI.clear(); 796263508Sdim result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address, 797263508Sdim this, STI); 798263508Sdim if (result != MCDisassembler::Fail) { 799263508Sdim Size = 4; 800263508Sdim Check(result, AddThumbPredicate(MI)); 801263508Sdim return result; 802263508Sdim } 803263508Sdim } 804263508Sdim 805239462Sdim if (fieldFromInstruction(insn32, 24, 8) == 0xF9) { 806226633Sdim MI.clear(); 807226633Sdim uint32_t NEONLdStInsn = insn32; 808226633Sdim NEONLdStInsn &= 0xF0FFFFFF; 809226633Sdim NEONLdStInsn |= 0x04000000; 810239462Sdim result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, 811239462Sdim Address, this, STI); 812226633Sdim if (result != MCDisassembler::Fail) { 813226633Sdim Size = 4; 814226633Sdim Check(result, AddThumbPredicate(MI)); 815226633Sdim return result; 816226633Sdim } 817226633Sdim } 818226633Sdim 819239462Sdim if (fieldFromInstruction(insn32, 24, 4) == 0xF) { 820226633Sdim MI.clear(); 821226633Sdim uint32_t NEONDataInsn = insn32; 822226633Sdim NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24 823226633Sdim NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 824226633Sdim NEONDataInsn |= 0x12000000; // Set bits 28 and 25 825239462Sdim result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn, 826239462Sdim Address, this, STI); 827226633Sdim if (result != MCDisassembler::Fail) { 828226633Sdim Size = 4; 829226633Sdim Check(result, AddThumbPredicate(MI)); 830226633Sdim return result; 831226633Sdim } 832263508Sdim 833263508Sdim MI.clear(); 834263508Sdim uint32_t NEONCryptoInsn = insn32; 835263508Sdim NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24 836263508Sdim NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 837263508Sdim NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25 838263508Sdim result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn, 839263508Sdim Address, this, STI); 840263508Sdim if (result != MCDisassembler::Fail) { 841263508Sdim Size = 4; 842263508Sdim return result; 843263508Sdim } 844263508Sdim 845263508Sdim MI.clear(); 846263508Sdim uint32_t NEONv8Insn = insn32; 847263508Sdim NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26 848263508Sdim result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address, 849263508Sdim this, STI); 850263508Sdim if (result != MCDisassembler::Fail) { 851263508Sdim Size = 4; 852263508Sdim return result; 853263508Sdim } 854226633Sdim } 855226633Sdim 856263508Sdim MI.clear(); 857226633Sdim Size = 0; 858226633Sdim return MCDisassembler::Fail; 859226633Sdim} 860226633Sdim 861226633Sdim 862226633Sdimextern "C" void LLVMInitializeARMDisassembler() { 863226633Sdim TargetRegistry::RegisterMCDisassembler(TheARMTarget, 864226633Sdim createARMDisassembler); 865226633Sdim TargetRegistry::RegisterMCDisassembler(TheThumbTarget, 866226633Sdim createThumbDisassembler); 867226633Sdim} 868226633Sdim 869234353Sdimstatic const uint16_t GPRDecoderTable[] = { 870226633Sdim ARM::R0, ARM::R1, ARM::R2, ARM::R3, 871226633Sdim ARM::R4, ARM::R5, ARM::R6, ARM::R7, 872226633Sdim ARM::R8, ARM::R9, ARM::R10, ARM::R11, 873226633Sdim ARM::R12, ARM::SP, ARM::LR, ARM::PC 874226633Sdim}; 875226633Sdim 876234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 877226633Sdim uint64_t Address, const void *Decoder) { 878226633Sdim if (RegNo > 15) 879226633Sdim return MCDisassembler::Fail; 880226633Sdim 881226633Sdim unsigned Register = GPRDecoderTable[RegNo]; 882226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 883226633Sdim return MCDisassembler::Success; 884226633Sdim} 885226633Sdim 886226633Sdimstatic DecodeStatus 887234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo, 888226633Sdim uint64_t Address, const void *Decoder) { 889234353Sdim DecodeStatus S = MCDisassembler::Success; 890234353Sdim 891234353Sdim if (RegNo == 15) 892234353Sdim S = MCDisassembler::SoftFail; 893234353Sdim 894234353Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 895234353Sdim 896234353Sdim return S; 897226633Sdim} 898226633Sdim 899263508Sdimstatic DecodeStatus 900263508SdimDecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, 901263508Sdim uint64_t Address, const void *Decoder) { 902263508Sdim DecodeStatus S = MCDisassembler::Success; 903263508Sdim 904263508Sdim if (RegNo == 15) 905263508Sdim { 906263508Sdim Inst.addOperand(MCOperand::CreateReg(ARM::APSR_NZCV)); 907263508Sdim return MCDisassembler::Success; 908263508Sdim } 909263508Sdim 910263508Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 911263508Sdim return S; 912263508Sdim} 913263508Sdim 914234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 915226633Sdim uint64_t Address, const void *Decoder) { 916226633Sdim if (RegNo > 7) 917226633Sdim return MCDisassembler::Fail; 918226633Sdim return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 919226633Sdim} 920226633Sdim 921263508Sdimstatic const uint16_t GPRPairDecoderTable[] = { 922263508Sdim ARM::R0_R1, ARM::R2_R3, ARM::R4_R5, ARM::R6_R7, 923263508Sdim ARM::R8_R9, ARM::R10_R11, ARM::R12_SP 924263508Sdim}; 925263508Sdim 926263508Sdimstatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo, 927263508Sdim uint64_t Address, const void *Decoder) { 928263508Sdim DecodeStatus S = MCDisassembler::Success; 929263508Sdim 930263508Sdim if (RegNo > 13) 931263508Sdim return MCDisassembler::Fail; 932263508Sdim 933263508Sdim if ((RegNo & 1) || RegNo == 0xe) 934263508Sdim S = MCDisassembler::SoftFail; 935263508Sdim 936263508Sdim unsigned RegisterPair = GPRPairDecoderTable[RegNo/2]; 937263508Sdim Inst.addOperand(MCOperand::CreateReg(RegisterPair)); 938263508Sdim return S; 939263508Sdim} 940263508Sdim 941234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 942226633Sdim uint64_t Address, const void *Decoder) { 943226633Sdim unsigned Register = 0; 944226633Sdim switch (RegNo) { 945226633Sdim case 0: 946226633Sdim Register = ARM::R0; 947206124Srdivacky break; 948226633Sdim case 1: 949226633Sdim Register = ARM::R1; 950226633Sdim break; 951226633Sdim case 2: 952226633Sdim Register = ARM::R2; 953226633Sdim break; 954206124Srdivacky case 3: 955226633Sdim Register = ARM::R3; 956206124Srdivacky break; 957226633Sdim case 9: 958226633Sdim Register = ARM::R9; 959226633Sdim break; 960226633Sdim case 12: 961226633Sdim Register = ARM::R12; 962226633Sdim break; 963206124Srdivacky default: 964226633Sdim return MCDisassembler::Fail; 965206124Srdivacky } 966226633Sdim 967226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 968226633Sdim return MCDisassembler::Success; 969226633Sdim} 970226633Sdim 971234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 972226633Sdim uint64_t Address, const void *Decoder) { 973263508Sdim DecodeStatus S = MCDisassembler::Success; 974263508Sdim if (RegNo == 13 || RegNo == 15) 975263508Sdim S = MCDisassembler::SoftFail; 976263508Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 977263508Sdim return S; 978226633Sdim} 979226633Sdim 980234353Sdimstatic const uint16_t SPRDecoderTable[] = { 981226633Sdim ARM::S0, ARM::S1, ARM::S2, ARM::S3, 982226633Sdim ARM::S4, ARM::S5, ARM::S6, ARM::S7, 983226633Sdim ARM::S8, ARM::S9, ARM::S10, ARM::S11, 984226633Sdim ARM::S12, ARM::S13, ARM::S14, ARM::S15, 985226633Sdim ARM::S16, ARM::S17, ARM::S18, ARM::S19, 986226633Sdim ARM::S20, ARM::S21, ARM::S22, ARM::S23, 987226633Sdim ARM::S24, ARM::S25, ARM::S26, ARM::S27, 988226633Sdim ARM::S28, ARM::S29, ARM::S30, ARM::S31 989226633Sdim}; 990226633Sdim 991234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 992226633Sdim uint64_t Address, const void *Decoder) { 993226633Sdim if (RegNo > 31) 994226633Sdim return MCDisassembler::Fail; 995226633Sdim 996226633Sdim unsigned Register = SPRDecoderTable[RegNo]; 997226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 998226633Sdim return MCDisassembler::Success; 999226633Sdim} 1000226633Sdim 1001234353Sdimstatic const uint16_t DPRDecoderTable[] = { 1002226633Sdim ARM::D0, ARM::D1, ARM::D2, ARM::D3, 1003226633Sdim ARM::D4, ARM::D5, ARM::D6, ARM::D7, 1004226633Sdim ARM::D8, ARM::D9, ARM::D10, ARM::D11, 1005226633Sdim ARM::D12, ARM::D13, ARM::D14, ARM::D15, 1006226633Sdim ARM::D16, ARM::D17, ARM::D18, ARM::D19, 1007226633Sdim ARM::D20, ARM::D21, ARM::D22, ARM::D23, 1008226633Sdim ARM::D24, ARM::D25, ARM::D26, ARM::D27, 1009226633Sdim ARM::D28, ARM::D29, ARM::D30, ARM::D31 1010226633Sdim}; 1011226633Sdim 1012234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 1013226633Sdim uint64_t Address, const void *Decoder) { 1014226633Sdim if (RegNo > 31) 1015226633Sdim return MCDisassembler::Fail; 1016226633Sdim 1017226633Sdim unsigned Register = DPRDecoderTable[RegNo]; 1018226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1019226633Sdim return MCDisassembler::Success; 1020226633Sdim} 1021226633Sdim 1022234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 1023226633Sdim uint64_t Address, const void *Decoder) { 1024226633Sdim if (RegNo > 7) 1025226633Sdim return MCDisassembler::Fail; 1026226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 1027226633Sdim} 1028226633Sdim 1029226633Sdimstatic DecodeStatus 1030234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo, 1031226633Sdim uint64_t Address, const void *Decoder) { 1032226633Sdim if (RegNo > 15) 1033226633Sdim return MCDisassembler::Fail; 1034226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 1035226633Sdim} 1036226633Sdim 1037234353Sdimstatic const uint16_t QPRDecoderTable[] = { 1038226633Sdim ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3, 1039226633Sdim ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7, 1040226633Sdim ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11, 1041226633Sdim ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15 1042226633Sdim}; 1043226633Sdim 1044226633Sdim 1045234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 1046226633Sdim uint64_t Address, const void *Decoder) { 1047263508Sdim if (RegNo > 31 || (RegNo & 1) != 0) 1048226633Sdim return MCDisassembler::Fail; 1049226633Sdim RegNo >>= 1; 1050226633Sdim 1051226633Sdim unsigned Register = QPRDecoderTable[RegNo]; 1052226633Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1053226633Sdim return MCDisassembler::Success; 1054226633Sdim} 1055226633Sdim 1056234353Sdimstatic const uint16_t DPairDecoderTable[] = { 1057234353Sdim ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6, 1058234353Sdim ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12, 1059234353Sdim ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18, 1060234353Sdim ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24, 1061234353Sdim ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30, 1062234353Sdim ARM::Q15 1063234353Sdim}; 1064234353Sdim 1065234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 1066234353Sdim uint64_t Address, const void *Decoder) { 1067234353Sdim if (RegNo > 30) 1068234353Sdim return MCDisassembler::Fail; 1069234353Sdim 1070234353Sdim unsigned Register = DPairDecoderTable[RegNo]; 1071234353Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1072234353Sdim return MCDisassembler::Success; 1073234353Sdim} 1074234353Sdim 1075234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = { 1076234353Sdim ARM::D0_D2, ARM::D1_D3, ARM::D2_D4, ARM::D3_D5, 1077234353Sdim ARM::D4_D6, ARM::D5_D7, ARM::D6_D8, ARM::D7_D9, 1078234353Sdim ARM::D8_D10, ARM::D9_D11, ARM::D10_D12, ARM::D11_D13, 1079234353Sdim ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17, 1080234353Sdim ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21, 1081234353Sdim ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25, 1082234353Sdim ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29, 1083234353Sdim ARM::D28_D30, ARM::D29_D31 1084234353Sdim}; 1085234353Sdim 1086234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 1087234353Sdim unsigned RegNo, 1088234353Sdim uint64_t Address, 1089234353Sdim const void *Decoder) { 1090234353Sdim if (RegNo > 29) 1091234353Sdim return MCDisassembler::Fail; 1092234353Sdim 1093234353Sdim unsigned Register = DPairSpacedDecoderTable[RegNo]; 1094234353Sdim Inst.addOperand(MCOperand::CreateReg(Register)); 1095234353Sdim return MCDisassembler::Success; 1096234353Sdim} 1097234353Sdim 1098234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 1099226633Sdim uint64_t Address, const void *Decoder) { 1100226633Sdim if (Val == 0xF) return MCDisassembler::Fail; 1101226633Sdim // AL predicate is not allowed on Thumb1 branches. 1102226633Sdim if (Inst.getOpcode() == ARM::tBcc && Val == 0xE) 1103226633Sdim return MCDisassembler::Fail; 1104226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 1105226633Sdim if (Val == ARMCC::AL) { 1106226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1107226633Sdim } else 1108226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1109226633Sdim return MCDisassembler::Success; 1110226633Sdim} 1111226633Sdim 1112234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 1113226633Sdim uint64_t Address, const void *Decoder) { 1114226633Sdim if (Val) 1115226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1116226633Sdim else 1117226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1118226633Sdim return MCDisassembler::Success; 1119226633Sdim} 1120226633Sdim 1121234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, 1122226633Sdim uint64_t Address, const void *Decoder) { 1123226633Sdim uint32_t imm = Val & 0xFF; 1124226633Sdim uint32_t rot = (Val & 0xF00) >> 7; 1125226633Sdim uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F)); 1126226633Sdim Inst.addOperand(MCOperand::CreateImm(rot_imm)); 1127226633Sdim return MCDisassembler::Success; 1128226633Sdim} 1129226633Sdim 1130234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val, 1131226633Sdim uint64_t Address, const void *Decoder) { 1132226633Sdim DecodeStatus S = MCDisassembler::Success; 1133226633Sdim 1134239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1135239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1136239462Sdim unsigned imm = fieldFromInstruction(Val, 7, 5); 1137226633Sdim 1138226633Sdim // Register-immediate 1139226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1140226633Sdim return MCDisassembler::Fail; 1141226633Sdim 1142226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1143226633Sdim switch (type) { 1144226633Sdim case 0: 1145226633Sdim Shift = ARM_AM::lsl; 1146226633Sdim break; 1147226633Sdim case 1: 1148226633Sdim Shift = ARM_AM::lsr; 1149226633Sdim break; 1150226633Sdim case 2: 1151226633Sdim Shift = ARM_AM::asr; 1152226633Sdim break; 1153226633Sdim case 3: 1154226633Sdim Shift = ARM_AM::ror; 1155226633Sdim break; 1156206124Srdivacky } 1157206124Srdivacky 1158226633Sdim if (Shift == ARM_AM::ror && imm == 0) 1159226633Sdim Shift = ARM_AM::rrx; 1160226633Sdim 1161226633Sdim unsigned Op = Shift | (imm << 3); 1162226633Sdim Inst.addOperand(MCOperand::CreateImm(Op)); 1163226633Sdim 1164226633Sdim return S; 1165226633Sdim} 1166226633Sdim 1167234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val, 1168226633Sdim uint64_t Address, const void *Decoder) { 1169226633Sdim DecodeStatus S = MCDisassembler::Success; 1170226633Sdim 1171239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1172239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1173239462Sdim unsigned Rs = fieldFromInstruction(Val, 8, 4); 1174226633Sdim 1175226633Sdim // Register-register 1176226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1177226633Sdim return MCDisassembler::Fail; 1178226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder))) 1179226633Sdim return MCDisassembler::Fail; 1180226633Sdim 1181226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1182226633Sdim switch (type) { 1183226633Sdim case 0: 1184226633Sdim Shift = ARM_AM::lsl; 1185206124Srdivacky break; 1186226633Sdim case 1: 1187226633Sdim Shift = ARM_AM::lsr; 1188206124Srdivacky break; 1189226633Sdim case 2: 1190226633Sdim Shift = ARM_AM::asr; 1191206124Srdivacky break; 1192226633Sdim case 3: 1193226633Sdim Shift = ARM_AM::ror; 1194226633Sdim break; 1195226633Sdim } 1196226633Sdim 1197226633Sdim Inst.addOperand(MCOperand::CreateImm(Shift)); 1198226633Sdim 1199226633Sdim return S; 1200226633Sdim} 1201226633Sdim 1202234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 1203226633Sdim uint64_t Address, const void *Decoder) { 1204226633Sdim DecodeStatus S = MCDisassembler::Success; 1205226633Sdim 1206263508Sdim bool NeedDisjointWriteback = false; 1207263508Sdim unsigned WritebackReg = 0; 1208226633Sdim switch (Inst.getOpcode()) { 1209263508Sdim default: 1210263508Sdim break; 1211263508Sdim case ARM::LDMIA_UPD: 1212263508Sdim case ARM::LDMDB_UPD: 1213263508Sdim case ARM::LDMIB_UPD: 1214263508Sdim case ARM::LDMDA_UPD: 1215263508Sdim case ARM::t2LDMIA_UPD: 1216263508Sdim case ARM::t2LDMDB_UPD: 1217263508Sdim case ARM::t2STMIA_UPD: 1218263508Sdim case ARM::t2STMDB_UPD: 1219263508Sdim NeedDisjointWriteback = true; 1220263508Sdim WritebackReg = Inst.getOperand(0).getReg(); 1221263508Sdim break; 1222226633Sdim } 1223226633Sdim 1224226633Sdim // Empty register lists are not allowed. 1225263508Sdim if (Val == 0) return MCDisassembler::Fail; 1226226633Sdim for (unsigned i = 0; i < 16; ++i) { 1227226633Sdim if (Val & (1 << i)) { 1228226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder))) 1229226633Sdim return MCDisassembler::Fail; 1230226633Sdim // Writeback not allowed if Rn is in the target list. 1231263508Sdim if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg()) 1232226633Sdim Check(S, MCDisassembler::SoftFail); 1233206124Srdivacky } 1234206124Srdivacky } 1235206124Srdivacky 1236226633Sdim return S; 1237226633Sdim} 1238226633Sdim 1239234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 1240226633Sdim uint64_t Address, const void *Decoder) { 1241226633Sdim DecodeStatus S = MCDisassembler::Success; 1242226633Sdim 1243239462Sdim unsigned Vd = fieldFromInstruction(Val, 8, 5); 1244239462Sdim unsigned regs = fieldFromInstruction(Val, 0, 8); 1245226633Sdim 1246263508Sdim // In case of unpredictable encoding, tweak the operands. 1247263508Sdim if (regs == 0 || (Vd + regs) > 32) { 1248263508Sdim regs = Vd + regs > 32 ? 32 - Vd : regs; 1249263508Sdim regs = std::max( 1u, regs); 1250263508Sdim S = MCDisassembler::SoftFail; 1251263508Sdim } 1252263508Sdim 1253226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder))) 1254226633Sdim return MCDisassembler::Fail; 1255226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1256226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1257226633Sdim return MCDisassembler::Fail; 1258226633Sdim } 1259226633Sdim 1260226633Sdim return S; 1261226633Sdim} 1262226633Sdim 1263234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 1264226633Sdim uint64_t Address, const void *Decoder) { 1265226633Sdim DecodeStatus S = MCDisassembler::Success; 1266226633Sdim 1267239462Sdim unsigned Vd = fieldFromInstruction(Val, 8, 5); 1268263508Sdim unsigned regs = fieldFromInstruction(Val, 1, 7); 1269226633Sdim 1270263508Sdim // In case of unpredictable encoding, tweak the operands. 1271263508Sdim if (regs == 0 || regs > 16 || (Vd + regs) > 32) { 1272263508Sdim regs = Vd + regs > 32 ? 32 - Vd : regs; 1273263508Sdim regs = std::max( 1u, regs); 1274263508Sdim regs = std::min(16u, regs); 1275263508Sdim S = MCDisassembler::SoftFail; 1276263508Sdim } 1277239462Sdim 1278226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 1279226633Sdim return MCDisassembler::Fail; 1280226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1281226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1282226633Sdim return MCDisassembler::Fail; 1283226633Sdim } 1284226633Sdim 1285226633Sdim return S; 1286226633Sdim} 1287226633Sdim 1288234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val, 1289226633Sdim uint64_t Address, const void *Decoder) { 1290226633Sdim // This operand encodes a mask of contiguous zeros between a specified MSB 1291226633Sdim // and LSB. To decode it, we create the mask of all bits MSB-and-lower, 1292226633Sdim // the mask of all bits LSB-and-lower, and then xor them to create 1293226633Sdim // the mask of that's all ones on [msb, lsb]. Finally we not it to 1294226633Sdim // create the final mask. 1295239462Sdim unsigned msb = fieldFromInstruction(Val, 5, 5); 1296239462Sdim unsigned lsb = fieldFromInstruction(Val, 0, 5); 1297226633Sdim 1298226633Sdim DecodeStatus S = MCDisassembler::Success; 1299249423Sdim if (lsb > msb) { 1300249423Sdim Check(S, MCDisassembler::SoftFail); 1301249423Sdim // The check above will cause the warning for the "potentially undefined 1302249423Sdim // instruction encoding" but we can't build a bad MCOperand value here 1303249423Sdim // with a lsb > msb or else printing the MCInst will cause a crash. 1304249423Sdim lsb = msb; 1305249423Sdim } 1306226633Sdim 1307226633Sdim uint32_t msb_mask = 0xFFFFFFFF; 1308226633Sdim if (msb != 31) msb_mask = (1U << (msb+1)) - 1; 1309226633Sdim uint32_t lsb_mask = (1U << lsb) - 1; 1310226633Sdim 1311226633Sdim Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask))); 1312226633Sdim return S; 1313226633Sdim} 1314226633Sdim 1315234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 1316226633Sdim uint64_t Address, const void *Decoder) { 1317226633Sdim DecodeStatus S = MCDisassembler::Success; 1318226633Sdim 1319239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1320239462Sdim unsigned CRd = fieldFromInstruction(Insn, 12, 4); 1321239462Sdim unsigned coproc = fieldFromInstruction(Insn, 8, 4); 1322239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 1323239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1324239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 1325226633Sdim 1326226633Sdim switch (Inst.getOpcode()) { 1327226633Sdim case ARM::LDC_OFFSET: 1328226633Sdim case ARM::LDC_PRE: 1329226633Sdim case ARM::LDC_POST: 1330226633Sdim case ARM::LDC_OPTION: 1331226633Sdim case ARM::LDCL_OFFSET: 1332226633Sdim case ARM::LDCL_PRE: 1333226633Sdim case ARM::LDCL_POST: 1334226633Sdim case ARM::LDCL_OPTION: 1335226633Sdim case ARM::STC_OFFSET: 1336226633Sdim case ARM::STC_PRE: 1337226633Sdim case ARM::STC_POST: 1338226633Sdim case ARM::STC_OPTION: 1339226633Sdim case ARM::STCL_OFFSET: 1340226633Sdim case ARM::STCL_PRE: 1341226633Sdim case ARM::STCL_POST: 1342226633Sdim case ARM::STCL_OPTION: 1343226633Sdim case ARM::t2LDC_OFFSET: 1344226633Sdim case ARM::t2LDC_PRE: 1345226633Sdim case ARM::t2LDC_POST: 1346226633Sdim case ARM::t2LDC_OPTION: 1347226633Sdim case ARM::t2LDCL_OFFSET: 1348226633Sdim case ARM::t2LDCL_PRE: 1349226633Sdim case ARM::t2LDCL_POST: 1350226633Sdim case ARM::t2LDCL_OPTION: 1351226633Sdim case ARM::t2STC_OFFSET: 1352226633Sdim case ARM::t2STC_PRE: 1353226633Sdim case ARM::t2STC_POST: 1354226633Sdim case ARM::t2STC_OPTION: 1355226633Sdim case ARM::t2STCL_OFFSET: 1356226633Sdim case ARM::t2STCL_PRE: 1357226633Sdim case ARM::t2STCL_POST: 1358226633Sdim case ARM::t2STCL_OPTION: 1359226633Sdim if (coproc == 0xA || coproc == 0xB) 1360226633Sdim return MCDisassembler::Fail; 1361206124Srdivacky break; 1362226633Sdim default: 1363226633Sdim break; 1364226633Sdim } 1365226633Sdim 1366263508Sdim uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo() 1367263508Sdim .getFeatureBits(); 1368263508Sdim if ((featureBits & ARM::HasV8Ops) && (coproc != 14)) 1369263508Sdim return MCDisassembler::Fail; 1370263508Sdim 1371226633Sdim Inst.addOperand(MCOperand::CreateImm(coproc)); 1372226633Sdim Inst.addOperand(MCOperand::CreateImm(CRd)); 1373226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1374226633Sdim return MCDisassembler::Fail; 1375226633Sdim 1376226633Sdim switch (Inst.getOpcode()) { 1377226633Sdim case ARM::t2LDC2_OFFSET: 1378226633Sdim case ARM::t2LDC2L_OFFSET: 1379226633Sdim case ARM::t2LDC2_PRE: 1380226633Sdim case ARM::t2LDC2L_PRE: 1381226633Sdim case ARM::t2STC2_OFFSET: 1382226633Sdim case ARM::t2STC2L_OFFSET: 1383226633Sdim case ARM::t2STC2_PRE: 1384226633Sdim case ARM::t2STC2L_PRE: 1385226633Sdim case ARM::LDC2_OFFSET: 1386226633Sdim case ARM::LDC2L_OFFSET: 1387226633Sdim case ARM::LDC2_PRE: 1388226633Sdim case ARM::LDC2L_PRE: 1389226633Sdim case ARM::STC2_OFFSET: 1390226633Sdim case ARM::STC2L_OFFSET: 1391226633Sdim case ARM::STC2_PRE: 1392226633Sdim case ARM::STC2L_PRE: 1393226633Sdim case ARM::t2LDC_OFFSET: 1394226633Sdim case ARM::t2LDCL_OFFSET: 1395226633Sdim case ARM::t2LDC_PRE: 1396226633Sdim case ARM::t2LDCL_PRE: 1397226633Sdim case ARM::t2STC_OFFSET: 1398226633Sdim case ARM::t2STCL_OFFSET: 1399226633Sdim case ARM::t2STC_PRE: 1400226633Sdim case ARM::t2STCL_PRE: 1401226633Sdim case ARM::LDC_OFFSET: 1402226633Sdim case ARM::LDCL_OFFSET: 1403226633Sdim case ARM::LDC_PRE: 1404226633Sdim case ARM::LDCL_PRE: 1405226633Sdim case ARM::STC_OFFSET: 1406226633Sdim case ARM::STCL_OFFSET: 1407226633Sdim case ARM::STC_PRE: 1408226633Sdim case ARM::STCL_PRE: 1409226633Sdim imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm); 1410226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1411226633Sdim break; 1412226633Sdim case ARM::t2LDC2_POST: 1413226633Sdim case ARM::t2LDC2L_POST: 1414226633Sdim case ARM::t2STC2_POST: 1415226633Sdim case ARM::t2STC2L_POST: 1416226633Sdim case ARM::LDC2_POST: 1417226633Sdim case ARM::LDC2L_POST: 1418226633Sdim case ARM::STC2_POST: 1419226633Sdim case ARM::STC2L_POST: 1420226633Sdim case ARM::t2LDC_POST: 1421226633Sdim case ARM::t2LDCL_POST: 1422226633Sdim case ARM::t2STC_POST: 1423226633Sdim case ARM::t2STCL_POST: 1424226633Sdim case ARM::LDC_POST: 1425226633Sdim case ARM::LDCL_POST: 1426226633Sdim case ARM::STC_POST: 1427226633Sdim case ARM::STCL_POST: 1428226633Sdim imm |= U << 8; 1429226633Sdim // fall through. 1430226633Sdim default: 1431226633Sdim // The 'option' variant doesn't encode 'U' in the immediate since 1432226633Sdim // the immediate is unsigned [0,255]. 1433226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1434226633Sdim break; 1435226633Sdim } 1436226633Sdim 1437226633Sdim switch (Inst.getOpcode()) { 1438226633Sdim case ARM::LDC_OFFSET: 1439226633Sdim case ARM::LDC_PRE: 1440226633Sdim case ARM::LDC_POST: 1441226633Sdim case ARM::LDC_OPTION: 1442226633Sdim case ARM::LDCL_OFFSET: 1443226633Sdim case ARM::LDCL_PRE: 1444226633Sdim case ARM::LDCL_POST: 1445226633Sdim case ARM::LDCL_OPTION: 1446226633Sdim case ARM::STC_OFFSET: 1447226633Sdim case ARM::STC_PRE: 1448226633Sdim case ARM::STC_POST: 1449226633Sdim case ARM::STC_OPTION: 1450226633Sdim case ARM::STCL_OFFSET: 1451226633Sdim case ARM::STCL_PRE: 1452226633Sdim case ARM::STCL_POST: 1453226633Sdim case ARM::STCL_OPTION: 1454226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1455226633Sdim return MCDisassembler::Fail; 1456226633Sdim break; 1457226633Sdim default: 1458226633Sdim break; 1459226633Sdim } 1460226633Sdim 1461226633Sdim return S; 1462226633Sdim} 1463226633Sdim 1464226633Sdimstatic DecodeStatus 1465234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, 1466226633Sdim uint64_t Address, const void *Decoder) { 1467226633Sdim DecodeStatus S = MCDisassembler::Success; 1468226633Sdim 1469239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1470239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 1471239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1472239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 1473239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1474239462Sdim unsigned reg = fieldFromInstruction(Insn, 25, 1); 1475239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 1476239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 1477226633Sdim 1478226633Sdim // On stores, the writeback operand precedes Rt. 1479226633Sdim switch (Inst.getOpcode()) { 1480226633Sdim case ARM::STR_POST_IMM: 1481226633Sdim case ARM::STR_POST_REG: 1482226633Sdim case ARM::STRB_POST_IMM: 1483226633Sdim case ARM::STRB_POST_REG: 1484226633Sdim case ARM::STRT_POST_REG: 1485226633Sdim case ARM::STRT_POST_IMM: 1486226633Sdim case ARM::STRBT_POST_REG: 1487226633Sdim case ARM::STRBT_POST_IMM: 1488226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1489226633Sdim return MCDisassembler::Fail; 1490226633Sdim break; 1491226633Sdim default: 1492226633Sdim break; 1493226633Sdim } 1494226633Sdim 1495226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1496226633Sdim return MCDisassembler::Fail; 1497226633Sdim 1498226633Sdim // On loads, the writeback operand comes after Rt. 1499226633Sdim switch (Inst.getOpcode()) { 1500226633Sdim case ARM::LDR_POST_IMM: 1501226633Sdim case ARM::LDR_POST_REG: 1502226633Sdim case ARM::LDRB_POST_IMM: 1503226633Sdim case ARM::LDRB_POST_REG: 1504226633Sdim case ARM::LDRBT_POST_REG: 1505226633Sdim case ARM::LDRBT_POST_IMM: 1506226633Sdim case ARM::LDRT_POST_REG: 1507226633Sdim case ARM::LDRT_POST_IMM: 1508226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1509226633Sdim return MCDisassembler::Fail; 1510226633Sdim break; 1511226633Sdim default: 1512226633Sdim break; 1513226633Sdim } 1514226633Sdim 1515226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1516226633Sdim return MCDisassembler::Fail; 1517226633Sdim 1518226633Sdim ARM_AM::AddrOpc Op = ARM_AM::add; 1519239462Sdim if (!fieldFromInstruction(Insn, 23, 1)) 1520226633Sdim Op = ARM_AM::sub; 1521226633Sdim 1522226633Sdim bool writeback = (P == 0) || (W == 1); 1523226633Sdim unsigned idx_mode = 0; 1524226633Sdim if (P && writeback) 1525226633Sdim idx_mode = ARMII::IndexModePre; 1526226633Sdim else if (!P && writeback) 1527226633Sdim idx_mode = ARMII::IndexModePost; 1528226633Sdim 1529226633Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1530226633Sdim S = MCDisassembler::SoftFail; // UNPREDICTABLE 1531226633Sdim 1532226633Sdim if (reg) { 1533226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1534226633Sdim return MCDisassembler::Fail; 1535226633Sdim ARM_AM::ShiftOpc Opc = ARM_AM::lsl; 1536239462Sdim switch( fieldFromInstruction(Insn, 5, 2)) { 1537226633Sdim case 0: 1538226633Sdim Opc = ARM_AM::lsl; 1539226633Sdim break; 1540226633Sdim case 1: 1541226633Sdim Opc = ARM_AM::lsr; 1542226633Sdim break; 1543226633Sdim case 2: 1544226633Sdim Opc = ARM_AM::asr; 1545226633Sdim break; 1546226633Sdim case 3: 1547226633Sdim Opc = ARM_AM::ror; 1548226633Sdim break; 1549206124Srdivacky default: 1550226633Sdim return MCDisassembler::Fail; 1551226633Sdim } 1552239462Sdim unsigned amt = fieldFromInstruction(Insn, 7, 5); 1553243830Sdim if (Opc == ARM_AM::ror && amt == 0) 1554243830Sdim Opc = ARM_AM::rrx; 1555226633Sdim unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode); 1556226633Sdim 1557226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 1558226633Sdim } else { 1559226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1560226633Sdim unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode); 1561226633Sdim Inst.addOperand(MCOperand::CreateImm(tmp)); 1562226633Sdim } 1563226633Sdim 1564226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1565226633Sdim return MCDisassembler::Fail; 1566226633Sdim 1567226633Sdim return S; 1568226633Sdim} 1569226633Sdim 1570234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val, 1571226633Sdim uint64_t Address, const void *Decoder) { 1572226633Sdim DecodeStatus S = MCDisassembler::Success; 1573226633Sdim 1574239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 1575239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1576239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1577239462Sdim unsigned imm = fieldFromInstruction(Val, 7, 5); 1578239462Sdim unsigned U = fieldFromInstruction(Val, 12, 1); 1579226633Sdim 1580226633Sdim ARM_AM::ShiftOpc ShOp = ARM_AM::lsl; 1581226633Sdim switch (type) { 1582226633Sdim case 0: 1583226633Sdim ShOp = ARM_AM::lsl; 1584206124Srdivacky break; 1585226633Sdim case 1: 1586226633Sdim ShOp = ARM_AM::lsr; 1587226633Sdim break; 1588226633Sdim case 2: 1589226633Sdim ShOp = ARM_AM::asr; 1590226633Sdim break; 1591226633Sdim case 3: 1592226633Sdim ShOp = ARM_AM::ror; 1593226633Sdim break; 1594226633Sdim } 1595226633Sdim 1596243830Sdim if (ShOp == ARM_AM::ror && imm == 0) 1597243830Sdim ShOp = ARM_AM::rrx; 1598243830Sdim 1599226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1600226633Sdim return MCDisassembler::Fail; 1601226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1602226633Sdim return MCDisassembler::Fail; 1603226633Sdim unsigned shift; 1604226633Sdim if (U) 1605226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp); 1606226633Sdim else 1607226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp); 1608226633Sdim Inst.addOperand(MCOperand::CreateImm(shift)); 1609226633Sdim 1610226633Sdim return S; 1611226633Sdim} 1612226633Sdim 1613226633Sdimstatic DecodeStatus 1614234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn, 1615226633Sdim uint64_t Address, const void *Decoder) { 1616226633Sdim DecodeStatus S = MCDisassembler::Success; 1617226633Sdim 1618239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 1619239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1620239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1621239462Sdim unsigned type = fieldFromInstruction(Insn, 22, 1); 1622239462Sdim unsigned imm = fieldFromInstruction(Insn, 8, 4); 1623239462Sdim unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8; 1624239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1625239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 1626239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 1627234353Sdim unsigned Rt2 = Rt + 1; 1628226633Sdim 1629226633Sdim bool writeback = (W == 1) | (P == 0); 1630226633Sdim 1631226633Sdim // For {LD,ST}RD, Rt must be even, else undefined. 1632226633Sdim switch (Inst.getOpcode()) { 1633226633Sdim case ARM::STRD: 1634226633Sdim case ARM::STRD_PRE: 1635226633Sdim case ARM::STRD_POST: 1636226633Sdim case ARM::LDRD: 1637226633Sdim case ARM::LDRD_PRE: 1638226633Sdim case ARM::LDRD_POST: 1639234353Sdim if (Rt & 0x1) S = MCDisassembler::SoftFail; 1640226633Sdim break; 1641226633Sdim default: 1642226633Sdim break; 1643226633Sdim } 1644234353Sdim switch (Inst.getOpcode()) { 1645234353Sdim case ARM::STRD: 1646234353Sdim case ARM::STRD_PRE: 1647234353Sdim case ARM::STRD_POST: 1648234353Sdim if (P == 0 && W == 1) 1649234353Sdim S = MCDisassembler::SoftFail; 1650234353Sdim 1651234353Sdim if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2)) 1652234353Sdim S = MCDisassembler::SoftFail; 1653234353Sdim if (type && Rm == 15) 1654234353Sdim S = MCDisassembler::SoftFail; 1655234353Sdim if (Rt2 == 15) 1656234353Sdim S = MCDisassembler::SoftFail; 1657239462Sdim if (!type && fieldFromInstruction(Insn, 8, 4)) 1658234353Sdim S = MCDisassembler::SoftFail; 1659234353Sdim break; 1660234353Sdim case ARM::STRH: 1661234353Sdim case ARM::STRH_PRE: 1662234353Sdim case ARM::STRH_POST: 1663234353Sdim if (Rt == 15) 1664234353Sdim S = MCDisassembler::SoftFail; 1665234353Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1666234353Sdim S = MCDisassembler::SoftFail; 1667234353Sdim if (!type && Rm == 15) 1668234353Sdim S = MCDisassembler::SoftFail; 1669234353Sdim break; 1670234353Sdim case ARM::LDRD: 1671234353Sdim case ARM::LDRD_PRE: 1672234353Sdim case ARM::LDRD_POST: 1673234353Sdim if (type && Rn == 15){ 1674234353Sdim if (Rt2 == 15) 1675234353Sdim S = MCDisassembler::SoftFail; 1676234353Sdim break; 1677234353Sdim } 1678234353Sdim if (P == 0 && W == 1) 1679234353Sdim S = MCDisassembler::SoftFail; 1680234353Sdim if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2)) 1681234353Sdim S = MCDisassembler::SoftFail; 1682234353Sdim if (!type && writeback && Rn == 15) 1683234353Sdim S = MCDisassembler::SoftFail; 1684234353Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 1685234353Sdim S = MCDisassembler::SoftFail; 1686234353Sdim break; 1687234353Sdim case ARM::LDRH: 1688234353Sdim case ARM::LDRH_PRE: 1689234353Sdim case ARM::LDRH_POST: 1690234353Sdim if (type && Rn == 15){ 1691234353Sdim if (Rt == 15) 1692234353Sdim S = MCDisassembler::SoftFail; 1693234353Sdim break; 1694234353Sdim } 1695234353Sdim if (Rt == 15) 1696234353Sdim S = MCDisassembler::SoftFail; 1697234353Sdim if (!type && Rm == 15) 1698234353Sdim S = MCDisassembler::SoftFail; 1699234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 1700234353Sdim S = MCDisassembler::SoftFail; 1701234353Sdim break; 1702234353Sdim case ARM::LDRSH: 1703234353Sdim case ARM::LDRSH_PRE: 1704234353Sdim case ARM::LDRSH_POST: 1705234353Sdim case ARM::LDRSB: 1706234353Sdim case ARM::LDRSB_PRE: 1707234353Sdim case ARM::LDRSB_POST: 1708234353Sdim if (type && Rn == 15){ 1709234353Sdim if (Rt == 15) 1710234353Sdim S = MCDisassembler::SoftFail; 1711234353Sdim break; 1712234353Sdim } 1713234353Sdim if (type && (Rt == 15 || (writeback && Rn == Rt))) 1714234353Sdim S = MCDisassembler::SoftFail; 1715234353Sdim if (!type && (Rt == 15 || Rm == 15)) 1716234353Sdim S = MCDisassembler::SoftFail; 1717234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 1718234353Sdim S = MCDisassembler::SoftFail; 1719234353Sdim break; 1720234353Sdim default: 1721234353Sdim break; 1722234353Sdim } 1723226633Sdim 1724226633Sdim if (writeback) { // Writeback 1725226633Sdim if (P) 1726226633Sdim U |= ARMII::IndexModePre << 9; 1727226633Sdim else 1728226633Sdim U |= ARMII::IndexModePost << 9; 1729226633Sdim 1730226633Sdim // On stores, the writeback operand precedes Rt. 1731226633Sdim switch (Inst.getOpcode()) { 1732226633Sdim case ARM::STRD: 1733226633Sdim case ARM::STRD_PRE: 1734226633Sdim case ARM::STRD_POST: 1735226633Sdim case ARM::STRH: 1736226633Sdim case ARM::STRH_PRE: 1737226633Sdim case ARM::STRH_POST: 1738226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1739226633Sdim return MCDisassembler::Fail; 1740226633Sdim break; 1741226633Sdim default: 1742226633Sdim break; 1743226633Sdim } 1744226633Sdim } 1745226633Sdim 1746226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1747226633Sdim return MCDisassembler::Fail; 1748226633Sdim switch (Inst.getOpcode()) { 1749226633Sdim case ARM::STRD: 1750226633Sdim case ARM::STRD_PRE: 1751226633Sdim case ARM::STRD_POST: 1752226633Sdim case ARM::LDRD: 1753226633Sdim case ARM::LDRD_PRE: 1754226633Sdim case ARM::LDRD_POST: 1755226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 1756226633Sdim return MCDisassembler::Fail; 1757226633Sdim break; 1758226633Sdim default: 1759226633Sdim break; 1760226633Sdim } 1761226633Sdim 1762226633Sdim if (writeback) { 1763226633Sdim // On loads, the writeback operand comes after Rt. 1764226633Sdim switch (Inst.getOpcode()) { 1765226633Sdim case ARM::LDRD: 1766226633Sdim case ARM::LDRD_PRE: 1767226633Sdim case ARM::LDRD_POST: 1768226633Sdim case ARM::LDRH: 1769226633Sdim case ARM::LDRH_PRE: 1770226633Sdim case ARM::LDRH_POST: 1771226633Sdim case ARM::LDRSH: 1772226633Sdim case ARM::LDRSH_PRE: 1773226633Sdim case ARM::LDRSH_POST: 1774226633Sdim case ARM::LDRSB: 1775226633Sdim case ARM::LDRSB_PRE: 1776226633Sdim case ARM::LDRSB_POST: 1777226633Sdim case ARM::LDRHTr: 1778226633Sdim case ARM::LDRSBTr: 1779226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1780226633Sdim return MCDisassembler::Fail; 1781226633Sdim break; 1782226633Sdim default: 1783226633Sdim break; 1784226633Sdim } 1785226633Sdim } 1786226633Sdim 1787226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1788226633Sdim return MCDisassembler::Fail; 1789226633Sdim 1790226633Sdim if (type) { 1791226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 1792226633Sdim Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm)); 1793226633Sdim } else { 1794226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1795226633Sdim return MCDisassembler::Fail; 1796226633Sdim Inst.addOperand(MCOperand::CreateImm(U)); 1797226633Sdim } 1798226633Sdim 1799226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1800226633Sdim return MCDisassembler::Fail; 1801226633Sdim 1802226633Sdim return S; 1803226633Sdim} 1804226633Sdim 1805234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn, 1806226633Sdim uint64_t Address, const void *Decoder) { 1807226633Sdim DecodeStatus S = MCDisassembler::Success; 1808226633Sdim 1809239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1810239462Sdim unsigned mode = fieldFromInstruction(Insn, 23, 2); 1811226633Sdim 1812226633Sdim switch (mode) { 1813226633Sdim case 0: 1814226633Sdim mode = ARM_AM::da; 1815226633Sdim break; 1816226633Sdim case 1: 1817226633Sdim mode = ARM_AM::ia; 1818226633Sdim break; 1819226633Sdim case 2: 1820226633Sdim mode = ARM_AM::db; 1821226633Sdim break; 1822226633Sdim case 3: 1823226633Sdim mode = ARM_AM::ib; 1824226633Sdim break; 1825226633Sdim } 1826226633Sdim 1827226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1828226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1829226633Sdim return MCDisassembler::Fail; 1830226633Sdim 1831226633Sdim return S; 1832226633Sdim} 1833226633Sdim 1834263508Sdimstatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn, 1835263508Sdim uint64_t Address, const void *Decoder) { 1836263508Sdim DecodeStatus S = MCDisassembler::Success; 1837263508Sdim 1838263508Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 1839263508Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1840263508Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1841263508Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1842263508Sdim 1843263508Sdim if (pred == 0xF) 1844263508Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 1845263508Sdim 1846263508Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 1847263508Sdim return MCDisassembler::Fail; 1848263508Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1849263508Sdim return MCDisassembler::Fail; 1850263508Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 1851263508Sdim return MCDisassembler::Fail; 1852263508Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1853263508Sdim return MCDisassembler::Fail; 1854263508Sdim return S; 1855263508Sdim} 1856263508Sdim 1857234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst, 1858226633Sdim unsigned Insn, 1859226633Sdim uint64_t Address, const void *Decoder) { 1860226633Sdim DecodeStatus S = MCDisassembler::Success; 1861226633Sdim 1862239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1863239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1864239462Sdim unsigned reglist = fieldFromInstruction(Insn, 0, 16); 1865226633Sdim 1866226633Sdim if (pred == 0xF) { 1867263508Sdim // Ambiguous with RFE and SRS 1868226633Sdim switch (Inst.getOpcode()) { 1869226633Sdim case ARM::LDMDA: 1870226633Sdim Inst.setOpcode(ARM::RFEDA); 1871226633Sdim break; 1872226633Sdim case ARM::LDMDA_UPD: 1873226633Sdim Inst.setOpcode(ARM::RFEDA_UPD); 1874226633Sdim break; 1875226633Sdim case ARM::LDMDB: 1876226633Sdim Inst.setOpcode(ARM::RFEDB); 1877226633Sdim break; 1878226633Sdim case ARM::LDMDB_UPD: 1879226633Sdim Inst.setOpcode(ARM::RFEDB_UPD); 1880226633Sdim break; 1881226633Sdim case ARM::LDMIA: 1882226633Sdim Inst.setOpcode(ARM::RFEIA); 1883226633Sdim break; 1884226633Sdim case ARM::LDMIA_UPD: 1885226633Sdim Inst.setOpcode(ARM::RFEIA_UPD); 1886226633Sdim break; 1887226633Sdim case ARM::LDMIB: 1888226633Sdim Inst.setOpcode(ARM::RFEIB); 1889226633Sdim break; 1890226633Sdim case ARM::LDMIB_UPD: 1891226633Sdim Inst.setOpcode(ARM::RFEIB_UPD); 1892226633Sdim break; 1893226633Sdim case ARM::STMDA: 1894226633Sdim Inst.setOpcode(ARM::SRSDA); 1895226633Sdim break; 1896226633Sdim case ARM::STMDA_UPD: 1897226633Sdim Inst.setOpcode(ARM::SRSDA_UPD); 1898226633Sdim break; 1899226633Sdim case ARM::STMDB: 1900226633Sdim Inst.setOpcode(ARM::SRSDB); 1901226633Sdim break; 1902226633Sdim case ARM::STMDB_UPD: 1903226633Sdim Inst.setOpcode(ARM::SRSDB_UPD); 1904226633Sdim break; 1905226633Sdim case ARM::STMIA: 1906226633Sdim Inst.setOpcode(ARM::SRSIA); 1907226633Sdim break; 1908226633Sdim case ARM::STMIA_UPD: 1909226633Sdim Inst.setOpcode(ARM::SRSIA_UPD); 1910226633Sdim break; 1911226633Sdim case ARM::STMIB: 1912226633Sdim Inst.setOpcode(ARM::SRSIB); 1913226633Sdim break; 1914226633Sdim case ARM::STMIB_UPD: 1915226633Sdim Inst.setOpcode(ARM::SRSIB_UPD); 1916226633Sdim break; 1917206124Srdivacky default: 1918263508Sdim return MCDisassembler::Fail; 1919226633Sdim } 1920226633Sdim 1921226633Sdim // For stores (which become SRS's, the only operand is the mode. 1922239462Sdim if (fieldFromInstruction(Insn, 20, 1) == 0) { 1923263508Sdim // Check SRS encoding constraints 1924263508Sdim if (!(fieldFromInstruction(Insn, 22, 1) == 1 && 1925263508Sdim fieldFromInstruction(Insn, 20, 1) == 0)) 1926263508Sdim return MCDisassembler::Fail; 1927263508Sdim 1928226633Sdim Inst.addOperand( 1929239462Sdim MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4))); 1930226633Sdim return S; 1931226633Sdim } 1932226633Sdim 1933226633Sdim return DecodeRFEInstruction(Inst, Insn, Address, Decoder); 1934226633Sdim } 1935226633Sdim 1936226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1937226633Sdim return MCDisassembler::Fail; 1938226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1939226633Sdim return MCDisassembler::Fail; // Tied 1940226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1941226633Sdim return MCDisassembler::Fail; 1942226633Sdim if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder))) 1943226633Sdim return MCDisassembler::Fail; 1944226633Sdim 1945226633Sdim return S; 1946226633Sdim} 1947226633Sdim 1948234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 1949226633Sdim uint64_t Address, const void *Decoder) { 1950239462Sdim unsigned imod = fieldFromInstruction(Insn, 18, 2); 1951239462Sdim unsigned M = fieldFromInstruction(Insn, 17, 1); 1952239462Sdim unsigned iflags = fieldFromInstruction(Insn, 6, 3); 1953239462Sdim unsigned mode = fieldFromInstruction(Insn, 0, 5); 1954226633Sdim 1955226633Sdim DecodeStatus S = MCDisassembler::Success; 1956226633Sdim 1957263508Sdim // This decoder is called from multiple location that do not check 1958263508Sdim // the full encoding is valid before they do. 1959263508Sdim if (fieldFromInstruction(Insn, 5, 1) != 0 || 1960263508Sdim fieldFromInstruction(Insn, 16, 1) != 0 || 1961263508Sdim fieldFromInstruction(Insn, 20, 8) != 0x10) 1962263508Sdim return MCDisassembler::Fail; 1963263508Sdim 1964226633Sdim // imod == '01' --> UNPREDICTABLE 1965226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 1966226633Sdim // return failure here. The '01' imod value is unprintable, so there's 1967226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 1968226633Sdim 1969226633Sdim if (imod == 1) return MCDisassembler::Fail; 1970226633Sdim 1971226633Sdim if (imod && M) { 1972226633Sdim Inst.setOpcode(ARM::CPS3p); 1973226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1974226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1975226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1976226633Sdim } else if (imod && !M) { 1977226633Sdim Inst.setOpcode(ARM::CPS2p); 1978226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 1979226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 1980226633Sdim if (mode) S = MCDisassembler::SoftFail; 1981226633Sdim } else if (!imod && M) { 1982226633Sdim Inst.setOpcode(ARM::CPS1p); 1983226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1984226633Sdim if (iflags) S = MCDisassembler::SoftFail; 1985226633Sdim } else { 1986226633Sdim // imod == '00' && M == '0' --> UNPREDICTABLE 1987226633Sdim Inst.setOpcode(ARM::CPS1p); 1988226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 1989226633Sdim S = MCDisassembler::SoftFail; 1990226633Sdim } 1991226633Sdim 1992226633Sdim return S; 1993226633Sdim} 1994226633Sdim 1995234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 1996226633Sdim uint64_t Address, const void *Decoder) { 1997239462Sdim unsigned imod = fieldFromInstruction(Insn, 9, 2); 1998239462Sdim unsigned M = fieldFromInstruction(Insn, 8, 1); 1999239462Sdim unsigned iflags = fieldFromInstruction(Insn, 5, 3); 2000239462Sdim unsigned mode = fieldFromInstruction(Insn, 0, 5); 2001226633Sdim 2002226633Sdim DecodeStatus S = MCDisassembler::Success; 2003226633Sdim 2004226633Sdim // imod == '01' --> UNPREDICTABLE 2005226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 2006226633Sdim // return failure here. The '01' imod value is unprintable, so there's 2007226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 2008226633Sdim 2009226633Sdim if (imod == 1) return MCDisassembler::Fail; 2010226633Sdim 2011226633Sdim if (imod && M) { 2012226633Sdim Inst.setOpcode(ARM::t2CPS3p); 2013226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 2014226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 2015226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 2016226633Sdim } else if (imod && !M) { 2017226633Sdim Inst.setOpcode(ARM::t2CPS2p); 2018226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 2019226633Sdim Inst.addOperand(MCOperand::CreateImm(iflags)); 2020226633Sdim if (mode) S = MCDisassembler::SoftFail; 2021226633Sdim } else if (!imod && M) { 2022226633Sdim Inst.setOpcode(ARM::t2CPS1p); 2023226633Sdim Inst.addOperand(MCOperand::CreateImm(mode)); 2024226633Sdim if (iflags) S = MCDisassembler::SoftFail; 2025226633Sdim } else { 2026251662Sdim // imod == '00' && M == '0' --> this is a HINT instruction 2027251662Sdim int imm = fieldFromInstruction(Insn, 0, 8); 2028251662Sdim // HINT are defined only for immediate in [0..4] 2029251662Sdim if(imm > 4) return MCDisassembler::Fail; 2030251662Sdim Inst.setOpcode(ARM::t2HINT); 2031251662Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2032226633Sdim } 2033226633Sdim 2034226633Sdim return S; 2035226633Sdim} 2036226633Sdim 2037234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 2038226633Sdim uint64_t Address, const void *Decoder) { 2039226633Sdim DecodeStatus S = MCDisassembler::Success; 2040226633Sdim 2041239462Sdim unsigned Rd = fieldFromInstruction(Insn, 8, 4); 2042226633Sdim unsigned imm = 0; 2043226633Sdim 2044239462Sdim imm |= (fieldFromInstruction(Insn, 0, 8) << 0); 2045239462Sdim imm |= (fieldFromInstruction(Insn, 12, 3) << 8); 2046239462Sdim imm |= (fieldFromInstruction(Insn, 16, 4) << 12); 2047239462Sdim imm |= (fieldFromInstruction(Insn, 26, 1) << 11); 2048226633Sdim 2049226633Sdim if (Inst.getOpcode() == ARM::t2MOVTi16) 2050226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 2051226633Sdim return MCDisassembler::Fail; 2052226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 2053226633Sdim return MCDisassembler::Fail; 2054226633Sdim 2055226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 2056226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2057226633Sdim 2058226633Sdim return S; 2059226633Sdim} 2060226633Sdim 2061234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 2062226633Sdim uint64_t Address, const void *Decoder) { 2063226633Sdim DecodeStatus S = MCDisassembler::Success; 2064226633Sdim 2065239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2066239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2067226633Sdim unsigned imm = 0; 2068226633Sdim 2069239462Sdim imm |= (fieldFromInstruction(Insn, 0, 12) << 0); 2070239462Sdim imm |= (fieldFromInstruction(Insn, 16, 4) << 12); 2071226633Sdim 2072226633Sdim if (Inst.getOpcode() == ARM::MOVTi16) 2073251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2074226633Sdim return MCDisassembler::Fail; 2075251662Sdim 2076251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2077226633Sdim return MCDisassembler::Fail; 2078226633Sdim 2079226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 2080226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2081226633Sdim 2082226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2083226633Sdim return MCDisassembler::Fail; 2084226633Sdim 2085226633Sdim return S; 2086226633Sdim} 2087226633Sdim 2088234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 2089226633Sdim uint64_t Address, const void *Decoder) { 2090226633Sdim DecodeStatus S = MCDisassembler::Success; 2091226633Sdim 2092239462Sdim unsigned Rd = fieldFromInstruction(Insn, 16, 4); 2093239462Sdim unsigned Rn = fieldFromInstruction(Insn, 0, 4); 2094239462Sdim unsigned Rm = fieldFromInstruction(Insn, 8, 4); 2095239462Sdim unsigned Ra = fieldFromInstruction(Insn, 12, 4); 2096239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2097226633Sdim 2098226633Sdim if (pred == 0xF) 2099226633Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 2100226633Sdim 2101226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2102226633Sdim return MCDisassembler::Fail; 2103226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 2104226633Sdim return MCDisassembler::Fail; 2105226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 2106226633Sdim return MCDisassembler::Fail; 2107226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder))) 2108226633Sdim return MCDisassembler::Fail; 2109226633Sdim 2110226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2111226633Sdim return MCDisassembler::Fail; 2112226633Sdim 2113226633Sdim return S; 2114226633Sdim} 2115226633Sdim 2116234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 2117226633Sdim uint64_t Address, const void *Decoder) { 2118226633Sdim DecodeStatus S = MCDisassembler::Success; 2119226633Sdim 2120239462Sdim unsigned add = fieldFromInstruction(Val, 12, 1); 2121239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 12); 2122239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 2123226633Sdim 2124226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2125226633Sdim return MCDisassembler::Fail; 2126226633Sdim 2127226633Sdim if (!add) imm *= -1; 2128226633Sdim if (imm == 0 && !add) imm = INT32_MIN; 2129226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 2130226633Sdim if (Rn == 15) 2131226633Sdim tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder); 2132226633Sdim 2133226633Sdim return S; 2134226633Sdim} 2135226633Sdim 2136234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 2137226633Sdim uint64_t Address, const void *Decoder) { 2138226633Sdim DecodeStatus S = MCDisassembler::Success; 2139226633Sdim 2140239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 2141239462Sdim unsigned U = fieldFromInstruction(Val, 8, 1); 2142239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 2143226633Sdim 2144226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2145226633Sdim return MCDisassembler::Fail; 2146226633Sdim 2147226633Sdim if (U) 2148226633Sdim Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm))); 2149226633Sdim else 2150226633Sdim Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm))); 2151226633Sdim 2152226633Sdim return S; 2153226633Sdim} 2154226633Sdim 2155234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 2156226633Sdim uint64_t Address, const void *Decoder) { 2157226633Sdim return DecodeGPRRegisterClass(Inst, Val, Address, Decoder); 2158226633Sdim} 2159226633Sdim 2160226633Sdimstatic DecodeStatus 2161234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn, 2162234353Sdim uint64_t Address, const void *Decoder) { 2163243830Sdim DecodeStatus Status = MCDisassembler::Success; 2164243830Sdim 2165243830Sdim // Note the J1 and J2 values are from the encoded instruction. So here 2166243830Sdim // change them to I1 and I2 values via as documented: 2167243830Sdim // I1 = NOT(J1 EOR S); 2168243830Sdim // I2 = NOT(J2 EOR S); 2169243830Sdim // and build the imm32 with one trailing zero as documented: 2170243830Sdim // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); 2171243830Sdim unsigned S = fieldFromInstruction(Insn, 26, 1); 2172243830Sdim unsigned J1 = fieldFromInstruction(Insn, 13, 1); 2173243830Sdim unsigned J2 = fieldFromInstruction(Insn, 11, 1); 2174243830Sdim unsigned I1 = !(J1 ^ S); 2175243830Sdim unsigned I2 = !(J2 ^ S); 2176243830Sdim unsigned imm10 = fieldFromInstruction(Insn, 16, 10); 2177243830Sdim unsigned imm11 = fieldFromInstruction(Insn, 0, 11); 2178243830Sdim unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11; 2179263508Sdim int imm32 = SignExtend32<25>(tmp << 1); 2180243830Sdim if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, 2181234353Sdim true, 4, Inst, Decoder)) 2182243830Sdim Inst.addOperand(MCOperand::CreateImm(imm32)); 2183243830Sdim 2184243830Sdim return Status; 2185234353Sdim} 2186234353Sdim 2187234353Sdimstatic DecodeStatus 2188234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn, 2189226633Sdim uint64_t Address, const void *Decoder) { 2190226633Sdim DecodeStatus S = MCDisassembler::Success; 2191226633Sdim 2192239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2193239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2; 2194226633Sdim 2195226633Sdim if (pred == 0xF) { 2196226633Sdim Inst.setOpcode(ARM::BLXi); 2197239462Sdim imm |= fieldFromInstruction(Insn, 24, 1) << 1; 2198234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2199234353Sdim true, 4, Inst, Decoder)) 2200226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); 2201226633Sdim return S; 2202226633Sdim } 2203226633Sdim 2204234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2205234353Sdim true, 4, Inst, Decoder)) 2206226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); 2207226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2208226633Sdim return MCDisassembler::Fail; 2209226633Sdim 2210226633Sdim return S; 2211226633Sdim} 2212226633Sdim 2213226633Sdim 2214234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 2215226633Sdim uint64_t Address, const void *Decoder) { 2216226633Sdim DecodeStatus S = MCDisassembler::Success; 2217226633Sdim 2218239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 2219239462Sdim unsigned align = fieldFromInstruction(Val, 4, 2); 2220226633Sdim 2221226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2222226633Sdim return MCDisassembler::Fail; 2223226633Sdim if (!align) 2224226633Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2225226633Sdim else 2226226633Sdim Inst.addOperand(MCOperand::CreateImm(4 << align)); 2227226633Sdim 2228226633Sdim return S; 2229226633Sdim} 2230226633Sdim 2231234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn, 2232226633Sdim uint64_t Address, const void *Decoder) { 2233226633Sdim DecodeStatus S = MCDisassembler::Success; 2234226633Sdim 2235239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2236239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2237239462Sdim unsigned wb = fieldFromInstruction(Insn, 16, 4); 2238239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2239239462Sdim Rn |= fieldFromInstruction(Insn, 4, 2) << 4; 2240239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2241226633Sdim 2242226633Sdim // First output register 2243234353Sdim switch (Inst.getOpcode()) { 2244234353Sdim case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8: 2245234353Sdim case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register: 2246234353Sdim case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register: 2247234353Sdim case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register: 2248234353Sdim case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register: 2249234353Sdim case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8: 2250234353Sdim case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register: 2251234353Sdim case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register: 2252234353Sdim case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register: 2253234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2254234353Sdim return MCDisassembler::Fail; 2255234353Sdim break; 2256234353Sdim case ARM::VLD2b16: 2257234353Sdim case ARM::VLD2b32: 2258234353Sdim case ARM::VLD2b8: 2259234353Sdim case ARM::VLD2b16wb_fixed: 2260234353Sdim case ARM::VLD2b16wb_register: 2261234353Sdim case ARM::VLD2b32wb_fixed: 2262234353Sdim case ARM::VLD2b32wb_register: 2263234353Sdim case ARM::VLD2b8wb_fixed: 2264234353Sdim case ARM::VLD2b8wb_register: 2265234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2266234353Sdim return MCDisassembler::Fail; 2267234353Sdim break; 2268234353Sdim default: 2269234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2270234353Sdim return MCDisassembler::Fail; 2271234353Sdim } 2272226633Sdim 2273226633Sdim // Second output register 2274226633Sdim switch (Inst.getOpcode()) { 2275226633Sdim case ARM::VLD3d8: 2276226633Sdim case ARM::VLD3d16: 2277226633Sdim case ARM::VLD3d32: 2278226633Sdim case ARM::VLD3d8_UPD: 2279226633Sdim case ARM::VLD3d16_UPD: 2280226633Sdim case ARM::VLD3d32_UPD: 2281226633Sdim case ARM::VLD4d8: 2282226633Sdim case ARM::VLD4d16: 2283226633Sdim case ARM::VLD4d32: 2284226633Sdim case ARM::VLD4d8_UPD: 2285226633Sdim case ARM::VLD4d16_UPD: 2286226633Sdim case ARM::VLD4d32_UPD: 2287226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2288226633Sdim return MCDisassembler::Fail; 2289206124Srdivacky break; 2290226633Sdim case ARM::VLD3q8: 2291226633Sdim case ARM::VLD3q16: 2292226633Sdim case ARM::VLD3q32: 2293226633Sdim case ARM::VLD3q8_UPD: 2294226633Sdim case ARM::VLD3q16_UPD: 2295226633Sdim case ARM::VLD3q32_UPD: 2296226633Sdim case ARM::VLD4q8: 2297226633Sdim case ARM::VLD4q16: 2298226633Sdim case ARM::VLD4q32: 2299226633Sdim case ARM::VLD4q8_UPD: 2300226633Sdim case ARM::VLD4q16_UPD: 2301226633Sdim case ARM::VLD4q32_UPD: 2302226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2303226633Sdim return MCDisassembler::Fail; 2304206124Srdivacky default: 2305226633Sdim break; 2306226633Sdim } 2307226633Sdim 2308226633Sdim // Third output register 2309226633Sdim switch(Inst.getOpcode()) { 2310226633Sdim case ARM::VLD3d8: 2311226633Sdim case ARM::VLD3d16: 2312226633Sdim case ARM::VLD3d32: 2313226633Sdim case ARM::VLD3d8_UPD: 2314226633Sdim case ARM::VLD3d16_UPD: 2315226633Sdim case ARM::VLD3d32_UPD: 2316226633Sdim case ARM::VLD4d8: 2317226633Sdim case ARM::VLD4d16: 2318226633Sdim case ARM::VLD4d32: 2319226633Sdim case ARM::VLD4d8_UPD: 2320226633Sdim case ARM::VLD4d16_UPD: 2321226633Sdim case ARM::VLD4d32_UPD: 2322226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2323226633Sdim return MCDisassembler::Fail; 2324226633Sdim break; 2325226633Sdim case ARM::VLD3q8: 2326226633Sdim case ARM::VLD3q16: 2327226633Sdim case ARM::VLD3q32: 2328226633Sdim case ARM::VLD3q8_UPD: 2329226633Sdim case ARM::VLD3q16_UPD: 2330226633Sdim case ARM::VLD3q32_UPD: 2331226633Sdim case ARM::VLD4q8: 2332226633Sdim case ARM::VLD4q16: 2333226633Sdim case ARM::VLD4q32: 2334226633Sdim case ARM::VLD4q8_UPD: 2335226633Sdim case ARM::VLD4q16_UPD: 2336226633Sdim case ARM::VLD4q32_UPD: 2337226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2338226633Sdim return MCDisassembler::Fail; 2339226633Sdim break; 2340226633Sdim default: 2341226633Sdim break; 2342226633Sdim } 2343226633Sdim 2344226633Sdim // Fourth output register 2345226633Sdim switch (Inst.getOpcode()) { 2346226633Sdim case ARM::VLD4d8: 2347226633Sdim case ARM::VLD4d16: 2348226633Sdim case ARM::VLD4d32: 2349226633Sdim case ARM::VLD4d8_UPD: 2350226633Sdim case ARM::VLD4d16_UPD: 2351226633Sdim case ARM::VLD4d32_UPD: 2352226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 2353226633Sdim return MCDisassembler::Fail; 2354226633Sdim break; 2355226633Sdim case ARM::VLD4q8: 2356226633Sdim case ARM::VLD4q16: 2357226633Sdim case ARM::VLD4q32: 2358226633Sdim case ARM::VLD4q8_UPD: 2359226633Sdim case ARM::VLD4q16_UPD: 2360226633Sdim case ARM::VLD4q32_UPD: 2361226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2362226633Sdim return MCDisassembler::Fail; 2363226633Sdim break; 2364226633Sdim default: 2365226633Sdim break; 2366226633Sdim } 2367226633Sdim 2368226633Sdim // Writeback operand 2369226633Sdim switch (Inst.getOpcode()) { 2370234353Sdim case ARM::VLD1d8wb_fixed: 2371234353Sdim case ARM::VLD1d16wb_fixed: 2372234353Sdim case ARM::VLD1d32wb_fixed: 2373234353Sdim case ARM::VLD1d64wb_fixed: 2374234353Sdim case ARM::VLD1d8wb_register: 2375234353Sdim case ARM::VLD1d16wb_register: 2376234353Sdim case ARM::VLD1d32wb_register: 2377234353Sdim case ARM::VLD1d64wb_register: 2378234353Sdim case ARM::VLD1q8wb_fixed: 2379234353Sdim case ARM::VLD1q16wb_fixed: 2380234353Sdim case ARM::VLD1q32wb_fixed: 2381234353Sdim case ARM::VLD1q64wb_fixed: 2382234353Sdim case ARM::VLD1q8wb_register: 2383234353Sdim case ARM::VLD1q16wb_register: 2384234353Sdim case ARM::VLD1q32wb_register: 2385234353Sdim case ARM::VLD1q64wb_register: 2386234353Sdim case ARM::VLD1d8Twb_fixed: 2387234353Sdim case ARM::VLD1d8Twb_register: 2388234353Sdim case ARM::VLD1d16Twb_fixed: 2389234353Sdim case ARM::VLD1d16Twb_register: 2390234353Sdim case ARM::VLD1d32Twb_fixed: 2391234353Sdim case ARM::VLD1d32Twb_register: 2392234353Sdim case ARM::VLD1d64Twb_fixed: 2393234353Sdim case ARM::VLD1d64Twb_register: 2394234353Sdim case ARM::VLD1d8Qwb_fixed: 2395234353Sdim case ARM::VLD1d8Qwb_register: 2396234353Sdim case ARM::VLD1d16Qwb_fixed: 2397234353Sdim case ARM::VLD1d16Qwb_register: 2398234353Sdim case ARM::VLD1d32Qwb_fixed: 2399234353Sdim case ARM::VLD1d32Qwb_register: 2400234353Sdim case ARM::VLD1d64Qwb_fixed: 2401234353Sdim case ARM::VLD1d64Qwb_register: 2402234353Sdim case ARM::VLD2d8wb_fixed: 2403234353Sdim case ARM::VLD2d16wb_fixed: 2404234353Sdim case ARM::VLD2d32wb_fixed: 2405234353Sdim case ARM::VLD2q8wb_fixed: 2406234353Sdim case ARM::VLD2q16wb_fixed: 2407234353Sdim case ARM::VLD2q32wb_fixed: 2408234353Sdim case ARM::VLD2d8wb_register: 2409234353Sdim case ARM::VLD2d16wb_register: 2410234353Sdim case ARM::VLD2d32wb_register: 2411234353Sdim case ARM::VLD2q8wb_register: 2412234353Sdim case ARM::VLD2q16wb_register: 2413234353Sdim case ARM::VLD2q32wb_register: 2414234353Sdim case ARM::VLD2b8wb_fixed: 2415234353Sdim case ARM::VLD2b16wb_fixed: 2416234353Sdim case ARM::VLD2b32wb_fixed: 2417234353Sdim case ARM::VLD2b8wb_register: 2418234353Sdim case ARM::VLD2b16wb_register: 2419234353Sdim case ARM::VLD2b32wb_register: 2420234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2421234353Sdim break; 2422226633Sdim case ARM::VLD3d8_UPD: 2423226633Sdim case ARM::VLD3d16_UPD: 2424226633Sdim case ARM::VLD3d32_UPD: 2425226633Sdim case ARM::VLD3q8_UPD: 2426226633Sdim case ARM::VLD3q16_UPD: 2427226633Sdim case ARM::VLD3q32_UPD: 2428226633Sdim case ARM::VLD4d8_UPD: 2429226633Sdim case ARM::VLD4d16_UPD: 2430226633Sdim case ARM::VLD4d32_UPD: 2431226633Sdim case ARM::VLD4q8_UPD: 2432226633Sdim case ARM::VLD4q16_UPD: 2433226633Sdim case ARM::VLD4q32_UPD: 2434226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2435226633Sdim return MCDisassembler::Fail; 2436226633Sdim break; 2437226633Sdim default: 2438226633Sdim break; 2439226633Sdim } 2440226633Sdim 2441226633Sdim // AddrMode6 Base (register+alignment) 2442226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2443226633Sdim return MCDisassembler::Fail; 2444226633Sdim 2445226633Sdim // AddrMode6 Offset (register) 2446234353Sdim switch (Inst.getOpcode()) { 2447234353Sdim default: 2448234353Sdim // The below have been updated to have explicit am6offset split 2449234353Sdim // between fixed and register offset. For those instructions not 2450234353Sdim // yet updated, we need to add an additional reg0 operand for the 2451234353Sdim // fixed variant. 2452234353Sdim // 2453234353Sdim // The fixed offset encodes as Rm == 0xd, so we check for that. 2454234353Sdim if (Rm == 0xd) { 2455234353Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2456234353Sdim break; 2457234353Sdim } 2458234353Sdim // Fall through to handle the register offset variant. 2459234353Sdim case ARM::VLD1d8wb_fixed: 2460234353Sdim case ARM::VLD1d16wb_fixed: 2461234353Sdim case ARM::VLD1d32wb_fixed: 2462234353Sdim case ARM::VLD1d64wb_fixed: 2463234353Sdim case ARM::VLD1d8Twb_fixed: 2464234353Sdim case ARM::VLD1d16Twb_fixed: 2465234353Sdim case ARM::VLD1d32Twb_fixed: 2466234353Sdim case ARM::VLD1d64Twb_fixed: 2467234353Sdim case ARM::VLD1d8Qwb_fixed: 2468234353Sdim case ARM::VLD1d16Qwb_fixed: 2469234353Sdim case ARM::VLD1d32Qwb_fixed: 2470234353Sdim case ARM::VLD1d64Qwb_fixed: 2471234353Sdim case ARM::VLD1d8wb_register: 2472234353Sdim case ARM::VLD1d16wb_register: 2473234353Sdim case ARM::VLD1d32wb_register: 2474234353Sdim case ARM::VLD1d64wb_register: 2475234353Sdim case ARM::VLD1q8wb_fixed: 2476234353Sdim case ARM::VLD1q16wb_fixed: 2477234353Sdim case ARM::VLD1q32wb_fixed: 2478234353Sdim case ARM::VLD1q64wb_fixed: 2479234353Sdim case ARM::VLD1q8wb_register: 2480234353Sdim case ARM::VLD1q16wb_register: 2481234353Sdim case ARM::VLD1q32wb_register: 2482234353Sdim case ARM::VLD1q64wb_register: 2483234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2484234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2485234353Sdim // increment and we need to add the register operand to the instruction. 2486234353Sdim if (Rm != 0xD && Rm != 0xF && 2487234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2488226633Sdim return MCDisassembler::Fail; 2489234353Sdim break; 2490234353Sdim case ARM::VLD2d8wb_fixed: 2491234353Sdim case ARM::VLD2d16wb_fixed: 2492234353Sdim case ARM::VLD2d32wb_fixed: 2493234353Sdim case ARM::VLD2b8wb_fixed: 2494234353Sdim case ARM::VLD2b16wb_fixed: 2495234353Sdim case ARM::VLD2b32wb_fixed: 2496234353Sdim case ARM::VLD2q8wb_fixed: 2497234353Sdim case ARM::VLD2q16wb_fixed: 2498234353Sdim case ARM::VLD2q32wb_fixed: 2499234353Sdim break; 2500226633Sdim } 2501226633Sdim 2502226633Sdim return S; 2503226633Sdim} 2504226633Sdim 2505263508Sdimstatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn, 2506263508Sdim uint64_t Address, const void *Decoder) { 2507263508Sdim unsigned type = fieldFromInstruction(Insn, 8, 4); 2508263508Sdim unsigned align = fieldFromInstruction(Insn, 4, 2); 2509263508Sdim if (type == 6 && (align & 2)) return MCDisassembler::Fail; 2510263508Sdim if (type == 7 && (align & 2)) return MCDisassembler::Fail; 2511263508Sdim if (type == 10 && align == 3) return MCDisassembler::Fail; 2512263508Sdim 2513263508Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2514263508Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2515263508Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2516263508Sdim} 2517263508Sdim 2518263508Sdimstatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn, 2519263508Sdim uint64_t Address, const void *Decoder) { 2520263508Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2521263508Sdim if (size == 3) return MCDisassembler::Fail; 2522263508Sdim 2523263508Sdim unsigned type = fieldFromInstruction(Insn, 8, 4); 2524263508Sdim unsigned align = fieldFromInstruction(Insn, 4, 2); 2525263508Sdim if (type == 8 && align == 3) return MCDisassembler::Fail; 2526263508Sdim if (type == 9 && align == 3) return MCDisassembler::Fail; 2527263508Sdim 2528263508Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2529263508Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2530263508Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2531263508Sdim} 2532263508Sdim 2533263508Sdimstatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn, 2534263508Sdim uint64_t Address, const void *Decoder) { 2535263508Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2536263508Sdim if (size == 3) return MCDisassembler::Fail; 2537263508Sdim 2538263508Sdim unsigned align = fieldFromInstruction(Insn, 4, 2); 2539263508Sdim if (align & 2) return MCDisassembler::Fail; 2540263508Sdim 2541263508Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2542263508Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2543263508Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2544263508Sdim} 2545263508Sdim 2546263508Sdimstatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn, 2547263508Sdim uint64_t Address, const void *Decoder) { 2548263508Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2549263508Sdim if (size == 3) return MCDisassembler::Fail; 2550263508Sdim 2551263508Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2552263508Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2553263508Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2554263508Sdim} 2555263508Sdim 2556234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn, 2557226633Sdim uint64_t Address, const void *Decoder) { 2558226633Sdim DecodeStatus S = MCDisassembler::Success; 2559226633Sdim 2560239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2561239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2562239462Sdim unsigned wb = fieldFromInstruction(Insn, 16, 4); 2563239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2564239462Sdim Rn |= fieldFromInstruction(Insn, 4, 2) << 4; 2565239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2566226633Sdim 2567226633Sdim // Writeback Operand 2568226633Sdim switch (Inst.getOpcode()) { 2569234353Sdim case ARM::VST1d8wb_fixed: 2570234353Sdim case ARM::VST1d16wb_fixed: 2571234353Sdim case ARM::VST1d32wb_fixed: 2572234353Sdim case ARM::VST1d64wb_fixed: 2573234353Sdim case ARM::VST1d8wb_register: 2574234353Sdim case ARM::VST1d16wb_register: 2575234353Sdim case ARM::VST1d32wb_register: 2576234353Sdim case ARM::VST1d64wb_register: 2577234353Sdim case ARM::VST1q8wb_fixed: 2578234353Sdim case ARM::VST1q16wb_fixed: 2579234353Sdim case ARM::VST1q32wb_fixed: 2580234353Sdim case ARM::VST1q64wb_fixed: 2581234353Sdim case ARM::VST1q8wb_register: 2582234353Sdim case ARM::VST1q16wb_register: 2583234353Sdim case ARM::VST1q32wb_register: 2584234353Sdim case ARM::VST1q64wb_register: 2585234353Sdim case ARM::VST1d8Twb_fixed: 2586234353Sdim case ARM::VST1d16Twb_fixed: 2587234353Sdim case ARM::VST1d32Twb_fixed: 2588234353Sdim case ARM::VST1d64Twb_fixed: 2589234353Sdim case ARM::VST1d8Twb_register: 2590234353Sdim case ARM::VST1d16Twb_register: 2591234353Sdim case ARM::VST1d32Twb_register: 2592234353Sdim case ARM::VST1d64Twb_register: 2593234353Sdim case ARM::VST1d8Qwb_fixed: 2594234353Sdim case ARM::VST1d16Qwb_fixed: 2595234353Sdim case ARM::VST1d32Qwb_fixed: 2596234353Sdim case ARM::VST1d64Qwb_fixed: 2597234353Sdim case ARM::VST1d8Qwb_register: 2598234353Sdim case ARM::VST1d16Qwb_register: 2599234353Sdim case ARM::VST1d32Qwb_register: 2600234353Sdim case ARM::VST1d64Qwb_register: 2601234353Sdim case ARM::VST2d8wb_fixed: 2602234353Sdim case ARM::VST2d16wb_fixed: 2603234353Sdim case ARM::VST2d32wb_fixed: 2604234353Sdim case ARM::VST2d8wb_register: 2605234353Sdim case ARM::VST2d16wb_register: 2606234353Sdim case ARM::VST2d32wb_register: 2607234353Sdim case ARM::VST2q8wb_fixed: 2608234353Sdim case ARM::VST2q16wb_fixed: 2609234353Sdim case ARM::VST2q32wb_fixed: 2610234353Sdim case ARM::VST2q8wb_register: 2611234353Sdim case ARM::VST2q16wb_register: 2612234353Sdim case ARM::VST2q32wb_register: 2613234353Sdim case ARM::VST2b8wb_fixed: 2614234353Sdim case ARM::VST2b16wb_fixed: 2615234353Sdim case ARM::VST2b32wb_fixed: 2616234353Sdim case ARM::VST2b8wb_register: 2617234353Sdim case ARM::VST2b16wb_register: 2618234353Sdim case ARM::VST2b32wb_register: 2619234353Sdim if (Rm == 0xF) 2620234353Sdim return MCDisassembler::Fail; 2621234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2622234353Sdim break; 2623226633Sdim case ARM::VST3d8_UPD: 2624226633Sdim case ARM::VST3d16_UPD: 2625226633Sdim case ARM::VST3d32_UPD: 2626226633Sdim case ARM::VST3q8_UPD: 2627226633Sdim case ARM::VST3q16_UPD: 2628226633Sdim case ARM::VST3q32_UPD: 2629226633Sdim case ARM::VST4d8_UPD: 2630226633Sdim case ARM::VST4d16_UPD: 2631226633Sdim case ARM::VST4d32_UPD: 2632226633Sdim case ARM::VST4q8_UPD: 2633226633Sdim case ARM::VST4q16_UPD: 2634226633Sdim case ARM::VST4q32_UPD: 2635226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2636226633Sdim return MCDisassembler::Fail; 2637226633Sdim break; 2638226633Sdim default: 2639226633Sdim break; 2640226633Sdim } 2641226633Sdim 2642226633Sdim // AddrMode6 Base (register+alignment) 2643226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2644226633Sdim return MCDisassembler::Fail; 2645226633Sdim 2646226633Sdim // AddrMode6 Offset (register) 2647234353Sdim switch (Inst.getOpcode()) { 2648234353Sdim default: 2649234353Sdim if (Rm == 0xD) 2650234353Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2651234353Sdim else if (Rm != 0xF) { 2652234353Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2653234353Sdim return MCDisassembler::Fail; 2654234353Sdim } 2655234353Sdim break; 2656234353Sdim case ARM::VST1d8wb_fixed: 2657234353Sdim case ARM::VST1d16wb_fixed: 2658234353Sdim case ARM::VST1d32wb_fixed: 2659234353Sdim case ARM::VST1d64wb_fixed: 2660234353Sdim case ARM::VST1q8wb_fixed: 2661234353Sdim case ARM::VST1q16wb_fixed: 2662234353Sdim case ARM::VST1q32wb_fixed: 2663234353Sdim case ARM::VST1q64wb_fixed: 2664234353Sdim case ARM::VST1d8Twb_fixed: 2665234353Sdim case ARM::VST1d16Twb_fixed: 2666234353Sdim case ARM::VST1d32Twb_fixed: 2667234353Sdim case ARM::VST1d64Twb_fixed: 2668234353Sdim case ARM::VST1d8Qwb_fixed: 2669234353Sdim case ARM::VST1d16Qwb_fixed: 2670234353Sdim case ARM::VST1d32Qwb_fixed: 2671234353Sdim case ARM::VST1d64Qwb_fixed: 2672234353Sdim case ARM::VST2d8wb_fixed: 2673234353Sdim case ARM::VST2d16wb_fixed: 2674234353Sdim case ARM::VST2d32wb_fixed: 2675234353Sdim case ARM::VST2q8wb_fixed: 2676234353Sdim case ARM::VST2q16wb_fixed: 2677234353Sdim case ARM::VST2q32wb_fixed: 2678234353Sdim case ARM::VST2b8wb_fixed: 2679234353Sdim case ARM::VST2b16wb_fixed: 2680234353Sdim case ARM::VST2b32wb_fixed: 2681234353Sdim break; 2682226633Sdim } 2683226633Sdim 2684234353Sdim 2685226633Sdim // First input register 2686234353Sdim switch (Inst.getOpcode()) { 2687234353Sdim case ARM::VST1q16: 2688234353Sdim case ARM::VST1q32: 2689234353Sdim case ARM::VST1q64: 2690234353Sdim case ARM::VST1q8: 2691234353Sdim case ARM::VST1q16wb_fixed: 2692234353Sdim case ARM::VST1q16wb_register: 2693234353Sdim case ARM::VST1q32wb_fixed: 2694234353Sdim case ARM::VST1q32wb_register: 2695234353Sdim case ARM::VST1q64wb_fixed: 2696234353Sdim case ARM::VST1q64wb_register: 2697234353Sdim case ARM::VST1q8wb_fixed: 2698234353Sdim case ARM::VST1q8wb_register: 2699234353Sdim case ARM::VST2d16: 2700234353Sdim case ARM::VST2d32: 2701234353Sdim case ARM::VST2d8: 2702234353Sdim case ARM::VST2d16wb_fixed: 2703234353Sdim case ARM::VST2d16wb_register: 2704234353Sdim case ARM::VST2d32wb_fixed: 2705234353Sdim case ARM::VST2d32wb_register: 2706234353Sdim case ARM::VST2d8wb_fixed: 2707234353Sdim case ARM::VST2d8wb_register: 2708234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2709234353Sdim return MCDisassembler::Fail; 2710234353Sdim break; 2711234353Sdim case ARM::VST2b16: 2712234353Sdim case ARM::VST2b32: 2713234353Sdim case ARM::VST2b8: 2714234353Sdim case ARM::VST2b16wb_fixed: 2715234353Sdim case ARM::VST2b16wb_register: 2716234353Sdim case ARM::VST2b32wb_fixed: 2717234353Sdim case ARM::VST2b32wb_register: 2718234353Sdim case ARM::VST2b8wb_fixed: 2719234353Sdim case ARM::VST2b8wb_register: 2720234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2721234353Sdim return MCDisassembler::Fail; 2722234353Sdim break; 2723234353Sdim default: 2724234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2725234353Sdim return MCDisassembler::Fail; 2726234353Sdim } 2727226633Sdim 2728226633Sdim // Second input register 2729226633Sdim switch (Inst.getOpcode()) { 2730226633Sdim case ARM::VST3d8: 2731226633Sdim case ARM::VST3d16: 2732226633Sdim case ARM::VST3d32: 2733226633Sdim case ARM::VST3d8_UPD: 2734226633Sdim case ARM::VST3d16_UPD: 2735226633Sdim case ARM::VST3d32_UPD: 2736226633Sdim case ARM::VST4d8: 2737226633Sdim case ARM::VST4d16: 2738226633Sdim case ARM::VST4d32: 2739226633Sdim case ARM::VST4d8_UPD: 2740226633Sdim case ARM::VST4d16_UPD: 2741226633Sdim case ARM::VST4d32_UPD: 2742226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2743226633Sdim return MCDisassembler::Fail; 2744226633Sdim break; 2745226633Sdim case ARM::VST3q8: 2746226633Sdim case ARM::VST3q16: 2747226633Sdim case ARM::VST3q32: 2748226633Sdim case ARM::VST3q8_UPD: 2749226633Sdim case ARM::VST3q16_UPD: 2750226633Sdim case ARM::VST3q32_UPD: 2751226633Sdim case ARM::VST4q8: 2752226633Sdim case ARM::VST4q16: 2753226633Sdim case ARM::VST4q32: 2754226633Sdim case ARM::VST4q8_UPD: 2755226633Sdim case ARM::VST4q16_UPD: 2756226633Sdim case ARM::VST4q32_UPD: 2757226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2758226633Sdim return MCDisassembler::Fail; 2759226633Sdim break; 2760226633Sdim default: 2761226633Sdim break; 2762226633Sdim } 2763226633Sdim 2764226633Sdim // Third input register 2765226633Sdim switch (Inst.getOpcode()) { 2766226633Sdim case ARM::VST3d8: 2767226633Sdim case ARM::VST3d16: 2768226633Sdim case ARM::VST3d32: 2769226633Sdim case ARM::VST3d8_UPD: 2770226633Sdim case ARM::VST3d16_UPD: 2771226633Sdim case ARM::VST3d32_UPD: 2772226633Sdim case ARM::VST4d8: 2773226633Sdim case ARM::VST4d16: 2774226633Sdim case ARM::VST4d32: 2775226633Sdim case ARM::VST4d8_UPD: 2776226633Sdim case ARM::VST4d16_UPD: 2777226633Sdim case ARM::VST4d32_UPD: 2778226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2779226633Sdim return MCDisassembler::Fail; 2780226633Sdim break; 2781226633Sdim case ARM::VST3q8: 2782226633Sdim case ARM::VST3q16: 2783226633Sdim case ARM::VST3q32: 2784226633Sdim case ARM::VST3q8_UPD: 2785226633Sdim case ARM::VST3q16_UPD: 2786226633Sdim case ARM::VST3q32_UPD: 2787226633Sdim case ARM::VST4q8: 2788226633Sdim case ARM::VST4q16: 2789226633Sdim case ARM::VST4q32: 2790226633Sdim case ARM::VST4q8_UPD: 2791226633Sdim case ARM::VST4q16_UPD: 2792226633Sdim case ARM::VST4q32_UPD: 2793226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2794226633Sdim return MCDisassembler::Fail; 2795226633Sdim break; 2796226633Sdim default: 2797226633Sdim break; 2798226633Sdim } 2799226633Sdim 2800226633Sdim // Fourth input register 2801226633Sdim switch (Inst.getOpcode()) { 2802226633Sdim case ARM::VST4d8: 2803226633Sdim case ARM::VST4d16: 2804226633Sdim case ARM::VST4d32: 2805226633Sdim case ARM::VST4d8_UPD: 2806226633Sdim case ARM::VST4d16_UPD: 2807226633Sdim case ARM::VST4d32_UPD: 2808226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 2809226633Sdim return MCDisassembler::Fail; 2810226633Sdim break; 2811226633Sdim case ARM::VST4q8: 2812226633Sdim case ARM::VST4q16: 2813226633Sdim case ARM::VST4q32: 2814226633Sdim case ARM::VST4q8_UPD: 2815226633Sdim case ARM::VST4q16_UPD: 2816226633Sdim case ARM::VST4q32_UPD: 2817226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2818226633Sdim return MCDisassembler::Fail; 2819226633Sdim break; 2820226633Sdim default: 2821226633Sdim break; 2822226633Sdim } 2823226633Sdim 2824226633Sdim return S; 2825226633Sdim} 2826226633Sdim 2827234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn, 2828226633Sdim uint64_t Address, const void *Decoder) { 2829226633Sdim DecodeStatus S = MCDisassembler::Success; 2830226633Sdim 2831239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2832239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2833239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2834239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2835239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 2836239462Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2837226633Sdim 2838243830Sdim if (size == 0 && align == 1) 2839243830Sdim return MCDisassembler::Fail; 2840226633Sdim align *= (1 << size); 2841226633Sdim 2842234353Sdim switch (Inst.getOpcode()) { 2843234353Sdim case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8: 2844234353Sdim case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register: 2845234353Sdim case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register: 2846234353Sdim case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register: 2847234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2848226633Sdim return MCDisassembler::Fail; 2849234353Sdim break; 2850234353Sdim default: 2851234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2852234353Sdim return MCDisassembler::Fail; 2853234353Sdim break; 2854226633Sdim } 2855226633Sdim if (Rm != 0xF) { 2856226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2857226633Sdim return MCDisassembler::Fail; 2858226633Sdim } 2859226633Sdim 2860226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2861226633Sdim return MCDisassembler::Fail; 2862226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2863226633Sdim 2864234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2865234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2866234353Sdim // increment and we need to add the register operand to the instruction. 2867234353Sdim if (Rm != 0xD && Rm != 0xF && 2868234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2869234353Sdim return MCDisassembler::Fail; 2870226633Sdim 2871226633Sdim return S; 2872226633Sdim} 2873226633Sdim 2874234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, 2875226633Sdim uint64_t Address, const void *Decoder) { 2876226633Sdim DecodeStatus S = MCDisassembler::Success; 2877226633Sdim 2878239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2879239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2880239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2881239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2882239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 2883239462Sdim unsigned size = 1 << fieldFromInstruction(Insn, 6, 2); 2884226633Sdim align *= 2*size; 2885226633Sdim 2886234353Sdim switch (Inst.getOpcode()) { 2887234353Sdim case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8: 2888234353Sdim case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register: 2889234353Sdim case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register: 2890234353Sdim case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register: 2891234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2892226633Sdim return MCDisassembler::Fail; 2893234353Sdim break; 2894234353Sdim case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2: 2895234353Sdim case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register: 2896234353Sdim case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register: 2897234353Sdim case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register: 2898234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2899234353Sdim return MCDisassembler::Fail; 2900234353Sdim break; 2901234353Sdim default: 2902234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2903234353Sdim return MCDisassembler::Fail; 2904234353Sdim break; 2905226633Sdim } 2906226633Sdim 2907234353Sdim if (Rm != 0xF) 2908234353Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2909234353Sdim 2910226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2911226633Sdim return MCDisassembler::Fail; 2912226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 2913226633Sdim 2914234982Sdim if (Rm != 0xD && Rm != 0xF) { 2915226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2916226633Sdim return MCDisassembler::Fail; 2917226633Sdim } 2918226633Sdim 2919226633Sdim return S; 2920226633Sdim} 2921226633Sdim 2922234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn, 2923226633Sdim uint64_t Address, const void *Decoder) { 2924226633Sdim DecodeStatus S = MCDisassembler::Success; 2925226633Sdim 2926239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2927239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2928239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2929239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2930239462Sdim unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; 2931226633Sdim 2932226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2933226633Sdim return MCDisassembler::Fail; 2934226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 2935226633Sdim return MCDisassembler::Fail; 2936226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 2937226633Sdim return MCDisassembler::Fail; 2938226633Sdim if (Rm != 0xF) { 2939226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2940226633Sdim return MCDisassembler::Fail; 2941226633Sdim } 2942226633Sdim 2943226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2944226633Sdim return MCDisassembler::Fail; 2945226633Sdim Inst.addOperand(MCOperand::CreateImm(0)); 2946226633Sdim 2947226633Sdim if (Rm == 0xD) 2948226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 2949226633Sdim else if (Rm != 0xF) { 2950226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2951226633Sdim return MCDisassembler::Fail; 2952226633Sdim } 2953226633Sdim 2954226633Sdim return S; 2955226633Sdim} 2956226633Sdim 2957234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn, 2958226633Sdim uint64_t Address, const void *Decoder) { 2959226633Sdim DecodeStatus S = MCDisassembler::Success; 2960226633Sdim 2961239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2962239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2963239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2964239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2965239462Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2966239462Sdim unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; 2967239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 2968226633Sdim 2969226633Sdim if (size == 0x3) { 2970243830Sdim if (align == 0) 2971243830Sdim return MCDisassembler::Fail; 2972226633Sdim size = 4; 2973226633Sdim align = 16; 2974226633Sdim } else { 2975226633Sdim if (size == 2) { 2976226633Sdim size = 1 << size; 2977226633Sdim align *= 8; 2978226633Sdim } else { 2979226633Sdim size = 1 << size; 2980226633Sdim align *= 4*size; 2981206124Srdivacky } 2982206124Srdivacky } 2983206124Srdivacky 2984226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2985226633Sdim return MCDisassembler::Fail; 2986226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 2987226633Sdim return MCDisassembler::Fail; 2988226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 2989226633Sdim return MCDisassembler::Fail; 2990226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder))) 2991226633Sdim return MCDisassembler::Fail; 2992226633Sdim if (Rm != 0xF) { 2993226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2994226633Sdim return MCDisassembler::Fail; 2995226633Sdim } 2996226633Sdim 2997226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2998226633Sdim return MCDisassembler::Fail; 2999226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 3000226633Sdim 3001226633Sdim if (Rm == 0xD) 3002226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 3003226633Sdim else if (Rm != 0xF) { 3004226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3005226633Sdim return MCDisassembler::Fail; 3006226633Sdim } 3007226633Sdim 3008226633Sdim return S; 3009206124Srdivacky} 3010206124Srdivacky 3011226633Sdimstatic DecodeStatus 3012234353SdimDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn, 3013226633Sdim uint64_t Address, const void *Decoder) { 3014226633Sdim DecodeStatus S = MCDisassembler::Success; 3015206124Srdivacky 3016239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3017239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3018239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 3019239462Sdim imm |= fieldFromInstruction(Insn, 16, 3) << 4; 3020239462Sdim imm |= fieldFromInstruction(Insn, 24, 1) << 7; 3021239462Sdim imm |= fieldFromInstruction(Insn, 8, 4) << 8; 3022239462Sdim imm |= fieldFromInstruction(Insn, 5, 1) << 12; 3023239462Sdim unsigned Q = fieldFromInstruction(Insn, 6, 1); 3024206124Srdivacky 3025226633Sdim if (Q) { 3026226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 3027226633Sdim return MCDisassembler::Fail; 3028226633Sdim } else { 3029226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3030226633Sdim return MCDisassembler::Fail; 3031226633Sdim } 3032206124Srdivacky 3033226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3034206124Srdivacky 3035226633Sdim switch (Inst.getOpcode()) { 3036226633Sdim case ARM::VORRiv4i16: 3037226633Sdim case ARM::VORRiv2i32: 3038226633Sdim case ARM::VBICiv4i16: 3039226633Sdim case ARM::VBICiv2i32: 3040226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3041226633Sdim return MCDisassembler::Fail; 3042226633Sdim break; 3043226633Sdim case ARM::VORRiv8i16: 3044226633Sdim case ARM::VORRiv4i32: 3045226633Sdim case ARM::VBICiv8i16: 3046226633Sdim case ARM::VBICiv4i32: 3047226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 3048226633Sdim return MCDisassembler::Fail; 3049226633Sdim break; 3050226633Sdim default: 3051226633Sdim break; 3052226633Sdim } 3053206124Srdivacky 3054226633Sdim return S; 3055226633Sdim} 3056226633Sdim 3057234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn, 3058226633Sdim uint64_t Address, const void *Decoder) { 3059226633Sdim DecodeStatus S = MCDisassembler::Success; 3060226633Sdim 3061239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3062239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3063239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3064239462Sdim Rm |= fieldFromInstruction(Insn, 5, 1) << 4; 3065239462Sdim unsigned size = fieldFromInstruction(Insn, 18, 2); 3066226633Sdim 3067226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 3068226633Sdim return MCDisassembler::Fail; 3069226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 3070226633Sdim return MCDisassembler::Fail; 3071226633Sdim Inst.addOperand(MCOperand::CreateImm(8 << size)); 3072226633Sdim 3073226633Sdim return S; 3074226633Sdim} 3075226633Sdim 3076234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 3077226633Sdim uint64_t Address, const void *Decoder) { 3078226633Sdim Inst.addOperand(MCOperand::CreateImm(8 - Val)); 3079226633Sdim return MCDisassembler::Success; 3080226633Sdim} 3081226633Sdim 3082234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 3083226633Sdim uint64_t Address, const void *Decoder) { 3084226633Sdim Inst.addOperand(MCOperand::CreateImm(16 - Val)); 3085226633Sdim return MCDisassembler::Success; 3086226633Sdim} 3087226633Sdim 3088234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 3089226633Sdim uint64_t Address, const void *Decoder) { 3090226633Sdim Inst.addOperand(MCOperand::CreateImm(32 - Val)); 3091226633Sdim return MCDisassembler::Success; 3092226633Sdim} 3093226633Sdim 3094234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 3095226633Sdim uint64_t Address, const void *Decoder) { 3096226633Sdim Inst.addOperand(MCOperand::CreateImm(64 - Val)); 3097226633Sdim return MCDisassembler::Success; 3098226633Sdim} 3099226633Sdim 3100234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 3101226633Sdim uint64_t Address, const void *Decoder) { 3102226633Sdim DecodeStatus S = MCDisassembler::Success; 3103226633Sdim 3104239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3105239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3106239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3107239462Sdim Rn |= fieldFromInstruction(Insn, 7, 1) << 4; 3108239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3109239462Sdim Rm |= fieldFromInstruction(Insn, 5, 1) << 4; 3110239462Sdim unsigned op = fieldFromInstruction(Insn, 6, 1); 3111226633Sdim 3112226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3113226633Sdim return MCDisassembler::Fail; 3114226633Sdim if (op) { 3115226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3116226633Sdim return MCDisassembler::Fail; // Writeback 3117206124Srdivacky } 3118226633Sdim 3119234353Sdim switch (Inst.getOpcode()) { 3120234353Sdim case ARM::VTBL2: 3121234353Sdim case ARM::VTBX2: 3122234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder))) 3123234353Sdim return MCDisassembler::Fail; 3124234353Sdim break; 3125234353Sdim default: 3126234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder))) 3127234353Sdim return MCDisassembler::Fail; 3128226633Sdim } 3129226633Sdim 3130226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 3131226633Sdim return MCDisassembler::Fail; 3132226633Sdim 3133226633Sdim return S; 3134206124Srdivacky} 3135206124Srdivacky 3136234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 3137226633Sdim uint64_t Address, const void *Decoder) { 3138226633Sdim DecodeStatus S = MCDisassembler::Success; 3139221345Sdim 3140239462Sdim unsigned dst = fieldFromInstruction(Insn, 8, 3); 3141239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 3142221345Sdim 3143226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder))) 3144226633Sdim return MCDisassembler::Fail; 3145226633Sdim 3146226633Sdim switch(Inst.getOpcode()) { 3147226633Sdim default: 3148226633Sdim return MCDisassembler::Fail; 3149226633Sdim case ARM::tADR: 3150226633Sdim break; // tADR does not explicitly represent the PC as an operand. 3151226633Sdim case ARM::tADDrSPi: 3152226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3153226633Sdim break; 3154221345Sdim } 3155226633Sdim 3156226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3157226633Sdim return S; 3158221345Sdim} 3159221345Sdim 3160234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 3161226633Sdim uint64_t Address, const void *Decoder) { 3162234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4, 3163234353Sdim true, 2, Inst, Decoder)) 3164234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1))); 3165226633Sdim return MCDisassembler::Success; 3166226633Sdim} 3167206124Srdivacky 3168234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 3169226633Sdim uint64_t Address, const void *Decoder) { 3170239462Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4, 3171234353Sdim true, 4, Inst, Decoder)) 3172234353Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val))); 3173226633Sdim return MCDisassembler::Success; 3174226633Sdim} 3175206124Srdivacky 3176234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 3177226633Sdim uint64_t Address, const void *Decoder) { 3178249423Sdim if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4, 3179234353Sdim true, 2, Inst, Decoder)) 3180249423Sdim Inst.addOperand(MCOperand::CreateImm(Val << 1)); 3181226633Sdim return MCDisassembler::Success; 3182226633Sdim} 3183206124Srdivacky 3184234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 3185226633Sdim uint64_t Address, const void *Decoder) { 3186226633Sdim DecodeStatus S = MCDisassembler::Success; 3187206124Srdivacky 3188239462Sdim unsigned Rn = fieldFromInstruction(Val, 0, 3); 3189239462Sdim unsigned Rm = fieldFromInstruction(Val, 3, 3); 3190226633Sdim 3191226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3192226633Sdim return MCDisassembler::Fail; 3193226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder))) 3194226633Sdim return MCDisassembler::Fail; 3195226633Sdim 3196226633Sdim return S; 3197226633Sdim} 3198226633Sdim 3199234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 3200226633Sdim uint64_t Address, const void *Decoder) { 3201226633Sdim DecodeStatus S = MCDisassembler::Success; 3202226633Sdim 3203239462Sdim unsigned Rn = fieldFromInstruction(Val, 0, 3); 3204239462Sdim unsigned imm = fieldFromInstruction(Val, 3, 5); 3205226633Sdim 3206226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3207226633Sdim return MCDisassembler::Fail; 3208226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3209226633Sdim 3210226633Sdim return S; 3211226633Sdim} 3212226633Sdim 3213234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 3214226633Sdim uint64_t Address, const void *Decoder) { 3215226633Sdim unsigned imm = Val << 2; 3216226633Sdim 3217226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3218226633Sdim tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder); 3219226633Sdim 3220226633Sdim return MCDisassembler::Success; 3221226633Sdim} 3222226633Sdim 3223234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 3224226633Sdim uint64_t Address, const void *Decoder) { 3225226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3226226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3227226633Sdim 3228226633Sdim return MCDisassembler::Success; 3229226633Sdim} 3230226633Sdim 3231234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 3232226633Sdim uint64_t Address, const void *Decoder) { 3233226633Sdim DecodeStatus S = MCDisassembler::Success; 3234226633Sdim 3235239462Sdim unsigned Rn = fieldFromInstruction(Val, 6, 4); 3236239462Sdim unsigned Rm = fieldFromInstruction(Val, 2, 4); 3237239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 2); 3238226633Sdim 3239263508Sdim // Thumb stores cannot use PC as dest register. 3240263508Sdim switch (Inst.getOpcode()) { 3241263508Sdim case ARM::t2STRHs: 3242263508Sdim case ARM::t2STRBs: 3243263508Sdim case ARM::t2STRs: 3244263508Sdim if (Rn == 15) 3245263508Sdim return MCDisassembler::Fail; 3246263508Sdim default: 3247263508Sdim break; 3248263508Sdim } 3249263508Sdim 3250226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3251226633Sdim return MCDisassembler::Fail; 3252226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3253226633Sdim return MCDisassembler::Fail; 3254226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3255226633Sdim 3256226633Sdim return S; 3257226633Sdim} 3258226633Sdim 3259234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn, 3260226633Sdim uint64_t Address, const void *Decoder) { 3261226633Sdim DecodeStatus S = MCDisassembler::Success; 3262226633Sdim 3263263508Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3264263508Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3265263508Sdim 3266263508Sdim if (Rn == 15) { 3267263508Sdim switch (Inst.getOpcode()) { 3268263508Sdim case ARM::t2LDRBs: 3269263508Sdim Inst.setOpcode(ARM::t2LDRBpci); 3270263508Sdim break; 3271263508Sdim case ARM::t2LDRHs: 3272263508Sdim Inst.setOpcode(ARM::t2LDRHpci); 3273263508Sdim break; 3274263508Sdim case ARM::t2LDRSHs: 3275263508Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3276263508Sdim break; 3277263508Sdim case ARM::t2LDRSBs: 3278263508Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3279263508Sdim break; 3280263508Sdim case ARM::t2LDRs: 3281263508Sdim Inst.setOpcode(ARM::t2LDRpci); 3282263508Sdim break; 3283263508Sdim case ARM::t2PLDs: 3284263508Sdim Inst.setOpcode(ARM::t2PLDpci); 3285263508Sdim break; 3286263508Sdim case ARM::t2PLIs: 3287263508Sdim Inst.setOpcode(ARM::t2PLIpci); 3288263508Sdim break; 3289263508Sdim default: 3290263508Sdim return MCDisassembler::Fail; 3291263508Sdim } 3292263508Sdim 3293263508Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3294263508Sdim } 3295263508Sdim 3296263508Sdim if (Rt == 15) { 3297263508Sdim switch (Inst.getOpcode()) { 3298263508Sdim case ARM::t2LDRSHs: 3299263508Sdim return MCDisassembler::Fail; 3300263508Sdim case ARM::t2LDRHs: 3301263508Sdim // FIXME: this instruction is only available with MP extensions, 3302263508Sdim // this should be checked first but we don't have access to the 3303263508Sdim // feature bits here. 3304263508Sdim Inst.setOpcode(ARM::t2PLDWs); 3305263508Sdim break; 3306263508Sdim default: 3307263508Sdim break; 3308263508Sdim } 3309263508Sdim } 3310263508Sdim 3311226633Sdim switch (Inst.getOpcode()) { 3312226633Sdim case ARM::t2PLDs: 3313226633Sdim case ARM::t2PLDWs: 3314226633Sdim case ARM::t2PLIs: 3315226633Sdim break; 3316263508Sdim default: 3317263508Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3318263508Sdim return MCDisassembler::Fail; 3319263508Sdim } 3320263508Sdim 3321263508Sdim unsigned addrmode = fieldFromInstruction(Insn, 4, 2); 3322263508Sdim addrmode |= fieldFromInstruction(Insn, 0, 4) << 2; 3323263508Sdim addrmode |= fieldFromInstruction(Insn, 16, 4) << 6; 3324263508Sdim if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder))) 3325226633Sdim return MCDisassembler::Fail; 3326263508Sdim 3327263508Sdim return S; 3328263508Sdim} 3329263508Sdim 3330263508Sdimstatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn, 3331263508Sdim uint64_t Address, const void* Decoder) { 3332263508Sdim DecodeStatus S = MCDisassembler::Success; 3333263508Sdim 3334263508Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3335263508Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3336263508Sdim unsigned U = fieldFromInstruction(Insn, 9, 1); 3337263508Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 3338263508Sdim imm |= (U << 8); 3339263508Sdim imm |= (Rn << 9); 3340263508Sdim 3341263508Sdim if (Rn == 15) { 3342263508Sdim switch (Inst.getOpcode()) { 3343263508Sdim case ARM::t2LDRi8: 3344263508Sdim Inst.setOpcode(ARM::t2LDRpci); 3345263508Sdim break; 3346263508Sdim case ARM::t2LDRBi8: 3347263508Sdim Inst.setOpcode(ARM::t2LDRBpci); 3348263508Sdim break; 3349263508Sdim case ARM::t2LDRSBi8: 3350263508Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3351263508Sdim break; 3352263508Sdim case ARM::t2LDRHi8: 3353263508Sdim Inst.setOpcode(ARM::t2LDRHpci); 3354263508Sdim break; 3355263508Sdim case ARM::t2LDRSHi8: 3356263508Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3357263508Sdim break; 3358263508Sdim case ARM::t2PLDi8: 3359263508Sdim Inst.setOpcode(ARM::t2PLDpci); 3360263508Sdim break; 3361263508Sdim case ARM::t2PLIi8: 3362263508Sdim Inst.setOpcode(ARM::t2PLIpci); 3363263508Sdim break; 3364263508Sdim default: 3365263508Sdim return MCDisassembler::Fail; 3366206124Srdivacky } 3367263508Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3368226633Sdim } 3369206124Srdivacky 3370263508Sdim if (Rt == 15) { 3371263508Sdim switch (Inst.getOpcode()) { 3372263508Sdim case ARM::t2LDRSHi8: 3373263508Sdim return MCDisassembler::Fail; 3374263508Sdim default: 3375263508Sdim break; 3376263508Sdim } 3377263508Sdim } 3378263508Sdim 3379263508Sdim switch (Inst.getOpcode()) { 3380263508Sdim case ARM::t2PLDi8: 3381263508Sdim case ARM::t2PLIi8: 3382263508Sdim case ARM::t2PLDWi8: 3383263508Sdim break; 3384263508Sdim default: 3385263508Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3386263508Sdim return MCDisassembler::Fail; 3387263508Sdim } 3388263508Sdim 3389263508Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder))) 3390263508Sdim return MCDisassembler::Fail; 3391263508Sdim return S; 3392263508Sdim} 3393263508Sdim 3394263508Sdimstatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn, 3395263508Sdim uint64_t Address, const void* Decoder) { 3396263508Sdim DecodeStatus S = MCDisassembler::Success; 3397263508Sdim 3398239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3399263508Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3400263508Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 3401263508Sdim imm |= (Rn << 13); 3402263508Sdim 3403263508Sdim if (Rn == 15) { 3404226633Sdim switch (Inst.getOpcode()) { 3405263508Sdim case ARM::t2LDRi12: 3406263508Sdim Inst.setOpcode(ARM::t2LDRpci); 3407263508Sdim break; 3408263508Sdim case ARM::t2LDRHi12: 3409263508Sdim Inst.setOpcode(ARM::t2LDRHpci); 3410263508Sdim break; 3411263508Sdim case ARM::t2LDRSHi12: 3412263508Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3413263508Sdim break; 3414263508Sdim case ARM::t2LDRBi12: 3415263508Sdim Inst.setOpcode(ARM::t2LDRBpci); 3416263508Sdim break; 3417263508Sdim case ARM::t2LDRSBi12: 3418263508Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3419263508Sdim break; 3420263508Sdim case ARM::t2PLDi12: 3421263508Sdim Inst.setOpcode(ARM::t2PLDpci); 3422263508Sdim break; 3423263508Sdim case ARM::t2PLIi12: 3424263508Sdim Inst.setOpcode(ARM::t2PLIpci); 3425263508Sdim break; 3426263508Sdim default: 3427263508Sdim return MCDisassembler::Fail; 3428263508Sdim } 3429263508Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3430263508Sdim } 3431263508Sdim 3432263508Sdim if (Rt == 15) { 3433263508Sdim switch (Inst.getOpcode()) { 3434263508Sdim case ARM::t2LDRSHi12: 3435263508Sdim return MCDisassembler::Fail; 3436263508Sdim case ARM::t2LDRHi12: 3437263508Sdim Inst.setOpcode(ARM::t2PLDi12); 3438263508Sdim break; 3439263508Sdim default: 3440263508Sdim break; 3441263508Sdim } 3442263508Sdim } 3443263508Sdim 3444263508Sdim switch (Inst.getOpcode()) { 3445263508Sdim case ARM::t2PLDi12: 3446263508Sdim case ARM::t2PLDWi12: 3447263508Sdim case ARM::t2PLIi12: 3448263508Sdim break; 3449263508Sdim default: 3450263508Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3451263508Sdim return MCDisassembler::Fail; 3452263508Sdim } 3453263508Sdim 3454263508Sdim if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder))) 3455263508Sdim return MCDisassembler::Fail; 3456263508Sdim return S; 3457263508Sdim} 3458263508Sdim 3459263508Sdimstatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, 3460263508Sdim uint64_t Address, const void* Decoder) { 3461263508Sdim DecodeStatus S = MCDisassembler::Success; 3462263508Sdim 3463263508Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3464263508Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3465263508Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 3466263508Sdim imm |= (Rn << 9); 3467263508Sdim 3468263508Sdim if (Rn == 15) { 3469263508Sdim switch (Inst.getOpcode()) { 3470263508Sdim case ARM::t2LDRT: 3471263508Sdim Inst.setOpcode(ARM::t2LDRpci); 3472263508Sdim break; 3473263508Sdim case ARM::t2LDRBT: 3474263508Sdim Inst.setOpcode(ARM::t2LDRBpci); 3475263508Sdim break; 3476263508Sdim case ARM::t2LDRHT: 3477263508Sdim Inst.setOpcode(ARM::t2LDRHpci); 3478263508Sdim break; 3479263508Sdim case ARM::t2LDRSBT: 3480263508Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3481263508Sdim break; 3482263508Sdim case ARM::t2LDRSHT: 3483263508Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3484263508Sdim break; 3485263508Sdim default: 3486263508Sdim return MCDisassembler::Fail; 3487263508Sdim } 3488263508Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3489263508Sdim } 3490263508Sdim 3491263508Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 3492263508Sdim return MCDisassembler::Fail; 3493263508Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder))) 3494263508Sdim return MCDisassembler::Fail; 3495263508Sdim return S; 3496263508Sdim} 3497263508Sdim 3498263508Sdimstatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn, 3499263508Sdim uint64_t Address, const void* Decoder) { 3500263508Sdim DecodeStatus S = MCDisassembler::Success; 3501263508Sdim 3502263508Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3503263508Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 3504263508Sdim int imm = fieldFromInstruction(Insn, 0, 12); 3505263508Sdim 3506263508Sdim if (Rt == 15) { 3507263508Sdim switch (Inst.getOpcode()) { 3508263508Sdim case ARM::t2LDRBpci: 3509263508Sdim case ARM::t2LDRHpci: 3510263508Sdim Inst.setOpcode(ARM::t2PLDpci); 3511226633Sdim break; 3512263508Sdim case ARM::t2LDRSBpci: 3513263508Sdim Inst.setOpcode(ARM::t2PLIpci); 3514226633Sdim break; 3515263508Sdim case ARM::t2LDRSHpci: 3516263508Sdim return MCDisassembler::Fail; 3517263508Sdim default: 3518226633Sdim break; 3519206124Srdivacky } 3520263508Sdim } 3521206124Srdivacky 3522263508Sdim switch(Inst.getOpcode()) { 3523263508Sdim case ARM::t2PLDpci: 3524263508Sdim case ARM::t2PLIpci: 3525263508Sdim break; 3526263508Sdim default: 3527263508Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3528263508Sdim return MCDisassembler::Fail; 3529263508Sdim } 3530221345Sdim 3531263508Sdim if (!U) { 3532263508Sdim // Special case for #-0. 3533263508Sdim if (imm == 0) 3534263508Sdim imm = INT32_MIN; 3535263508Sdim else 3536263508Sdim imm = -imm; 3537226633Sdim } 3538263508Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3539226633Sdim 3540226633Sdim return S; 3541226633Sdim} 3542226633Sdim 3543234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 3544226633Sdim uint64_t Address, const void *Decoder) { 3545239462Sdim if (Val == 0) 3546239462Sdim Inst.addOperand(MCOperand::CreateImm(INT32_MIN)); 3547239462Sdim else { 3548239462Sdim int imm = Val & 0xFF; 3549226633Sdim 3550239462Sdim if (!(Val & 0x100)) imm *= -1; 3551243830Sdim Inst.addOperand(MCOperand::CreateImm(imm * 4)); 3552239462Sdim } 3553239462Sdim 3554226633Sdim return MCDisassembler::Success; 3555226633Sdim} 3556226633Sdim 3557234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 3558226633Sdim uint64_t Address, const void *Decoder) { 3559226633Sdim DecodeStatus S = MCDisassembler::Success; 3560226633Sdim 3561239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 3562239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 9); 3563226633Sdim 3564226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3565226633Sdim return MCDisassembler::Fail; 3566226633Sdim if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder))) 3567226633Sdim return MCDisassembler::Fail; 3568226633Sdim 3569226633Sdim return S; 3570226633Sdim} 3571226633Sdim 3572234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 3573226633Sdim uint64_t Address, const void *Decoder) { 3574226633Sdim DecodeStatus S = MCDisassembler::Success; 3575226633Sdim 3576239462Sdim unsigned Rn = fieldFromInstruction(Val, 8, 4); 3577239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 3578226633Sdim 3579226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 3580226633Sdim return MCDisassembler::Fail; 3581226633Sdim 3582226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3583226633Sdim 3584226633Sdim return S; 3585226633Sdim} 3586226633Sdim 3587234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 3588226633Sdim uint64_t Address, const void *Decoder) { 3589226633Sdim int imm = Val & 0xFF; 3590226633Sdim if (Val == 0) 3591226633Sdim imm = INT32_MIN; 3592226633Sdim else if (!(Val & 0x100)) 3593226633Sdim imm *= -1; 3594226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3595226633Sdim 3596226633Sdim return MCDisassembler::Success; 3597226633Sdim} 3598226633Sdim 3599226633Sdim 3600234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 3601226633Sdim uint64_t Address, const void *Decoder) { 3602226633Sdim DecodeStatus S = MCDisassembler::Success; 3603226633Sdim 3604239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 3605239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 9); 3606226633Sdim 3607263508Sdim // Thumb stores cannot use PC as dest register. 3608263508Sdim switch (Inst.getOpcode()) { 3609263508Sdim case ARM::t2STRT: 3610263508Sdim case ARM::t2STRBT: 3611263508Sdim case ARM::t2STRHT: 3612263508Sdim case ARM::t2STRi8: 3613263508Sdim case ARM::t2STRHi8: 3614263508Sdim case ARM::t2STRBi8: 3615263508Sdim if (Rn == 15) 3616263508Sdim return MCDisassembler::Fail; 3617263508Sdim break; 3618263508Sdim default: 3619263508Sdim break; 3620263508Sdim } 3621263508Sdim 3622226633Sdim // Some instructions always use an additive offset. 3623226633Sdim switch (Inst.getOpcode()) { 3624226633Sdim case ARM::t2LDRT: 3625226633Sdim case ARM::t2LDRBT: 3626226633Sdim case ARM::t2LDRHT: 3627226633Sdim case ARM::t2LDRSBT: 3628226633Sdim case ARM::t2LDRSHT: 3629226633Sdim case ARM::t2STRT: 3630226633Sdim case ARM::t2STRBT: 3631226633Sdim case ARM::t2STRHT: 3632226633Sdim imm |= 0x100; 3633226633Sdim break; 3634226633Sdim default: 3635226633Sdim break; 3636226633Sdim } 3637226633Sdim 3638226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3639226633Sdim return MCDisassembler::Fail; 3640226633Sdim if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder))) 3641226633Sdim return MCDisassembler::Fail; 3642226633Sdim 3643226633Sdim return S; 3644226633Sdim} 3645226633Sdim 3646234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn, 3647226633Sdim uint64_t Address, const void *Decoder) { 3648226633Sdim DecodeStatus S = MCDisassembler::Success; 3649226633Sdim 3650239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3651239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3652239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 3653239462Sdim addr |= fieldFromInstruction(Insn, 9, 1) << 8; 3654226633Sdim addr |= Rn << 9; 3655239462Sdim unsigned load = fieldFromInstruction(Insn, 20, 1); 3656226633Sdim 3657263508Sdim if (Rn == 15) { 3658263508Sdim switch (Inst.getOpcode()) { 3659263508Sdim case ARM::t2LDR_PRE: 3660263508Sdim case ARM::t2LDR_POST: 3661263508Sdim Inst.setOpcode(ARM::t2LDRpci); 3662263508Sdim break; 3663263508Sdim case ARM::t2LDRB_PRE: 3664263508Sdim case ARM::t2LDRB_POST: 3665263508Sdim Inst.setOpcode(ARM::t2LDRBpci); 3666263508Sdim break; 3667263508Sdim case ARM::t2LDRH_PRE: 3668263508Sdim case ARM::t2LDRH_POST: 3669263508Sdim Inst.setOpcode(ARM::t2LDRHpci); 3670263508Sdim break; 3671263508Sdim case ARM::t2LDRSB_PRE: 3672263508Sdim case ARM::t2LDRSB_POST: 3673263508Sdim if (Rt == 15) 3674263508Sdim Inst.setOpcode(ARM::t2PLIpci); 3675263508Sdim else 3676263508Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3677263508Sdim break; 3678263508Sdim case ARM::t2LDRSH_PRE: 3679263508Sdim case ARM::t2LDRSH_POST: 3680263508Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3681263508Sdim break; 3682263508Sdim default: 3683263508Sdim return MCDisassembler::Fail; 3684263508Sdim } 3685263508Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3686263508Sdim } 3687263508Sdim 3688226633Sdim if (!load) { 3689226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3690226633Sdim return MCDisassembler::Fail; 3691226633Sdim } 3692226633Sdim 3693249423Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3694226633Sdim return MCDisassembler::Fail; 3695226633Sdim 3696226633Sdim if (load) { 3697226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3698226633Sdim return MCDisassembler::Fail; 3699226633Sdim } 3700226633Sdim 3701226633Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder))) 3702226633Sdim return MCDisassembler::Fail; 3703226633Sdim 3704226633Sdim return S; 3705226633Sdim} 3706226633Sdim 3707234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 3708226633Sdim uint64_t Address, const void *Decoder) { 3709226633Sdim DecodeStatus S = MCDisassembler::Success; 3710226633Sdim 3711239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 3712239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 12); 3713226633Sdim 3714263508Sdim // Thumb stores cannot use PC as dest register. 3715263508Sdim switch (Inst.getOpcode()) { 3716263508Sdim case ARM::t2STRi12: 3717263508Sdim case ARM::t2STRBi12: 3718263508Sdim case ARM::t2STRHi12: 3719263508Sdim if (Rn == 15) 3720263508Sdim return MCDisassembler::Fail; 3721263508Sdim default: 3722263508Sdim break; 3723263508Sdim } 3724263508Sdim 3725226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3726226633Sdim return MCDisassembler::Fail; 3727226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3728226633Sdim 3729226633Sdim return S; 3730226633Sdim} 3731226633Sdim 3732226633Sdim 3733234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn, 3734226633Sdim uint64_t Address, const void *Decoder) { 3735239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 7); 3736226633Sdim 3737226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3738226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3739226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3740226633Sdim 3741226633Sdim return MCDisassembler::Success; 3742226633Sdim} 3743226633Sdim 3744234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 3745226633Sdim uint64_t Address, const void *Decoder) { 3746226633Sdim DecodeStatus S = MCDisassembler::Success; 3747226633Sdim 3748226633Sdim if (Inst.getOpcode() == ARM::tADDrSP) { 3749239462Sdim unsigned Rdm = fieldFromInstruction(Insn, 0, 3); 3750239462Sdim Rdm |= fieldFromInstruction(Insn, 7, 1) << 3; 3751226633Sdim 3752226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 3753226633Sdim return MCDisassembler::Fail; 3754239462Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3755226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 3756226633Sdim return MCDisassembler::Fail; 3757226633Sdim } else if (Inst.getOpcode() == ARM::tADDspr) { 3758239462Sdim unsigned Rm = fieldFromInstruction(Insn, 3, 4); 3759226633Sdim 3760226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3761226633Sdim Inst.addOperand(MCOperand::CreateReg(ARM::SP)); 3762226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3763226633Sdim return MCDisassembler::Fail; 3764226633Sdim } 3765226633Sdim 3766226633Sdim return S; 3767226633Sdim} 3768226633Sdim 3769234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 3770226633Sdim uint64_t Address, const void *Decoder) { 3771239462Sdim unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2; 3772239462Sdim unsigned flags = fieldFromInstruction(Insn, 0, 3); 3773226633Sdim 3774226633Sdim Inst.addOperand(MCOperand::CreateImm(imod)); 3775226633Sdim Inst.addOperand(MCOperand::CreateImm(flags)); 3776226633Sdim 3777226633Sdim return MCDisassembler::Success; 3778226633Sdim} 3779226633Sdim 3780234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 3781226633Sdim uint64_t Address, const void *Decoder) { 3782226633Sdim DecodeStatus S = MCDisassembler::Success; 3783239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3784239462Sdim unsigned add = fieldFromInstruction(Insn, 4, 1); 3785226633Sdim 3786234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 3787226633Sdim return MCDisassembler::Fail; 3788226633Sdim Inst.addOperand(MCOperand::CreateImm(add)); 3789226633Sdim 3790226633Sdim return S; 3791226633Sdim} 3792226633Sdim 3793234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val, 3794226633Sdim uint64_t Address, const void *Decoder) { 3795239462Sdim // Val is passed in as S:J1:J2:imm10H:imm10L:'0' 3796239462Sdim // Note only one trailing zero not two. Also the J1 and J2 values are from 3797239462Sdim // the encoded instruction. So here change to I1 and I2 values via: 3798239462Sdim // I1 = NOT(J1 EOR S); 3799239462Sdim // I2 = NOT(J2 EOR S); 3800239462Sdim // and build the imm32 with two trailing zeros as documented: 3801239462Sdim // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32); 3802239462Sdim unsigned S = (Val >> 23) & 1; 3803239462Sdim unsigned J1 = (Val >> 22) & 1; 3804239462Sdim unsigned J2 = (Val >> 21) & 1; 3805239462Sdim unsigned I1 = !(J1 ^ S); 3806239462Sdim unsigned I2 = !(J2 ^ S); 3807239462Sdim unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); 3808239462Sdim int imm32 = SignExtend32<25>(tmp << 1); 3809239462Sdim 3810234353Sdim if (!tryAddingSymbolicOperand(Address, 3811239462Sdim (Address & ~2u) + imm32 + 4, 3812226633Sdim true, 4, Inst, Decoder)) 3813239462Sdim Inst.addOperand(MCOperand::CreateImm(imm32)); 3814226633Sdim return MCDisassembler::Success; 3815226633Sdim} 3816226633Sdim 3817234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val, 3818226633Sdim uint64_t Address, const void *Decoder) { 3819226633Sdim if (Val == 0xA || Val == 0xB) 3820226633Sdim return MCDisassembler::Fail; 3821226633Sdim 3822263508Sdim uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo() 3823263508Sdim .getFeatureBits(); 3824263508Sdim if ((featureBits & ARM::HasV8Ops) && !(Val == 14 || Val == 15)) 3825263508Sdim return MCDisassembler::Fail; 3826263508Sdim 3827226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3828226633Sdim return MCDisassembler::Success; 3829226633Sdim} 3830226633Sdim 3831226633Sdimstatic DecodeStatus 3832234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn, 3833226633Sdim uint64_t Address, const void *Decoder) { 3834226633Sdim DecodeStatus S = MCDisassembler::Success; 3835226633Sdim 3836239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3837239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3838226633Sdim 3839226633Sdim if (Rn == ARM::SP) S = MCDisassembler::SoftFail; 3840226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3841226633Sdim return MCDisassembler::Fail; 3842226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3843226633Sdim return MCDisassembler::Fail; 3844226633Sdim return S; 3845226633Sdim} 3846226633Sdim 3847226633Sdimstatic DecodeStatus 3848234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn, 3849226633Sdim uint64_t Address, const void *Decoder) { 3850226633Sdim DecodeStatus S = MCDisassembler::Success; 3851226633Sdim 3852239462Sdim unsigned pred = fieldFromInstruction(Insn, 22, 4); 3853226633Sdim if (pred == 0xE || pred == 0xF) { 3854239462Sdim unsigned opc = fieldFromInstruction(Insn, 4, 28); 3855226633Sdim switch (opc) { 3856226633Sdim default: 3857226633Sdim return MCDisassembler::Fail; 3858226633Sdim case 0xf3bf8f4: 3859226633Sdim Inst.setOpcode(ARM::t2DSB); 3860226633Sdim break; 3861226633Sdim case 0xf3bf8f5: 3862226633Sdim Inst.setOpcode(ARM::t2DMB); 3863226633Sdim break; 3864226633Sdim case 0xf3bf8f6: 3865226633Sdim Inst.setOpcode(ARM::t2ISB); 3866226633Sdim break; 3867221345Sdim } 3868206124Srdivacky 3869239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 3870226633Sdim return DecodeMemBarrierOption(Inst, imm, Address, Decoder); 3871226633Sdim } 3872226633Sdim 3873239462Sdim unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1; 3874239462Sdim brtarget |= fieldFromInstruction(Insn, 11, 1) << 19; 3875239462Sdim brtarget |= fieldFromInstruction(Insn, 13, 1) << 18; 3876239462Sdim brtarget |= fieldFromInstruction(Insn, 16, 6) << 12; 3877239462Sdim brtarget |= fieldFromInstruction(Insn, 26, 1) << 20; 3878226633Sdim 3879226633Sdim if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder))) 3880226633Sdim return MCDisassembler::Fail; 3881226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3882226633Sdim return MCDisassembler::Fail; 3883226633Sdim 3884226633Sdim return S; 3885226633Sdim} 3886226633Sdim 3887226633Sdim// Decode a shifted immediate operand. These basically consist 3888226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either 3889226633Sdim// a splat operation or a rotation. 3890234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 3891226633Sdim uint64_t Address, const void *Decoder) { 3892239462Sdim unsigned ctrl = fieldFromInstruction(Val, 10, 2); 3893226633Sdim if (ctrl == 0) { 3894239462Sdim unsigned byte = fieldFromInstruction(Val, 8, 2); 3895239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 3896226633Sdim switch (byte) { 3897226633Sdim case 0: 3898226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3899226633Sdim break; 3900226633Sdim case 1: 3901226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm)); 3902226633Sdim break; 3903226633Sdim case 2: 3904226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8))); 3905226633Sdim break; 3906226633Sdim case 3: 3907226633Sdim Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) | 3908226633Sdim (imm << 8) | imm)); 3909226633Sdim break; 3910221345Sdim } 3911226633Sdim } else { 3912239462Sdim unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80; 3913239462Sdim unsigned rot = fieldFromInstruction(Val, 7, 5); 3914226633Sdim unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31)); 3915226633Sdim Inst.addOperand(MCOperand::CreateImm(imm)); 3916226633Sdim } 3917221345Sdim 3918226633Sdim return MCDisassembler::Success; 3919226633Sdim} 3920206124Srdivacky 3921226633Sdimstatic DecodeStatus 3922234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val, 3923226633Sdim uint64_t Address, const void *Decoder){ 3924239462Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4, 3925234353Sdim true, 2, Inst, Decoder)) 3926239462Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1))); 3927226633Sdim return MCDisassembler::Success; 3928226633Sdim} 3929226633Sdim 3930234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 3931226633Sdim uint64_t Address, const void *Decoder){ 3932239462Sdim // Val is passed in as S:J1:J2:imm10:imm11 3933239462Sdim // Note no trailing zero after imm11. Also the J1 and J2 values are from 3934239462Sdim // the encoded instruction. So here change to I1 and I2 values via: 3935239462Sdim // I1 = NOT(J1 EOR S); 3936239462Sdim // I2 = NOT(J2 EOR S); 3937239462Sdim // and build the imm32 with one trailing zero as documented: 3938239462Sdim // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); 3939239462Sdim unsigned S = (Val >> 23) & 1; 3940239462Sdim unsigned J1 = (Val >> 22) & 1; 3941239462Sdim unsigned J2 = (Val >> 21) & 1; 3942239462Sdim unsigned I1 = !(J1 ^ S); 3943239462Sdim unsigned I2 = !(J2 ^ S); 3944239462Sdim unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); 3945239462Sdim int imm32 = SignExtend32<25>(tmp << 1); 3946239462Sdim 3947239462Sdim if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, 3948234353Sdim true, 4, Inst, Decoder)) 3949239462Sdim Inst.addOperand(MCOperand::CreateImm(imm32)); 3950226633Sdim return MCDisassembler::Success; 3951226633Sdim} 3952226633Sdim 3953234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val, 3954226633Sdim uint64_t Address, const void *Decoder) { 3955239462Sdim if (Val & ~0xf) 3956226633Sdim return MCDisassembler::Fail; 3957206124Srdivacky 3958226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3959226633Sdim return MCDisassembler::Success; 3960206124Srdivacky} 3961206124Srdivacky 3962263508Sdimstatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val, 3963263508Sdim uint64_t Address, const void *Decoder) { 3964263508Sdim if (Val & ~0xf) 3965263508Sdim return MCDisassembler::Fail; 3966263508Sdim 3967263508Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3968263508Sdim return MCDisassembler::Success; 3969263508Sdim} 3970263508Sdim 3971234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, 3972226633Sdim uint64_t Address, const void *Decoder) { 3973226633Sdim if (!Val) return MCDisassembler::Fail; 3974226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 3975226633Sdim return MCDisassembler::Success; 3976226633Sdim} 3977206124Srdivacky 3978234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 3979226633Sdim uint64_t Address, const void *Decoder) { 3980226633Sdim DecodeStatus S = MCDisassembler::Success; 3981206124Srdivacky 3982239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3983239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3984239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 3985206124Srdivacky 3986263508Sdim if (Rn == 0xF) 3987263508Sdim S = MCDisassembler::SoftFail; 3988206274Srdivacky 3989263508Sdim if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder))) 3990226633Sdim return MCDisassembler::Fail; 3991226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3992226633Sdim return MCDisassembler::Fail; 3993226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 3994226633Sdim return MCDisassembler::Fail; 3995206124Srdivacky 3996226633Sdim return S; 3997226633Sdim} 3998206124Srdivacky 3999234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 4000226633Sdim uint64_t Address, const void *Decoder){ 4001226633Sdim DecodeStatus S = MCDisassembler::Success; 4002221345Sdim 4003239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4004239462Sdim unsigned Rt = fieldFromInstruction(Insn, 0, 4); 4005239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4006239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4007206124Srdivacky 4008251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 4009226633Sdim return MCDisassembler::Fail; 4010226633Sdim 4011263508Sdim if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1) 4012263508Sdim S = MCDisassembler::SoftFail; 4013226633Sdim 4014263508Sdim if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder))) 4015226633Sdim return MCDisassembler::Fail; 4016226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4017226633Sdim return MCDisassembler::Fail; 4018226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4019226633Sdim return MCDisassembler::Fail; 4020226633Sdim 4021226633Sdim return S; 4022206124Srdivacky} 4023206124Srdivacky 4024234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 4025226633Sdim uint64_t Address, const void *Decoder) { 4026226633Sdim DecodeStatus S = MCDisassembler::Success; 4027206274Srdivacky 4028239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4029239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4030239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4031239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4032239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4033239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4034206124Srdivacky 4035226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4036206124Srdivacky 4037226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4038226633Sdim return MCDisassembler::Fail; 4039226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4040226633Sdim return MCDisassembler::Fail; 4041226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 4042226633Sdim return MCDisassembler::Fail; 4043226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4044226633Sdim return MCDisassembler::Fail; 4045206124Srdivacky 4046226633Sdim return S; 4047226633Sdim} 4048206124Srdivacky 4049234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 4050226633Sdim uint64_t Address, const void *Decoder) { 4051226633Sdim DecodeStatus S = MCDisassembler::Success; 4052226633Sdim 4053239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4054239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4055239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4056239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4057239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4058239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4059239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4060226633Sdim 4061226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4062226633Sdim if (Rm == 0xF) S = MCDisassembler::SoftFail; 4063226633Sdim 4064226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4065226633Sdim return MCDisassembler::Fail; 4066226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4067226633Sdim return MCDisassembler::Fail; 4068226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 4069226633Sdim return MCDisassembler::Fail; 4070226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4071226633Sdim return MCDisassembler::Fail; 4072226633Sdim 4073226633Sdim return S; 4074226633Sdim} 4075226633Sdim 4076226633Sdim 4077234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 4078226633Sdim uint64_t Address, const void *Decoder) { 4079226633Sdim DecodeStatus S = MCDisassembler::Success; 4080226633Sdim 4081239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4082239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4083239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4084239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4085239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4086239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4087226633Sdim 4088226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4089226633Sdim 4090226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4091226633Sdim return MCDisassembler::Fail; 4092226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4093226633Sdim return MCDisassembler::Fail; 4094226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 4095226633Sdim return MCDisassembler::Fail; 4096226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4097226633Sdim return MCDisassembler::Fail; 4098226633Sdim 4099226633Sdim return S; 4100226633Sdim} 4101226633Sdim 4102234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 4103226633Sdim uint64_t Address, const void *Decoder) { 4104226633Sdim DecodeStatus S = MCDisassembler::Success; 4105226633Sdim 4106239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4107239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4108239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4109239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4110239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4111239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4112226633Sdim 4113226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4114226633Sdim 4115226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4116226633Sdim return MCDisassembler::Fail; 4117226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4118226633Sdim return MCDisassembler::Fail; 4119226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 4120226633Sdim return MCDisassembler::Fail; 4121226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4122226633Sdim return MCDisassembler::Fail; 4123226633Sdim 4124226633Sdim return S; 4125226633Sdim} 4126226633Sdim 4127234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 4128226633Sdim uint64_t Address, const void *Decoder) { 4129226633Sdim DecodeStatus S = MCDisassembler::Success; 4130226633Sdim 4131239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4132239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4133239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4134239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4135239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4136226633Sdim 4137226633Sdim unsigned align = 0; 4138226633Sdim unsigned index = 0; 4139226633Sdim switch (size) { 4140226633Sdim default: 4141226633Sdim return MCDisassembler::Fail; 4142226633Sdim case 0: 4143239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4144226633Sdim return MCDisassembler::Fail; // UNDEFINED 4145239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4146226633Sdim break; 4147226633Sdim case 1: 4148239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4149226633Sdim return MCDisassembler::Fail; // UNDEFINED 4150239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4151239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4152226633Sdim align = 2; 4153226633Sdim break; 4154226633Sdim case 2: 4155239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4156226633Sdim return MCDisassembler::Fail; // UNDEFINED 4157239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4158243830Sdim 4159243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4160243830Sdim case 0 : 4161243830Sdim align = 0; break; 4162243830Sdim case 3: 4163243830Sdim align = 4; break; 4164243830Sdim default: 4165243830Sdim return MCDisassembler::Fail; 4166243830Sdim } 4167243830Sdim break; 4168206124Srdivacky } 4169206124Srdivacky 4170226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4171226633Sdim return MCDisassembler::Fail; 4172226633Sdim if (Rm != 0xF) { // Writeback 4173226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4174226633Sdim return MCDisassembler::Fail; 4175226633Sdim } 4176226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4177226633Sdim return MCDisassembler::Fail; 4178226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4179226633Sdim if (Rm != 0xF) { 4180226633Sdim if (Rm != 0xD) { 4181226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4182226633Sdim return MCDisassembler::Fail; 4183226633Sdim } else 4184226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4185226633Sdim } 4186206124Srdivacky 4187226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4188226633Sdim return MCDisassembler::Fail; 4189226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4190206124Srdivacky 4191226633Sdim return S; 4192226633Sdim} 4193206124Srdivacky 4194234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 4195226633Sdim uint64_t Address, const void *Decoder) { 4196226633Sdim DecodeStatus S = MCDisassembler::Success; 4197206124Srdivacky 4198239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4199239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4200239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4201239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4202239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4203207618Srdivacky 4204226633Sdim unsigned align = 0; 4205226633Sdim unsigned index = 0; 4206226633Sdim switch (size) { 4207226633Sdim default: 4208226633Sdim return MCDisassembler::Fail; 4209226633Sdim case 0: 4210239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4211226633Sdim return MCDisassembler::Fail; // UNDEFINED 4212239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4213226633Sdim break; 4214226633Sdim case 1: 4215239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4216226633Sdim return MCDisassembler::Fail; // UNDEFINED 4217239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4218239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4219226633Sdim align = 2; 4220226633Sdim break; 4221226633Sdim case 2: 4222239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4223226633Sdim return MCDisassembler::Fail; // UNDEFINED 4224239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4225243830Sdim 4226243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4227243830Sdim case 0: 4228243830Sdim align = 0; break; 4229243830Sdim case 3: 4230243830Sdim align = 4; break; 4231243830Sdim default: 4232243830Sdim return MCDisassembler::Fail; 4233243830Sdim } 4234243830Sdim break; 4235226633Sdim } 4236221345Sdim 4237226633Sdim if (Rm != 0xF) { // Writeback 4238226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4239226633Sdim return MCDisassembler::Fail; 4240226633Sdim } 4241226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4242226633Sdim return MCDisassembler::Fail; 4243226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4244226633Sdim if (Rm != 0xF) { 4245226633Sdim if (Rm != 0xD) { 4246226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4247226633Sdim return MCDisassembler::Fail; 4248226633Sdim } else 4249226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4250226633Sdim } 4251206124Srdivacky 4252226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4253226633Sdim return MCDisassembler::Fail; 4254226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4255226633Sdim 4256226633Sdim return S; 4257206124Srdivacky} 4258206124Srdivacky 4259226633Sdim 4260234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 4261226633Sdim uint64_t Address, const void *Decoder) { 4262226633Sdim DecodeStatus S = MCDisassembler::Success; 4263226633Sdim 4264239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4265239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4266239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4267239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4268239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4269226633Sdim 4270226633Sdim unsigned align = 0; 4271226633Sdim unsigned index = 0; 4272226633Sdim unsigned inc = 1; 4273226633Sdim switch (size) { 4274226633Sdim default: 4275226633Sdim return MCDisassembler::Fail; 4276226633Sdim case 0: 4277239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4278239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4279226633Sdim align = 2; 4280226633Sdim break; 4281226633Sdim case 1: 4282239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4283239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4284226633Sdim align = 4; 4285239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4286226633Sdim inc = 2; 4287226633Sdim break; 4288226633Sdim case 2: 4289239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4290226633Sdim return MCDisassembler::Fail; // UNDEFINED 4291239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4292239462Sdim if (fieldFromInstruction(Insn, 4, 1) != 0) 4293226633Sdim align = 8; 4294239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4295226633Sdim inc = 2; 4296226633Sdim break; 4297207618Srdivacky } 4298226633Sdim 4299226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4300226633Sdim return MCDisassembler::Fail; 4301226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4302226633Sdim return MCDisassembler::Fail; 4303226633Sdim if (Rm != 0xF) { // Writeback 4304226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4305226633Sdim return MCDisassembler::Fail; 4306226633Sdim } 4307226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4308226633Sdim return MCDisassembler::Fail; 4309226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4310226633Sdim if (Rm != 0xF) { 4311226633Sdim if (Rm != 0xD) { 4312226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4313226633Sdim return MCDisassembler::Fail; 4314226633Sdim } else 4315226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4316226633Sdim } 4317226633Sdim 4318226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4319226633Sdim return MCDisassembler::Fail; 4320226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4321226633Sdim return MCDisassembler::Fail; 4322226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4323226633Sdim 4324226633Sdim return S; 4325206124Srdivacky} 4326206124Srdivacky 4327234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 4328226633Sdim uint64_t Address, const void *Decoder) { 4329226633Sdim DecodeStatus S = MCDisassembler::Success; 4330207618Srdivacky 4331239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4332239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4333239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4334239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4335239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4336226633Sdim 4337226633Sdim unsigned align = 0; 4338226633Sdim unsigned index = 0; 4339226633Sdim unsigned inc = 1; 4340226633Sdim switch (size) { 4341226633Sdim default: 4342226633Sdim return MCDisassembler::Fail; 4343226633Sdim case 0: 4344239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4345239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4346226633Sdim align = 2; 4347226633Sdim break; 4348226633Sdim case 1: 4349239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4350239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4351226633Sdim align = 4; 4352239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4353226633Sdim inc = 2; 4354226633Sdim break; 4355226633Sdim case 2: 4356239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4357226633Sdim return MCDisassembler::Fail; // UNDEFINED 4358239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4359239462Sdim if (fieldFromInstruction(Insn, 4, 1) != 0) 4360226633Sdim align = 8; 4361239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4362226633Sdim inc = 2; 4363226633Sdim break; 4364207618Srdivacky } 4365226633Sdim 4366226633Sdim if (Rm != 0xF) { // Writeback 4367226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4368226633Sdim return MCDisassembler::Fail; 4369207618Srdivacky } 4370226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4371226633Sdim return MCDisassembler::Fail; 4372226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4373226633Sdim if (Rm != 0xF) { 4374226633Sdim if (Rm != 0xD) { 4375226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4376226633Sdim return MCDisassembler::Fail; 4377226633Sdim } else 4378226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4379226633Sdim } 4380207618Srdivacky 4381226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4382226633Sdim return MCDisassembler::Fail; 4383226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4384226633Sdim return MCDisassembler::Fail; 4385226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4386207618Srdivacky 4387226633Sdim return S; 4388206124Srdivacky} 4389206124Srdivacky 4390226633Sdim 4391234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 4392226633Sdim uint64_t Address, const void *Decoder) { 4393226633Sdim DecodeStatus S = MCDisassembler::Success; 4394226633Sdim 4395239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4396239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4397239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4398239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4399239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4400226633Sdim 4401226633Sdim unsigned align = 0; 4402226633Sdim unsigned index = 0; 4403226633Sdim unsigned inc = 1; 4404226633Sdim switch (size) { 4405226633Sdim default: 4406226633Sdim return MCDisassembler::Fail; 4407226633Sdim case 0: 4408239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4409226633Sdim return MCDisassembler::Fail; // UNDEFINED 4410239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4411226633Sdim break; 4412226633Sdim case 1: 4413239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4414226633Sdim return MCDisassembler::Fail; // UNDEFINED 4415239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4416239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4417226633Sdim inc = 2; 4418226633Sdim break; 4419226633Sdim case 2: 4420239462Sdim if (fieldFromInstruction(Insn, 4, 2)) 4421226633Sdim return MCDisassembler::Fail; // UNDEFINED 4422239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4423239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4424226633Sdim inc = 2; 4425226633Sdim break; 4426206124Srdivacky } 4427226633Sdim 4428226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4429226633Sdim return MCDisassembler::Fail; 4430226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4431226633Sdim return MCDisassembler::Fail; 4432226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4433226633Sdim return MCDisassembler::Fail; 4434226633Sdim 4435226633Sdim if (Rm != 0xF) { // Writeback 4436226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4437226633Sdim return MCDisassembler::Fail; 4438226633Sdim } 4439226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4440226633Sdim return MCDisassembler::Fail; 4441226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4442226633Sdim if (Rm != 0xF) { 4443226633Sdim if (Rm != 0xD) { 4444226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4445226633Sdim return MCDisassembler::Fail; 4446226633Sdim } else 4447226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4448226633Sdim } 4449226633Sdim 4450226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4451226633Sdim return MCDisassembler::Fail; 4452226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4453226633Sdim return MCDisassembler::Fail; 4454226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4455226633Sdim return MCDisassembler::Fail; 4456226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4457226633Sdim 4458226633Sdim return S; 4459206124Srdivacky} 4460206124Srdivacky 4461234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 4462226633Sdim uint64_t Address, const void *Decoder) { 4463226633Sdim DecodeStatus S = MCDisassembler::Success; 4464226633Sdim 4465239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4466239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4467239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4468239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4469239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4470226633Sdim 4471226633Sdim unsigned align = 0; 4472226633Sdim unsigned index = 0; 4473226633Sdim unsigned inc = 1; 4474226633Sdim switch (size) { 4475226633Sdim default: 4476226633Sdim return MCDisassembler::Fail; 4477226633Sdim case 0: 4478239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4479226633Sdim return MCDisassembler::Fail; // UNDEFINED 4480239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4481226633Sdim break; 4482226633Sdim case 1: 4483239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4484226633Sdim return MCDisassembler::Fail; // UNDEFINED 4485239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4486239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4487226633Sdim inc = 2; 4488226633Sdim break; 4489226633Sdim case 2: 4490239462Sdim if (fieldFromInstruction(Insn, 4, 2)) 4491226633Sdim return MCDisassembler::Fail; // UNDEFINED 4492239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4493239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4494226633Sdim inc = 2; 4495226633Sdim break; 4496226633Sdim } 4497226633Sdim 4498226633Sdim if (Rm != 0xF) { // Writeback 4499226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4500226633Sdim return MCDisassembler::Fail; 4501226633Sdim } 4502226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4503226633Sdim return MCDisassembler::Fail; 4504226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4505226633Sdim if (Rm != 0xF) { 4506226633Sdim if (Rm != 0xD) { 4507226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4508226633Sdim return MCDisassembler::Fail; 4509226633Sdim } else 4510226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4511226633Sdim } 4512226633Sdim 4513226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4514226633Sdim return MCDisassembler::Fail; 4515226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4516226633Sdim return MCDisassembler::Fail; 4517226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4518226633Sdim return MCDisassembler::Fail; 4519226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4520226633Sdim 4521226633Sdim return S; 4522206124Srdivacky} 4523206124Srdivacky 4524226633Sdim 4525234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 4526226633Sdim uint64_t Address, const void *Decoder) { 4527226633Sdim DecodeStatus S = MCDisassembler::Success; 4528226633Sdim 4529239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4530239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4531239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4532239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4533239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4534226633Sdim 4535226633Sdim unsigned align = 0; 4536226633Sdim unsigned index = 0; 4537226633Sdim unsigned inc = 1; 4538226633Sdim switch (size) { 4539226633Sdim default: 4540226633Sdim return MCDisassembler::Fail; 4541226633Sdim case 0: 4542239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4543226633Sdim align = 4; 4544239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4545226633Sdim break; 4546226633Sdim case 1: 4547239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4548226633Sdim align = 8; 4549239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4550239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4551226633Sdim inc = 2; 4552226633Sdim break; 4553226633Sdim case 2: 4554243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4555243830Sdim case 0: 4556243830Sdim align = 0; break; 4557243830Sdim case 3: 4558243830Sdim return MCDisassembler::Fail; 4559243830Sdim default: 4560243830Sdim align = 4 << fieldFromInstruction(Insn, 4, 2); break; 4561243830Sdim } 4562243830Sdim 4563239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4564239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4565226633Sdim inc = 2; 4566226633Sdim break; 4567226633Sdim } 4568226633Sdim 4569226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4570226633Sdim return MCDisassembler::Fail; 4571226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4572226633Sdim return MCDisassembler::Fail; 4573226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4574226633Sdim return MCDisassembler::Fail; 4575226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4576226633Sdim return MCDisassembler::Fail; 4577226633Sdim 4578226633Sdim if (Rm != 0xF) { // Writeback 4579226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4580226633Sdim return MCDisassembler::Fail; 4581226633Sdim } 4582226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4583226633Sdim return MCDisassembler::Fail; 4584226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4585226633Sdim if (Rm != 0xF) { 4586226633Sdim if (Rm != 0xD) { 4587226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4588226633Sdim return MCDisassembler::Fail; 4589226633Sdim } else 4590226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4591226633Sdim } 4592226633Sdim 4593226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4594226633Sdim return MCDisassembler::Fail; 4595226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4596226633Sdim return MCDisassembler::Fail; 4597226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4598226633Sdim return MCDisassembler::Fail; 4599226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4600226633Sdim return MCDisassembler::Fail; 4601226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4602226633Sdim 4603226633Sdim return S; 4604206124Srdivacky} 4605206124Srdivacky 4606234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 4607226633Sdim uint64_t Address, const void *Decoder) { 4608226633Sdim DecodeStatus S = MCDisassembler::Success; 4609226633Sdim 4610239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4611239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4612239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4613239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4614239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4615226633Sdim 4616226633Sdim unsigned align = 0; 4617226633Sdim unsigned index = 0; 4618226633Sdim unsigned inc = 1; 4619226633Sdim switch (size) { 4620226633Sdim default: 4621226633Sdim return MCDisassembler::Fail; 4622226633Sdim case 0: 4623239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4624226633Sdim align = 4; 4625239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4626226633Sdim break; 4627226633Sdim case 1: 4628239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4629226633Sdim align = 8; 4630239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4631239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4632226633Sdim inc = 2; 4633226633Sdim break; 4634226633Sdim case 2: 4635243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4636243830Sdim case 0: 4637243830Sdim align = 0; break; 4638243830Sdim case 3: 4639243830Sdim return MCDisassembler::Fail; 4640243830Sdim default: 4641243830Sdim align = 4 << fieldFromInstruction(Insn, 4, 2); break; 4642243830Sdim } 4643243830Sdim 4644239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4645239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4646226633Sdim inc = 2; 4647226633Sdim break; 4648226633Sdim } 4649226633Sdim 4650226633Sdim if (Rm != 0xF) { // Writeback 4651226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4652226633Sdim return MCDisassembler::Fail; 4653226633Sdim } 4654226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4655226633Sdim return MCDisassembler::Fail; 4656226633Sdim Inst.addOperand(MCOperand::CreateImm(align)); 4657226633Sdim if (Rm != 0xF) { 4658226633Sdim if (Rm != 0xD) { 4659226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4660226633Sdim return MCDisassembler::Fail; 4661226633Sdim } else 4662226633Sdim Inst.addOperand(MCOperand::CreateReg(0)); 4663226633Sdim } 4664226633Sdim 4665226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4666226633Sdim return MCDisassembler::Fail; 4667226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 4668226633Sdim return MCDisassembler::Fail; 4669226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 4670226633Sdim return MCDisassembler::Fail; 4671226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 4672226633Sdim return MCDisassembler::Fail; 4673226633Sdim Inst.addOperand(MCOperand::CreateImm(index)); 4674226633Sdim 4675226633Sdim return S; 4676206124Srdivacky} 4677206124Srdivacky 4678234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 4679226633Sdim uint64_t Address, const void *Decoder) { 4680226633Sdim DecodeStatus S = MCDisassembler::Success; 4681239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4682239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 4683239462Sdim unsigned Rm = fieldFromInstruction(Insn, 5, 1); 4684239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4685239462Sdim Rm |= fieldFromInstruction(Insn, 0, 4) << 1; 4686226633Sdim 4687226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 4688226633Sdim S = MCDisassembler::SoftFail; 4689226633Sdim 4690226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 4691226633Sdim return MCDisassembler::Fail; 4692226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 4693226633Sdim return MCDisassembler::Fail; 4694226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 4695226633Sdim return MCDisassembler::Fail; 4696226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 4697226633Sdim return MCDisassembler::Fail; 4698226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4699226633Sdim return MCDisassembler::Fail; 4700226633Sdim 4701226633Sdim return S; 4702207618Srdivacky} 4703207618Srdivacky 4704234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 4705226633Sdim uint64_t Address, const void *Decoder) { 4706226633Sdim DecodeStatus S = MCDisassembler::Success; 4707239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4708239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 4709239462Sdim unsigned Rm = fieldFromInstruction(Insn, 5, 1); 4710239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4711239462Sdim Rm |= fieldFromInstruction(Insn, 0, 4) << 1; 4712226633Sdim 4713226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 4714226633Sdim S = MCDisassembler::SoftFail; 4715226633Sdim 4716226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 4717226633Sdim return MCDisassembler::Fail; 4718226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 4719226633Sdim return MCDisassembler::Fail; 4720226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 4721226633Sdim return MCDisassembler::Fail; 4722226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 4723226633Sdim return MCDisassembler::Fail; 4724226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4725226633Sdim return MCDisassembler::Fail; 4726226633Sdim 4727226633Sdim return S; 4728207618Srdivacky} 4729226633Sdim 4730234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, 4731226633Sdim uint64_t Address, const void *Decoder) { 4732226633Sdim DecodeStatus S = MCDisassembler::Success; 4733239462Sdim unsigned pred = fieldFromInstruction(Insn, 4, 4); 4734239462Sdim unsigned mask = fieldFromInstruction(Insn, 0, 4); 4735226633Sdim 4736226633Sdim if (pred == 0xF) { 4737226633Sdim pred = 0xE; 4738226633Sdim S = MCDisassembler::SoftFail; 4739226633Sdim } 4740226633Sdim 4741263508Sdim if (mask == 0x0) 4742263508Sdim return MCDisassembler::Fail; 4743226633Sdim 4744226633Sdim Inst.addOperand(MCOperand::CreateImm(pred)); 4745226633Sdim Inst.addOperand(MCOperand::CreateImm(mask)); 4746226633Sdim return S; 4747226633Sdim} 4748226633Sdim 4749226633Sdimstatic DecodeStatus 4750234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn, 4751226633Sdim uint64_t Address, const void *Decoder) { 4752226633Sdim DecodeStatus S = MCDisassembler::Success; 4753226633Sdim 4754239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4755239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); 4756239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4757239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 4758239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 4759239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 4760239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 4761226633Sdim bool writeback = (W == 1) | (P == 0); 4762226633Sdim 4763226633Sdim addr |= (U << 8) | (Rn << 9); 4764226633Sdim 4765226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 4766226633Sdim Check(S, MCDisassembler::SoftFail); 4767226633Sdim if (Rt == Rt2) 4768226633Sdim Check(S, MCDisassembler::SoftFail); 4769226633Sdim 4770226633Sdim // Rt 4771226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4772226633Sdim return MCDisassembler::Fail; 4773226633Sdim // Rt2 4774226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 4775226633Sdim return MCDisassembler::Fail; 4776226633Sdim // Writeback operand 4777226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4778226633Sdim return MCDisassembler::Fail; 4779226633Sdim // addr 4780226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 4781226633Sdim return MCDisassembler::Fail; 4782226633Sdim 4783226633Sdim return S; 4784226633Sdim} 4785226633Sdim 4786226633Sdimstatic DecodeStatus 4787234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn, 4788226633Sdim uint64_t Address, const void *Decoder) { 4789226633Sdim DecodeStatus S = MCDisassembler::Success; 4790226633Sdim 4791239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4792239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); 4793239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4794239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 4795239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 4796239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 4797239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 4798226633Sdim bool writeback = (W == 1) | (P == 0); 4799226633Sdim 4800226633Sdim addr |= (U << 8) | (Rn << 9); 4801226633Sdim 4802226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 4803226633Sdim Check(S, MCDisassembler::SoftFail); 4804226633Sdim 4805226633Sdim // Writeback operand 4806226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4807226633Sdim return MCDisassembler::Fail; 4808226633Sdim // Rt 4809226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4810226633Sdim return MCDisassembler::Fail; 4811226633Sdim // Rt2 4812226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 4813226633Sdim return MCDisassembler::Fail; 4814226633Sdim // addr 4815226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 4816226633Sdim return MCDisassembler::Fail; 4817226633Sdim 4818226633Sdim return S; 4819226633Sdim} 4820226633Sdim 4821234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, 4822226633Sdim uint64_t Address, const void *Decoder) { 4823239462Sdim unsigned sign1 = fieldFromInstruction(Insn, 21, 1); 4824239462Sdim unsigned sign2 = fieldFromInstruction(Insn, 23, 1); 4825226633Sdim if (sign1 != sign2) return MCDisassembler::Fail; 4826226633Sdim 4827239462Sdim unsigned Val = fieldFromInstruction(Insn, 0, 8); 4828239462Sdim Val |= fieldFromInstruction(Insn, 12, 3) << 8; 4829239462Sdim Val |= fieldFromInstruction(Insn, 26, 1) << 11; 4830226633Sdim Val |= sign1 << 12; 4831226633Sdim Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val))); 4832226633Sdim 4833226633Sdim return MCDisassembler::Success; 4834226633Sdim} 4835226633Sdim 4836234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val, 4837226633Sdim uint64_t Address, 4838226633Sdim const void *Decoder) { 4839226633Sdim DecodeStatus S = MCDisassembler::Success; 4840226633Sdim 4841226633Sdim // Shift of "asr #32" is not allowed in Thumb2 mode. 4842226633Sdim if (Val == 0x20) S = MCDisassembler::SoftFail; 4843226633Sdim Inst.addOperand(MCOperand::CreateImm(Val)); 4844226633Sdim return S; 4845226633Sdim} 4846226633Sdim 4847234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 4848234353Sdim uint64_t Address, const void *Decoder) { 4849239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4850239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 0, 4); 4851239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4852239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4853234353Sdim 4854234353Sdim if (pred == 0xF) 4855234353Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 4856234353Sdim 4857234353Sdim DecodeStatus S = MCDisassembler::Success; 4858234982Sdim 4859234982Sdim if (Rt == Rn || Rn == Rt2) 4860234982Sdim S = MCDisassembler::SoftFail; 4861234982Sdim 4862234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4863234353Sdim return MCDisassembler::Fail; 4864234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 4865234353Sdim return MCDisassembler::Fail; 4866234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4867234353Sdim return MCDisassembler::Fail; 4868234353Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4869234353Sdim return MCDisassembler::Fail; 4870234353Sdim 4871234353Sdim return S; 4872234353Sdim} 4873234353Sdim 4874234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 4875234353Sdim uint64_t Address, const void *Decoder) { 4876239462Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 4877239462Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 4878239462Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 4879239462Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 4880239462Sdim unsigned imm = fieldFromInstruction(Insn, 16, 6); 4881239462Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 4882263508Sdim unsigned op = fieldFromInstruction(Insn, 5, 1); 4883234353Sdim 4884234353Sdim DecodeStatus S = MCDisassembler::Success; 4885234353Sdim 4886234353Sdim // VMOVv2f32 is ambiguous with these decodings. 4887234353Sdim if (!(imm & 0x38) && cmode == 0xF) { 4888263508Sdim if (op == 1) return MCDisassembler::Fail; 4889234353Sdim Inst.setOpcode(ARM::VMOVv2f32); 4890234353Sdim return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); 4891234353Sdim } 4892234353Sdim 4893263508Sdim if (!(imm & 0x20)) return MCDisassembler::Fail; 4894234353Sdim 4895234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 4896234353Sdim return MCDisassembler::Fail; 4897234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder))) 4898234353Sdim return MCDisassembler::Fail; 4899234353Sdim Inst.addOperand(MCOperand::CreateImm(64 - imm)); 4900234353Sdim 4901234353Sdim return S; 4902234353Sdim} 4903234353Sdim 4904234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 4905234353Sdim uint64_t Address, const void *Decoder) { 4906239462Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 4907239462Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 4908239462Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 4909239462Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 4910239462Sdim unsigned imm = fieldFromInstruction(Insn, 16, 6); 4911239462Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 4912263508Sdim unsigned op = fieldFromInstruction(Insn, 5, 1); 4913234353Sdim 4914234353Sdim DecodeStatus S = MCDisassembler::Success; 4915234353Sdim 4916234353Sdim // VMOVv4f32 is ambiguous with these decodings. 4917234353Sdim if (!(imm & 0x38) && cmode == 0xF) { 4918263508Sdim if (op == 1) return MCDisassembler::Fail; 4919234353Sdim Inst.setOpcode(ARM::VMOVv4f32); 4920234353Sdim return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); 4921234353Sdim } 4922234353Sdim 4923263508Sdim if (!(imm & 0x20)) return MCDisassembler::Fail; 4924234353Sdim 4925234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder))) 4926234353Sdim return MCDisassembler::Fail; 4927234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder))) 4928234353Sdim return MCDisassembler::Fail; 4929234353Sdim Inst.addOperand(MCOperand::CreateImm(64 - imm)); 4930234353Sdim 4931234353Sdim return S; 4932234353Sdim} 4933234353Sdim 4934234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 4935234353Sdim uint64_t Address, const void *Decoder) { 4936234353Sdim DecodeStatus S = MCDisassembler::Success; 4937234353Sdim 4938239462Sdim unsigned Rn = fieldFromInstruction(Val, 16, 4); 4939239462Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 4940239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 4941239462Sdim Rm |= (fieldFromInstruction(Val, 23, 1) << 4); 4942239462Sdim unsigned Cond = fieldFromInstruction(Val, 28, 4); 4943234353Sdim 4944239462Sdim if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt) 4945234353Sdim S = MCDisassembler::SoftFail; 4946234353Sdim 4947234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4948234353Sdim return MCDisassembler::Fail; 4949234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4950234353Sdim return MCDisassembler::Fail; 4951234353Sdim if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder))) 4952234353Sdim return MCDisassembler::Fail; 4953234353Sdim if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder))) 4954234353Sdim return MCDisassembler::Fail; 4955234353Sdim if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder))) 4956234353Sdim return MCDisassembler::Fail; 4957234353Sdim 4958234353Sdim return S; 4959234353Sdim} 4960234353Sdim 4961234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, 4962234982Sdim uint64_t Address, const void *Decoder) { 4963234982Sdim 4964234982Sdim DecodeStatus S = MCDisassembler::Success; 4965234982Sdim 4966239462Sdim unsigned CRm = fieldFromInstruction(Val, 0, 4); 4967239462Sdim unsigned opc1 = fieldFromInstruction(Val, 4, 4); 4968239462Sdim unsigned cop = fieldFromInstruction(Val, 8, 4); 4969239462Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 4970239462Sdim unsigned Rt2 = fieldFromInstruction(Val, 16, 4); 4971234982Sdim 4972234982Sdim if ((cop & ~0x1) == 0xa) 4973234982Sdim return MCDisassembler::Fail; 4974234982Sdim 4975234982Sdim if (Rt == Rt2) 4976234982Sdim S = MCDisassembler::SoftFail; 4977234982Sdim 4978234982Sdim Inst.addOperand(MCOperand::CreateImm(cop)); 4979234982Sdim Inst.addOperand(MCOperand::CreateImm(opc1)); 4980234982Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 4981234982Sdim return MCDisassembler::Fail; 4982234982Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 4983234982Sdim return MCDisassembler::Fail; 4984234982Sdim Inst.addOperand(MCOperand::CreateImm(CRm)); 4985234982Sdim 4986234982Sdim return S; 4987234982Sdim} 4988234982Sdim 4989