1327952Sdim//===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA ---------------===// 2206124Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6206124Srdivacky// 7206124Srdivacky//===----------------------------------------------------------------------===// 8206124Srdivacky 9353358Sdim#include "ARMBaseInstrInfo.h" 10226633Sdim#include "MCTargetDesc/ARMAddressingModes.h" 11249423Sdim#include "MCTargetDesc/ARMBaseInfo.h" 12321369Sdim#include "MCTargetDesc/ARMMCTargetDesc.h" 13353358Sdim#include "TargetInfo/ARMTargetInfo.h" 14327952Sdim#include "Utils/ARMBaseInfo.h" 15249423Sdim#include "llvm/MC/MCContext.h" 16321369Sdim#include "llvm/MC/MCDisassembler/MCDisassembler.h" 17249423Sdim#include "llvm/MC/MCFixedLenDisassembler.h" 18206124Srdivacky#include "llvm/MC/MCInst.h" 19234353Sdim#include "llvm/MC/MCInstrDesc.h" 20234353Sdim#include "llvm/MC/MCSubtargetInfo.h" 21321369Sdim#include "llvm/MC/SubtargetFeature.h" 22321369Sdim#include "llvm/Support/Compiler.h" 23206124Srdivacky#include "llvm/Support/ErrorHandling.h" 24321369Sdim#include "llvm/Support/MathExtras.h" 25226633Sdim#include "llvm/Support/TargetRegistry.h" 26206124Srdivacky#include "llvm/Support/raw_ostream.h" 27321369Sdim#include <algorithm> 28321369Sdim#include <cassert> 29321369Sdim#include <cstdint> 30239462Sdim#include <vector> 31206124Srdivacky 32226633Sdimusing namespace llvm; 33212904Sdim 34276479Sdim#define DEBUG_TYPE "arm-disassembler" 35276479Sdim 36327952Sdimusing DecodeStatus = MCDisassembler::DecodeStatus; 37206124Srdivacky 38226633Sdimnamespace { 39321369Sdim 40239462Sdim // Handles the condition code status of instructions in IT blocks 41239462Sdim class ITStatus 42239462Sdim { 43239462Sdim public: 44239462Sdim // Returns the condition code for instruction in IT block 45239462Sdim unsigned getITCC() { 46239462Sdim unsigned CC = ARMCC::AL; 47239462Sdim if (instrInITBlock()) 48239462Sdim CC = ITStates.back(); 49239462Sdim return CC; 50239462Sdim } 51239462Sdim 52239462Sdim // Advances the IT block state to the next T or E 53239462Sdim void advanceITState() { 54239462Sdim ITStates.pop_back(); 55239462Sdim } 56239462Sdim 57239462Sdim // Returns true if the current instruction is in an IT block 58239462Sdim bool instrInITBlock() { 59239462Sdim return !ITStates.empty(); 60239462Sdim } 61239462Sdim 62239462Sdim // Returns true if current instruction is the last instruction in an IT block 63239462Sdim bool instrLastInITBlock() { 64239462Sdim return ITStates.size() == 1; 65239462Sdim } 66239462Sdim 67353358Sdim // Called when decoding an IT instruction. Sets the IT state for 68353358Sdim // the following instructions that for the IT block. Firstcond 69353358Sdim // corresponds to the field in the IT instruction encoding; Mask 70353358Sdim // is in the MCOperand format in which 1 means 'else' and 0 'then'. 71239462Sdim void setITState(char Firstcond, char Mask) { 72239462Sdim // (3 - the number of trailing zeros) is the number of then / else. 73261991Sdim unsigned NumTZ = countTrailingZeros<uint8_t>(Mask); 74239462Sdim unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf); 75239462Sdim assert(NumTZ <= 3 && "Invalid IT mask!"); 76239462Sdim // push condition codes onto the stack the correct order for the pops 77239462Sdim for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) { 78353358Sdim unsigned Else = (Mask >> Pos) & 1; 79353358Sdim ITStates.push_back(CCBits ^ Else); 80239462Sdim } 81239462Sdim ITStates.push_back(CCBits); 82239462Sdim } 83239462Sdim 84239462Sdim private: 85239462Sdim std::vector<unsigned char> ITStates; 86239462Sdim }; 87239462Sdim 88353358Sdim class VPTStatus 89353358Sdim { 90353358Sdim public: 91353358Sdim unsigned getVPTPred() { 92353358Sdim unsigned Pred = ARMVCC::None; 93353358Sdim if (instrInVPTBlock()) 94353358Sdim Pred = VPTStates.back(); 95353358Sdim return Pred; 96353358Sdim } 97353358Sdim 98353358Sdim void advanceVPTState() { 99353358Sdim VPTStates.pop_back(); 100353358Sdim } 101353358Sdim 102353358Sdim bool instrInVPTBlock() { 103353358Sdim return !VPTStates.empty(); 104353358Sdim } 105353358Sdim 106353358Sdim bool instrLastInVPTBlock() { 107353358Sdim return VPTStates.size() == 1; 108353358Sdim } 109353358Sdim 110353358Sdim void setVPTState(char Mask) { 111353358Sdim // (3 - the number of trailing zeros) is the number of then / else. 112353358Sdim unsigned NumTZ = countTrailingZeros<uint8_t>(Mask); 113353358Sdim assert(NumTZ <= 3 && "Invalid VPT mask!"); 114353358Sdim // push predicates onto the stack the correct order for the pops 115353358Sdim for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) { 116353358Sdim bool T = ((Mask >> Pos) & 1) == 0; 117353358Sdim if (T) 118353358Sdim VPTStates.push_back(ARMVCC::Then); 119353358Sdim else 120353358Sdim VPTStates.push_back(ARMVCC::Else); 121353358Sdim } 122353358Sdim VPTStates.push_back(ARMVCC::Then); 123353358Sdim } 124353358Sdim 125353358Sdim private: 126353358Sdim SmallVector<unsigned char, 4> VPTStates; 127353358Sdim }; 128353358Sdim 129280031Sdim/// ARM disassembler for all ARM platforms. 130226633Sdimclass ARMDisassembler : public MCDisassembler { 131226633Sdimpublic: 132276479Sdim ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : 133276479Sdim MCDisassembler(STI, Ctx) { 134226633Sdim } 135226633Sdim 136321369Sdim ~ARMDisassembler() override = default; 137226633Sdim 138280031Sdim DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 139280031Sdim ArrayRef<uint8_t> Bytes, uint64_t Address, 140280031Sdim raw_ostream &CStream) const override; 141226633Sdim 142353358Sdimprivate: 143353358Sdim DecodeStatus getARMInstruction(MCInst &Instr, uint64_t &Size, 144353358Sdim ArrayRef<uint8_t> Bytes, uint64_t Address, 145353358Sdim raw_ostream &CStream) const; 146226633Sdim 147353358Sdim DecodeStatus getThumbInstruction(MCInst &Instr, uint64_t &Size, 148353358Sdim ArrayRef<uint8_t> Bytes, uint64_t Address, 149353358Sdim raw_ostream &CStream) const; 150226633Sdim 151239462Sdim mutable ITStatus ITBlock; 152353358Sdim mutable VPTStatus VPTBlock; 153327952Sdim 154226633Sdim DecodeStatus AddThumbPredicate(MCInst&) const; 155353358Sdim void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const; 156226633Sdim}; 157226633Sdim 158321369Sdim} // end anonymous namespace 159321369Sdim 160226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) { 161226633Sdim switch (In) { 162226633Sdim case MCDisassembler::Success: 163226633Sdim // Out stays the same. 164226633Sdim return true; 165226633Sdim case MCDisassembler::SoftFail: 166226633Sdim Out = In; 167226633Sdim return true; 168226633Sdim case MCDisassembler::Fail: 169226633Sdim Out = In; 170226633Sdim return false; 171226633Sdim } 172234353Sdim llvm_unreachable("Invalid DecodeStatus!"); 173226633Sdim} 174226633Sdim 175226633Sdim// Forward declare these because the autogenerated code will reference them. 176226633Sdim// Definitions are further down. 177234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 178226633Sdim uint64_t Address, const void *Decoder); 179353358Sdimstatic DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo, 180353358Sdim uint64_t Address, const void *Decoder); 181353358Sdimstatic DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo, 182353358Sdim uint64_t Address, const void *Decoder); 183353358Sdimstatic DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo, 184353358Sdim uint64_t Address, const void *Decoder); 185234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, 186226633Sdim unsigned RegNo, uint64_t Address, 187226633Sdim const void *Decoder); 188261991Sdimstatic DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst, 189261991Sdim unsigned RegNo, uint64_t Address, 190261991Sdim const void *Decoder); 191353358Sdimstatic DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst, 192353358Sdim unsigned RegNo, uint64_t Address, 193353358Sdim const void *Decoder); 194353358Sdimstatic DecodeStatus DecodeGPRwithZRnospRegisterClass( 195353358Sdim MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); 196234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 197226633Sdim uint64_t Address, const void *Decoder); 198234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 199226633Sdim uint64_t Address, const void *Decoder); 200234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 201226633Sdim uint64_t Address, const void *Decoder); 202261991Sdimstatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo, 203261991Sdim uint64_t Address, const void *Decoder); 204360784Sdimstatic DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo, 205360784Sdim uint64_t Address, 206360784Sdim const void *Decoder); 207341825Sdimstatic DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo, 208341825Sdim uint64_t Address, const void *Decoder); 209234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 210226633Sdim uint64_t Address, const void *Decoder); 211234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 212226633Sdim uint64_t Address, const void *Decoder); 213234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 214226633Sdim uint64_t Address, const void *Decoder); 215353358Sdimstatic DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 216353358Sdim uint64_t Address, const void *Decoder); 217234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, 218226633Sdim unsigned RegNo, 219226633Sdim uint64_t Address, 220226633Sdim const void *Decoder); 221234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 222226633Sdim uint64_t Address, const void *Decoder); 223353358Sdimstatic DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo, 224353358Sdim uint64_t Address, const void *Decoder); 225353358Sdimstatic DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo, 226353358Sdim uint64_t Address, const void *Decoder); 227353358Sdimstatic DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo, 228353358Sdim uint64_t Address, const void *Decoder); 229234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 230234353Sdim uint64_t Address, const void *Decoder); 231234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 232234353Sdim unsigned RegNo, uint64_t Address, 233234353Sdim const void *Decoder); 234226633Sdim 235234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 236226633Sdim uint64_t Address, const void *Decoder); 237234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 238226633Sdim uint64_t Address, const void *Decoder); 239234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 240226633Sdim uint64_t Address, const void *Decoder); 241234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 242226633Sdim uint64_t Address, const void *Decoder); 243234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 244226633Sdim uint64_t Address, const void *Decoder); 245226633Sdim 246234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn, 247226633Sdim uint64_t Address, const void *Decoder); 248234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 249226633Sdim uint64_t Address, const void *Decoder); 250234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst, 251226633Sdim unsigned Insn, 252226633Sdim uint64_t Address, 253226633Sdim const void *Decoder); 254234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn, 255226633Sdim uint64_t Address, const void *Decoder); 256234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn, 257226633Sdim uint64_t Address, const void *Decoder); 258234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn, 259226633Sdim uint64_t Address, const void *Decoder); 260234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn, 261226633Sdim uint64_t Address, const void *Decoder); 262226633Sdim 263234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst, 264226633Sdim unsigned Insn, 265226633Sdim uint64_t Adddress, 266226633Sdim const void *Decoder); 267234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 268226633Sdim uint64_t Address, const void *Decoder); 269234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 270226633Sdim uint64_t Address, const void *Decoder); 271234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 272226633Sdim uint64_t Address, const void *Decoder); 273309124Sdimstatic DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn, 274309124Sdim uint64_t Address, const void *Decoder); 275234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 276226633Sdim uint64_t Address, const void *Decoder); 277288943Sdimstatic DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn, 278288943Sdim uint64_t Address, const void *Decoder); 279288943Sdimstatic DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn, 280288943Sdim uint64_t Address, const void *Decoder); 281234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 282226633Sdim uint64_t Address, const void *Decoder); 283234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 284226633Sdim uint64_t Address, const void *Decoder); 285234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 286226633Sdim uint64_t Address, const void *Decoder); 287309124Sdimstatic DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val, 288309124Sdim uint64_t Address, const void *Decoder); 289234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 290226633Sdim uint64_t Address, const void *Decoder); 291234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn, 292226633Sdim uint64_t Address, const void *Decoder); 293234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn, 294226633Sdim uint64_t Address, const void *Decoder); 295234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 296226633Sdim uint64_t Address, const void *Decoder); 297261991Sdimstatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val, 298261991Sdim uint64_t Address, const void *Decoder); 299261991Sdimstatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val, 300261991Sdim uint64_t Address, const void *Decoder); 301261991Sdimstatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val, 302261991Sdim uint64_t Address, const void *Decoder); 303261991Sdimstatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val, 304261991Sdim uint64_t Address, const void *Decoder); 305234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val, 306226633Sdim uint64_t Address, const void *Decoder); 307234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val, 308226633Sdim uint64_t Address, const void *Decoder); 309234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val, 310226633Sdim uint64_t Address, const void *Decoder); 311234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val, 312226633Sdim uint64_t Address, const void *Decoder); 313234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val, 314226633Sdim uint64_t Address, const void *Decoder); 315234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val, 316226633Sdim uint64_t Address, const void *Decoder); 317360784Sdimstatic DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst,unsigned Val, 318226633Sdim uint64_t Address, const void *Decoder); 319353358Sdimstatic DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst,unsigned Val, 320353358Sdim uint64_t Address, const void *Decoder); 321353358Sdimstatic DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn, 322353358Sdim uint64_t Address, const void *Decoder); 323234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val, 324226633Sdim uint64_t Address, const void *Decoder); 325234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 326226633Sdim uint64_t Address, const void *Decoder); 327234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 328226633Sdim uint64_t Address, const void *Decoder); 329234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 330226633Sdim uint64_t Address, const void *Decoder); 331234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 332226633Sdim uint64_t Address, const void *Decoder); 333234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 334226633Sdim uint64_t Address, const void *Decoder); 335234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 336226633Sdim uint64_t Address, const void *Decoder); 337353358Sdimstatic DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn, 338353358Sdim uint64_t Address, const void *Decoder); 339353358Sdimtemplate<int shift> 340353358Sdimstatic DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn, 341353358Sdim uint64_t Address, const void *Decoder); 342234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn, 343226633Sdim uint64_t Address, const void *Decoder); 344234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn, 345226633Sdim uint64_t Address, const void *Decoder); 346261991Sdimstatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn, 347261991Sdim uint64_t Address, const void *Decoder); 348234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, 349226633Sdim uint64_t Address, const void *Decoder); 350280031Sdimstatic DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn, 351280031Sdim uint64_t Address, const void *Decoder); 352234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 353226633Sdim uint64_t Address, const void *Decoder); 354234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 355226633Sdim uint64_t Address, const void *Decoder); 356234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 357226633Sdim uint64_t Address, const void *Decoder); 358234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 359226633Sdim uint64_t Address, const void *Decoder); 360234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 361226633Sdim uint64_t Address, const void *Decoder); 362234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 363226633Sdim uint64_t Address, const void *Decoder); 364234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 365226633Sdim uint64_t Address, const void *Decoder); 366234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 367226633Sdim uint64_t Address, const void *Decoder); 368234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 369226633Sdim uint64_t Address, const void *Decoder); 370234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 371226633Sdim uint64_t Address, const void *Decoder); 372234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 373226633Sdim uint64_t Address, const void *Decoder); 374234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 375226633Sdim uint64_t Address, const void *Decoder); 376234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 377226633Sdim uint64_t Address, const void *Decoder); 378234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 379226633Sdim uint64_t Address, const void *Decoder); 380234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 381226633Sdim uint64_t Address, const void *Decoder); 382234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 383226633Sdim uint64_t Address, const void *Decoder); 384234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 385234353Sdim uint64_t Address, const void *Decoder); 386234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 387234353Sdim uint64_t Address, const void *Decoder); 388234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 389234353Sdim uint64_t Address, const void *Decoder); 390353358Sdimstatic DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Insn, 391353358Sdim uint64_t Address, const void *Decoder); 392327952Sdimstatic DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst, 393327952Sdim unsigned Val, 394327952Sdim uint64_t Address, 395327952Sdim const void *Decoder); 396226633Sdim 397234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 398226633Sdim uint64_t Address, const void *Decoder); 399234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 400226633Sdim uint64_t Address, const void *Decoder); 401234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 402226633Sdim uint64_t Address, const void *Decoder); 403234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 404226633Sdim uint64_t Address, const void *Decoder); 405234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 406226633Sdim uint64_t Address, const void *Decoder); 407234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 408226633Sdim uint64_t Address, const void *Decoder); 409234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 410226633Sdim uint64_t Address, const void *Decoder); 411234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 412226633Sdim uint64_t Address, const void *Decoder); 413234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 414226633Sdim uint64_t Address, const void *Decoder); 415234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val, 416226633Sdim uint64_t Address, const void *Decoder); 417261991Sdimstatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn, 418261991Sdim uint64_t Address, const void* Decoder); 419261991Sdimstatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn, 420261991Sdim uint64_t Address, const void* Decoder); 421261991Sdimstatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, 422261991Sdim uint64_t Address, const void* Decoder); 423261991Sdimstatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn, 424261991Sdim uint64_t Address, const void* Decoder); 425234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 426226633Sdim uint64_t Address, const void *Decoder); 427353358Sdimstatic DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, 428353358Sdim uint64_t Address, const void *Decoder); 429234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 430226633Sdim uint64_t Address, const void *Decoder); 431353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val, 432353358Sdim uint64_t Address, 433353358Sdim const void *Decoder); 434234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 435226633Sdim uint64_t Address, const void *Decoder); 436234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 437226633Sdim uint64_t Address, const void *Decoder); 438353358Sdimtemplate<int shift> 439353358Sdimstatic DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, 440353358Sdim uint64_t Address, const void *Decoder); 441234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 442226633Sdim uint64_t Address, const void *Decoder); 443353358Sdimtemplate<int shift> 444353358Sdimstatic DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val, 445353358Sdim uint64_t Address, const void *Decoder); 446353358Sdimtemplate<int shift, int WriteBack> 447353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val, 448353358Sdim uint64_t Address, const void *Decoder); 449234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val, 450226633Sdim uint64_t Address, const void *Decoder); 451234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 452226633Sdim uint64_t Address, const void *Decoder); 453234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 454226633Sdim uint64_t Address, const void *Decoder); 455261991Sdimstatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn, 456261991Sdim uint64_t Address, const void *Decoder); 457234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn, 458226633Sdim uint64_t Address, const void *Decoder); 459234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 460226633Sdim uint64_t Address, const void *Decoder); 461234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val, 462226633Sdim uint64_t Address, const void *Decoder); 463234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val, 464226633Sdim uint64_t Address, const void *Decoder); 465234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 466226633Sdim uint64_t Address, const void *Decoder); 467234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val, 468226633Sdim uint64_t Address, const void *Decoder); 469234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 470226633Sdim uint64_t Address, const void *Decoder); 471234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, 472226633Sdim uint64_t Address, const void *Decoder); 473234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn, 474226633Sdim uint64_t Address, const void *Decoder); 475234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn, 476226633Sdim uint64_t Address, const void *Decoder); 477234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, 478226633Sdim uint64_t Address, const void *Decoder); 479234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val, 480226633Sdim uint64_t Address, const void *Decoder); 481234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, 482226633Sdim uint64_t Address, const void *Decoder); 483226633Sdim 484234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 485234353Sdim uint64_t Address, const void *Decoder); 486321369Sdimstatic DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val, 487309124Sdim uint64_t Address, const void *Decoder); 488327952Sdimstatic DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val, 489327952Sdim uint64_t Address, const void *Decoder); 490321369Sdim 491353358Sdimtemplate <bool isSigned, bool isNeg, bool zeroPermitted, int size> 492353358Sdimstatic DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned val, 493353358Sdim uint64_t Address, const void *Decoder); 494353358Sdimstatic DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned val, 495353358Sdim uint64_t Address, 496353358Sdim const void *Decoder); 497353358Sdimstatic DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val, 498353358Sdim uint64_t Address, 499353358Sdim const void *Decoder); 500353358Sdimstatic DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address, 501353358Sdim const void *Decoder); 502353358Sdimstatic DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val, 503353358Sdim uint64_t Address, 504353358Sdim const void *Decoder); 505353358Sdimstatic DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address, 506353358Sdim const void *Decoder); 507353358Sdimstatic DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val, 508353358Sdim uint64_t Address, const void *Decoder); 509353358Sdimstatic DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val, 510353358Sdim uint64_t Address, const void *Decoder); 511353358Sdimstatic DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, 512353358Sdim uint64_t Address, 513353358Sdim const void *Decoder); 514353358Sdimstatic DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val, 515353358Sdim uint64_t Address, 516353358Sdim const void *Decoder); 517353358Sdimstatic DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val, 518353358Sdim uint64_t Address, 519353358Sdim const void *Decoder); 520353358Sdimstatic DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst, 521353358Sdim unsigned Val, 522353358Sdim uint64_t Address, 523353358Sdim const void *Decoder); 524353358Sdimtemplate<bool Writeback> 525353358Sdimstatic DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn, 526353358Sdim uint64_t Address, 527353358Sdim const void *Decoder); 528353358Sdimtemplate<int shift> 529353358Sdimstatic DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val, 530353358Sdim uint64_t Address, const void *Decoder); 531353358Sdimtemplate<int shift> 532353358Sdimstatic DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val, 533353358Sdim uint64_t Address, const void *Decoder); 534353358Sdimtemplate<int shift> 535353358Sdimstatic DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val, 536353358Sdim uint64_t Address, const void *Decoder); 537353358Sdimtemplate<unsigned MinLog, unsigned MaxLog> 538353358Sdimstatic DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val, 539353358Sdim uint64_t Address, 540353358Sdim const void *Decoder); 541353358Sdimtemplate <int shift> 542353358Sdimstatic DecodeStatus DecodeExpandedImmOperand(MCInst &Inst, unsigned Val, 543353358Sdim uint64_t Address, 544353358Sdim const void *Decoder); 545353358Sdimtemplate<unsigned start> 546353358Sdimstatic DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, 547353358Sdim uint64_t Address, 548353358Sdim const void *Decoder); 549353358Sdimstatic DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn, 550353358Sdim uint64_t Address, 551353358Sdim const void *Decoder); 552353358Sdimstatic DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn, 553353358Sdim uint64_t Address, 554353358Sdim const void *Decoder); 555353358Sdimstatic DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn, 556353358Sdim uint64_t Address, const void *Decoder); 557353358Sdimtypedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val, 558353358Sdim uint64_t Address, const void *Decoder); 559353358Sdimtemplate<bool scalar, OperandDecoder predicate_decoder> 560353358Sdimstatic DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, 561353358Sdim uint64_t Address, const void *Decoder); 562353358Sdimstatic DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, 563353358Sdim uint64_t Address, const void *Decoder); 564360784Sdimstatic DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn, 565360784Sdim uint64_t Address, const void *Decoder); 566353358Sdimstatic DecodeStatus DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, 567353358Sdim uint64_t Address, 568353358Sdim const void *Decoder); 569360784Sdimstatic DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn, 570360784Sdim uint64_t Address, const void *Decoder); 571360784Sdim 572226633Sdim#include "ARMGenDisassemblerTables.inc" 573206124Srdivacky 574276479Sdimstatic MCDisassembler *createARMDisassembler(const Target &T, 575276479Sdim const MCSubtargetInfo &STI, 576276479Sdim MCContext &Ctx) { 577276479Sdim return new ARMDisassembler(STI, Ctx); 578226633Sdim} 579207618Srdivacky 580280031Sdim// Post-decoding checks 581280031Sdimstatic DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size, 582360784Sdim uint64_t Address, raw_ostream &CS, 583280031Sdim uint32_t Insn, 584321369Sdim DecodeStatus Result) { 585280031Sdim switch (MI.getOpcode()) { 586280031Sdim case ARM::HVC: { 587280031Sdim // HVC is undefined if condition = 0xf otherwise upredictable 588280031Sdim // if condition != 0xe 589280031Sdim uint32_t Cond = (Insn >> 28) & 0xF; 590280031Sdim if (Cond == 0xF) 591280031Sdim return MCDisassembler::Fail; 592280031Sdim if (Cond != 0xE) 593280031Sdim return MCDisassembler::SoftFail; 594280031Sdim return Result; 595280031Sdim } 596353358Sdim case ARM::t2ADDri: 597353358Sdim case ARM::t2ADDri12: 598353358Sdim case ARM::t2ADDrr: 599353358Sdim case ARM::t2ADDrs: 600353358Sdim case ARM::t2SUBri: 601353358Sdim case ARM::t2SUBri12: 602353358Sdim case ARM::t2SUBrr: 603353358Sdim case ARM::t2SUBrs: 604353358Sdim if (MI.getOperand(0).getReg() == ARM::SP && 605353358Sdim MI.getOperand(1).getReg() != ARM::SP) 606353358Sdim return MCDisassembler::SoftFail; 607353358Sdim return Result; 608280031Sdim default: return Result; 609280031Sdim } 610280031Sdim} 611280031Sdim 612226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 613280031Sdim ArrayRef<uint8_t> Bytes, 614360784Sdim uint64_t Address, 615280031Sdim raw_ostream &CS) const { 616353358Sdim if (STI.getFeatureBits()[ARM::ModeThumb]) 617360784Sdim return getThumbInstruction(MI, Size, Bytes, Address, CS); 618360784Sdim return getARMInstruction(MI, Size, Bytes, Address, CS); 619353358Sdim} 620353358Sdim 621353358SdimDecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size, 622353358Sdim ArrayRef<uint8_t> Bytes, 623353358Sdim uint64_t Address, 624353358Sdim raw_ostream &CS) const { 625280031Sdim CommentStream = &CS; 626226633Sdim 627288943Sdim assert(!STI.getFeatureBits()[ARM::ModeThumb] && 628280031Sdim "Asked to disassemble an ARM instruction but Subtarget is in Thumb " 629280031Sdim "mode!"); 630226633Sdim 631226633Sdim // We want to read exactly 4 bytes of data. 632280031Sdim if (Bytes.size() < 4) { 633226633Sdim Size = 0; 634226633Sdim return MCDisassembler::Fail; 635206124Srdivacky } 636226633Sdim 637226633Sdim // Encoded as a small-endian 32-bit word in the stream. 638280031Sdim uint32_t Insn = 639280031Sdim (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); 640226633Sdim 641226633Sdim // Calling the auto-generated decoder function. 642280031Sdim DecodeStatus Result = 643280031Sdim decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI); 644280031Sdim if (Result != MCDisassembler::Fail) { 645226633Sdim Size = 4; 646360784Sdim return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result); 647226633Sdim } 648226633Sdim 649321369Sdim struct DecodeTable { 650321369Sdim const uint8_t *P; 651321369Sdim bool DecodePred; 652321369Sdim }; 653226633Sdim 654321369Sdim const DecodeTable Tables[] = { 655321369Sdim {DecoderTableVFP32, false}, {DecoderTableVFPV832, false}, 656321369Sdim {DecoderTableNEONData32, true}, {DecoderTableNEONLoadStore32, true}, 657321369Sdim {DecoderTableNEONDup32, true}, {DecoderTablev8NEON32, false}, 658321369Sdim {DecoderTablev8Crypto32, false}, 659321369Sdim }; 660261991Sdim 661321369Sdim for (auto Table : Tables) { 662321369Sdim Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI); 663321369Sdim if (Result != MCDisassembler::Fail) { 664321369Sdim Size = 4; 665321369Sdim // Add a fake predicate operand, because we share these instruction 666321369Sdim // definitions with Thumb2 where these instructions are predicable. 667321369Sdim if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this)) 668321369Sdim return MCDisassembler::Fail; 669321369Sdim return Result; 670321369Sdim } 671226633Sdim } 672226633Sdim 673327952Sdim Result = 674327952Sdim decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI); 675327952Sdim if (Result != MCDisassembler::Fail) { 676327952Sdim Size = 4; 677360784Sdim return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result); 678327952Sdim } 679327952Sdim 680321369Sdim Size = 4; 681226633Sdim return MCDisassembler::Fail; 682206124Srdivacky} 683206124Srdivacky 684226633Sdimnamespace llvm { 685321369Sdim 686234353Sdimextern const MCInstrDesc ARMInsts[]; 687206124Srdivacky 688321369Sdim} // end namespace llvm 689321369Sdim 690226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 691226633Sdim/// immediate Value in the MCInst. The immediate Value has had any PC 692226633Sdim/// adjustment made by the caller. If the instruction is a branch instruction 693226633Sdim/// then isBranch is true, else false. If the getOpInfo() function was set as 694226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called 695226633Sdim/// to get any symbolic information at the Address for this instruction. If 696226633Sdim/// that returns non-zero then the symbolic information it returns is used to 697226633Sdim/// create an MCExpr and that is added as an operand to the MCInst. If 698226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for 699226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else 700226633Sdim/// an MCExpr with Value is created. This function returns true if it adds an 701226633Sdim/// operand to the MCInst and false otherwise. 702226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value, 703226633Sdim bool isBranch, uint64_t InstSize, 704226633Sdim MCInst &MI, const void *Decoder) { 705226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 706261991Sdim // FIXME: Does it make sense for value to be negative? 707261991Sdim return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch, 708261991Sdim /* Offset */ 0, InstSize); 709226633Sdim} 710226633Sdim 711226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being 712226633Sdim/// referenced by a load instruction with the base register that is the Pc. 713226633Sdim/// These can often be values in a literal pool near the Address of the 714226633Sdim/// instruction. The Address of the instruction and its immediate Value are 715226633Sdim/// used as a possible literal pool entry. The SymbolLookUp call back will 716239462Sdim/// return the name of a symbol referenced by the literal pool's entry if 717226633Sdim/// the referenced address is that of a symbol. Or it will return a pointer to 718226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry 719226633Sdim/// is an address into a section with 'C' string literals. 720226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value, 721234353Sdim const void *Decoder) { 722226633Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 723261991Sdim Dis->tryAddingPcLoadReferenceComment(Value, Address); 724226633Sdim} 725206124Srdivacky 726226633Sdim// Thumb1 instructions don't have explicit S bits. Rather, they 727226633Sdim// implicitly set CPSR. Since it's not represented in the encoding, the 728226633Sdim// auto-generated decoder won't inject the CPSR operand. We need to fix 729226633Sdim// that as a post-pass. 730226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) { 731226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 732226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 733226633Sdim MCInst::iterator I = MI.begin(); 734226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 735226633Sdim if (I == MI.end()) break; 736226633Sdim if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) { 737226633Sdim if (i > 0 && OpInfo[i-1].isPredicate()) continue; 738288943Sdim MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR)); 739226633Sdim return; 740226633Sdim } 741226633Sdim } 742206124Srdivacky 743288943Sdim MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR)); 744226633Sdim} 745206124Srdivacky 746353358Sdimstatic bool isVectorPredicable(unsigned Opcode) { 747353358Sdim const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo; 748353358Sdim unsigned short NumOps = ARMInsts[Opcode].NumOperands; 749353358Sdim for (unsigned i = 0; i < NumOps; ++i) { 750353358Sdim if (ARM::isVpred(OpInfo[i].OperandType)) 751353358Sdim return true; 752353358Sdim } 753353358Sdim return false; 754353358Sdim} 755353358Sdim 756226633Sdim// Most Thumb instructions don't have explicit predicates in the 757226633Sdim// encoding, but rather get their predicates from IT context. We need 758226633Sdim// to fix up the predicate operands using this context information as a 759226633Sdim// post-pass. 760226633SdimMCDisassembler::DecodeStatus 761353358SdimARMDisassembler::AddThumbPredicate(MCInst &MI) const { 762226633Sdim MCDisassembler::DecodeStatus S = Success; 763206124Srdivacky 764309124Sdim const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits(); 765309124Sdim 766226633Sdim // A few instructions actually have predicates encoded in them. Don't 767226633Sdim // try to overwrite it if we're seeing one of those. 768226633Sdim switch (MI.getOpcode()) { 769226633Sdim case ARM::tBcc: 770226633Sdim case ARM::t2Bcc: 771226633Sdim case ARM::tCBZ: 772226633Sdim case ARM::tCBNZ: 773226633Sdim case ARM::tCPS: 774226633Sdim case ARM::t2CPS3p: 775226633Sdim case ARM::t2CPS2p: 776226633Sdim case ARM::t2CPS1p: 777353358Sdim case ARM::t2CSEL: 778353358Sdim case ARM::t2CSINC: 779353358Sdim case ARM::t2CSINV: 780353358Sdim case ARM::t2CSNEG: 781226633Sdim case ARM::tMOVSr: 782226633Sdim case ARM::tSETEND: 783226633Sdim // Some instructions (mostly conditional branches) are not 784226633Sdim // allowed in IT blocks. 785239462Sdim if (ITBlock.instrInITBlock()) 786226633Sdim S = SoftFail; 787226633Sdim else 788226633Sdim return Success; 789226633Sdim break; 790309124Sdim case ARM::t2HINT: 791309124Sdim if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0) 792309124Sdim S = SoftFail; 793309124Sdim break; 794226633Sdim case ARM::tB: 795226633Sdim case ARM::t2B: 796226633Sdim case ARM::t2TBB: 797226633Sdim case ARM::t2TBH: 798226633Sdim // Some instructions (mostly unconditional branches) can 799226633Sdim // only appears at the end of, or outside of, an IT. 800239462Sdim if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock()) 801226633Sdim S = SoftFail; 802226633Sdim break; 803226633Sdim default: 804226633Sdim break; 805226633Sdim } 806226633Sdim 807353358Sdim // Warn on non-VPT predicable instruction in a VPT block and a VPT 808353358Sdim // predicable instruction in an IT block 809353358Sdim if ((!isVectorPredicable(MI.getOpcode()) && VPTBlock.instrInVPTBlock()) || 810353358Sdim (isVectorPredicable(MI.getOpcode()) && ITBlock.instrInITBlock())) 811353358Sdim S = SoftFail; 812353358Sdim 813353358Sdim // If we're in an IT/VPT block, base the predicate on that. Otherwise, 814226633Sdim // assume a predicate of AL. 815353358Sdim unsigned CC = ARMCC::AL; 816353358Sdim unsigned VCC = ARMVCC::None; 817353358Sdim if (ITBlock.instrInITBlock()) { 818353358Sdim CC = ITBlock.getITCC(); 819239462Sdim ITBlock.advanceITState(); 820353358Sdim } else if (VPTBlock.instrInVPTBlock()) { 821353358Sdim VCC = VPTBlock.getVPTPred(); 822353358Sdim VPTBlock.advanceVPTState(); 823353358Sdim } 824226633Sdim 825226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 826226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 827353358Sdim 828353358Sdim MCInst::iterator CCI = MI.begin(); 829353358Sdim for (unsigned i = 0; i < NumOps; ++i, ++CCI) { 830353358Sdim if (OpInfo[i].isPredicate() || CCI == MI.end()) break; 831353358Sdim } 832353358Sdim 833353358Sdim if (ARMInsts[MI.getOpcode()].isPredicable()) { 834353358Sdim CCI = MI.insert(CCI, MCOperand::createImm(CC)); 835353358Sdim ++CCI; 836353358Sdim if (CC == ARMCC::AL) 837353358Sdim MI.insert(CCI, MCOperand::createReg(0)); 838353358Sdim else 839353358Sdim MI.insert(CCI, MCOperand::createReg(ARM::CPSR)); 840353358Sdim } else if (CC != ARMCC::AL) { 841353358Sdim Check(S, SoftFail); 842353358Sdim } 843353358Sdim 844353358Sdim MCInst::iterator VCCI = MI.begin(); 845353358Sdim unsigned VCCPos; 846353358Sdim for (VCCPos = 0; VCCPos < NumOps; ++VCCPos, ++VCCI) { 847353358Sdim if (ARM::isVpred(OpInfo[VCCPos].OperandType) || VCCI == MI.end()) break; 848353358Sdim } 849353358Sdim 850353358Sdim if (isVectorPredicable(MI.getOpcode())) { 851353358Sdim VCCI = MI.insert(VCCI, MCOperand::createImm(VCC)); 852353358Sdim ++VCCI; 853353358Sdim if (VCC == ARMVCC::None) 854353358Sdim MI.insert(VCCI, MCOperand::createReg(0)); 855353358Sdim else 856353358Sdim MI.insert(VCCI, MCOperand::createReg(ARM::P0)); 857353358Sdim if (OpInfo[VCCPos].OperandType == ARM::OPERAND_VPRED_R) { 858353358Sdim int TiedOp = ARMInsts[MI.getOpcode()].getOperandConstraint( 859353358Sdim VCCPos + 2, MCOI::TIED_TO); 860353358Sdim assert(TiedOp >= 0 && 861353358Sdim "Inactive register in vpred_r is not tied to an output!"); 862353358Sdim MI.insert(VCCI, MI.getOperand(TiedOp)); 863226633Sdim } 864353358Sdim } else if (VCC != ARMVCC::None) { 865353358Sdim Check(S, SoftFail); 866226633Sdim } 867226633Sdim 868226633Sdim return S; 869226633Sdim} 870226633Sdim 871226633Sdim// Thumb VFP instructions are a special case. Because we share their 872226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM 873226633Sdim// mode, the auto-generated decoder will give them an (incorrect) 874226633Sdim// predicate operand. We need to rewrite these operands based on the IT 875226633Sdim// context as a post-pass. 876353358Sdimvoid ARMDisassembler::UpdateThumbVFPPredicate( 877353358Sdim DecodeStatus &S, MCInst &MI) const { 878226633Sdim unsigned CC; 879239462Sdim CC = ITBlock.getITCC(); 880341825Sdim if (CC == 0xF) 881341825Sdim CC = ARMCC::AL; 882239462Sdim if (ITBlock.instrInITBlock()) 883239462Sdim ITBlock.advanceITState(); 884353358Sdim else if (VPTBlock.instrInVPTBlock()) { 885353358Sdim CC = VPTBlock.getVPTPred(); 886353358Sdim VPTBlock.advanceVPTState(); 887353358Sdim } 888226633Sdim 889226633Sdim const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; 890226633Sdim MCInst::iterator I = MI.begin(); 891226633Sdim unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; 892226633Sdim for (unsigned i = 0; i < NumOps; ++i, ++I) { 893226633Sdim if (OpInfo[i].isPredicate() ) { 894353358Sdim if (CC != ARMCC::AL && !ARMInsts[MI.getOpcode()].isPredicable()) 895353358Sdim Check(S, SoftFail); 896226633Sdim I->setImm(CC); 897226633Sdim ++I; 898226633Sdim if (CC == ARMCC::AL) 899226633Sdim I->setReg(0); 900226633Sdim else 901226633Sdim I->setReg(ARM::CPSR); 902226633Sdim return; 903226633Sdim } 904226633Sdim } 905226633Sdim} 906226633Sdim 907353358SdimDecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size, 908353358Sdim ArrayRef<uint8_t> Bytes, 909353358Sdim uint64_t Address, 910353358Sdim raw_ostream &CS) const { 911280031Sdim CommentStream = &CS; 912226633Sdim 913288943Sdim assert(STI.getFeatureBits()[ARM::ModeThumb] && 914226633Sdim "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!"); 915226633Sdim 916226633Sdim // We want to read exactly 2 bytes of data. 917280031Sdim if (Bytes.size() < 2) { 918226633Sdim Size = 0; 919226633Sdim return MCDisassembler::Fail; 920226633Sdim } 921226633Sdim 922280031Sdim uint16_t Insn16 = (Bytes[1] << 8) | Bytes[0]; 923280031Sdim DecodeStatus Result = 924280031Sdim decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI); 925280031Sdim if (Result != MCDisassembler::Fail) { 926226633Sdim Size = 2; 927280031Sdim Check(Result, AddThumbPredicate(MI)); 928280031Sdim return Result; 929226633Sdim } 930226633Sdim 931280031Sdim Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this, 932280031Sdim STI); 933280031Sdim if (Result) { 934226633Sdim Size = 2; 935239462Sdim bool InITBlock = ITBlock.instrInITBlock(); 936280031Sdim Check(Result, AddThumbPredicate(MI)); 937226633Sdim AddThumb1SBit(MI, InITBlock); 938280031Sdim return Result; 939226633Sdim } 940226633Sdim 941280031Sdim Result = 942280031Sdim decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI); 943280031Sdim if (Result != MCDisassembler::Fail) { 944226633Sdim Size = 2; 945226633Sdim 946226633Sdim // Nested IT blocks are UNPREDICTABLE. Must be checked before we add 947226633Sdim // the Thumb predicate. 948239462Sdim if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock()) 949280031Sdim Result = MCDisassembler::SoftFail; 950226633Sdim 951280031Sdim Check(Result, AddThumbPredicate(MI)); 952226633Sdim 953226633Sdim // If we find an IT instruction, we need to parse its condition 954226633Sdim // code and mask operands so that we can apply them correctly 955226633Sdim // to the subsequent instructions. 956226633Sdim if (MI.getOpcode() == ARM::t2IT) { 957239462Sdim unsigned Firstcond = MI.getOperand(0).getImm(); 958226633Sdim unsigned Mask = MI.getOperand(1).getImm(); 959239462Sdim ITBlock.setITState(Firstcond, Mask); 960341825Sdim 961341825Sdim // An IT instruction that would give a 'NV' predicate is unpredictable. 962341825Sdim if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask)) 963341825Sdim CS << "unpredictable IT predicate sequence"; 964226633Sdim } 965226633Sdim 966280031Sdim return Result; 967226633Sdim } 968226633Sdim 969226633Sdim // We want to read exactly 4 bytes of data. 970280031Sdim if (Bytes.size() < 4) { 971226633Sdim Size = 0; 972226633Sdim return MCDisassembler::Fail; 973226633Sdim } 974226633Sdim 975280031Sdim uint32_t Insn32 = 976280031Sdim (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16); 977353358Sdim 978280031Sdim Result = 979353358Sdim decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI); 980353358Sdim if (Result != MCDisassembler::Fail) { 981353358Sdim Size = 4; 982353358Sdim 983353358Sdim // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add 984353358Sdim // the VPT predicate. 985353358Sdim if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock()) 986353358Sdim Result = MCDisassembler::SoftFail; 987353358Sdim 988353358Sdim Check(Result, AddThumbPredicate(MI)); 989353358Sdim 990353358Sdim if (isVPTOpcode(MI.getOpcode())) { 991353358Sdim unsigned Mask = MI.getOperand(0).getImm(); 992353358Sdim VPTBlock.setVPTState(Mask); 993353358Sdim } 994353358Sdim 995353358Sdim return Result; 996353358Sdim } 997353358Sdim 998353358Sdim Result = 999280031Sdim decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI); 1000280031Sdim if (Result != MCDisassembler::Fail) { 1001226633Sdim Size = 4; 1002239462Sdim bool InITBlock = ITBlock.instrInITBlock(); 1003280031Sdim Check(Result, AddThumbPredicate(MI)); 1004226633Sdim AddThumb1SBit(MI, InITBlock); 1005280031Sdim return Result; 1006226633Sdim } 1007226633Sdim 1008280031Sdim Result = 1009280031Sdim decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI); 1010280031Sdim if (Result != MCDisassembler::Fail) { 1011226633Sdim Size = 4; 1012280031Sdim Check(Result, AddThumbPredicate(MI)); 1013360784Sdim return checkDecodedInstruction(MI, Size, Address, CS, Insn32, Result); 1014226633Sdim } 1015226633Sdim 1016280031Sdim if (fieldFromInstruction(Insn32, 28, 4) == 0xE) { 1017280031Sdim Result = 1018280031Sdim decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI); 1019280031Sdim if (Result != MCDisassembler::Fail) { 1020261991Sdim Size = 4; 1021353358Sdim UpdateThumbVFPPredicate(Result, MI); 1022280031Sdim return Result; 1023261991Sdim } 1024226633Sdim } 1025226633Sdim 1026280031Sdim Result = 1027280031Sdim decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI); 1028280031Sdim if (Result != MCDisassembler::Fail) { 1029226633Sdim Size = 4; 1030280031Sdim return Result; 1031226633Sdim } 1032226633Sdim 1033280031Sdim if (fieldFromInstruction(Insn32, 28, 4) == 0xE) { 1034280031Sdim Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this, 1035280031Sdim STI); 1036280031Sdim if (Result != MCDisassembler::Fail) { 1037261991Sdim Size = 4; 1038280031Sdim Check(Result, AddThumbPredicate(MI)); 1039280031Sdim return Result; 1040261991Sdim } 1041261991Sdim } 1042261991Sdim 1043280031Sdim if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) { 1044280031Sdim uint32_t NEONLdStInsn = Insn32; 1045226633Sdim NEONLdStInsn &= 0xF0FFFFFF; 1046226633Sdim NEONLdStInsn |= 0x04000000; 1047280031Sdim Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, 1048239462Sdim Address, this, STI); 1049280031Sdim if (Result != MCDisassembler::Fail) { 1050226633Sdim Size = 4; 1051280031Sdim Check(Result, AddThumbPredicate(MI)); 1052280031Sdim return Result; 1053226633Sdim } 1054226633Sdim } 1055226633Sdim 1056280031Sdim if (fieldFromInstruction(Insn32, 24, 4) == 0xF) { 1057280031Sdim uint32_t NEONDataInsn = Insn32; 1058226633Sdim NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24 1059226633Sdim NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 1060226633Sdim NEONDataInsn |= 0x12000000; // Set bits 28 and 25 1061280031Sdim Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn, 1062239462Sdim Address, this, STI); 1063280031Sdim if (Result != MCDisassembler::Fail) { 1064226633Sdim Size = 4; 1065280031Sdim Check(Result, AddThumbPredicate(MI)); 1066280031Sdim return Result; 1067226633Sdim } 1068261991Sdim 1069280031Sdim uint32_t NEONCryptoInsn = Insn32; 1070261991Sdim NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24 1071261991Sdim NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 1072261991Sdim NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25 1073280031Sdim Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn, 1074261991Sdim Address, this, STI); 1075280031Sdim if (Result != MCDisassembler::Fail) { 1076261991Sdim Size = 4; 1077280031Sdim return Result; 1078261991Sdim } 1079261991Sdim 1080280031Sdim uint32_t NEONv8Insn = Insn32; 1081261991Sdim NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26 1082280031Sdim Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address, 1083261991Sdim this, STI); 1084280031Sdim if (Result != MCDisassembler::Fail) { 1085261991Sdim Size = 4; 1086280031Sdim return Result; 1087261991Sdim } 1088226633Sdim } 1089226633Sdim 1090327952Sdim Result = 1091327952Sdim decodeInstruction(DecoderTableThumb2CoProc32, MI, Insn32, Address, this, STI); 1092327952Sdim if (Result != MCDisassembler::Fail) { 1093327952Sdim Size = 4; 1094327952Sdim Check(Result, AddThumbPredicate(MI)); 1095327952Sdim return Result; 1096327952Sdim } 1097327952Sdim 1098226633Sdim Size = 0; 1099226633Sdim return MCDisassembler::Fail; 1100226633Sdim} 1101226633Sdim 1102360784Sdimextern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMDisassembler() { 1103314564Sdim TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(), 1104226633Sdim createARMDisassembler); 1105314564Sdim TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(), 1106276479Sdim createARMDisassembler); 1107314564Sdim TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(), 1108353358Sdim createARMDisassembler); 1109314564Sdim TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(), 1110353358Sdim createARMDisassembler); 1111226633Sdim} 1112226633Sdim 1113234353Sdimstatic const uint16_t GPRDecoderTable[] = { 1114226633Sdim ARM::R0, ARM::R1, ARM::R2, ARM::R3, 1115226633Sdim ARM::R4, ARM::R5, ARM::R6, ARM::R7, 1116226633Sdim ARM::R8, ARM::R9, ARM::R10, ARM::R11, 1117226633Sdim ARM::R12, ARM::SP, ARM::LR, ARM::PC 1118226633Sdim}; 1119226633Sdim 1120353358Sdimstatic const uint16_t CLRMGPRDecoderTable[] = { 1121353358Sdim ARM::R0, ARM::R1, ARM::R2, ARM::R3, 1122353358Sdim ARM::R4, ARM::R5, ARM::R6, ARM::R7, 1123353358Sdim ARM::R8, ARM::R9, ARM::R10, ARM::R11, 1124353358Sdim ARM::R12, 0, ARM::LR, ARM::APSR 1125353358Sdim}; 1126353358Sdim 1127234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 1128226633Sdim uint64_t Address, const void *Decoder) { 1129226633Sdim if (RegNo > 15) 1130226633Sdim return MCDisassembler::Fail; 1131226633Sdim 1132226633Sdim unsigned Register = GPRDecoderTable[RegNo]; 1133288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1134226633Sdim return MCDisassembler::Success; 1135226633Sdim} 1136226633Sdim 1137353358Sdimstatic DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo, 1138353358Sdim uint64_t Address, 1139353358Sdim const void *Decoder) { 1140353358Sdim if (RegNo > 15) 1141353358Sdim return MCDisassembler::Fail; 1142353358Sdim 1143353358Sdim unsigned Register = CLRMGPRDecoderTable[RegNo]; 1144353358Sdim if (Register == 0) 1145353358Sdim return MCDisassembler::Fail; 1146353358Sdim 1147353358Sdim Inst.addOperand(MCOperand::createReg(Register)); 1148353358Sdim return MCDisassembler::Success; 1149353358Sdim} 1150353358Sdim 1151226633Sdimstatic DecodeStatus 1152234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo, 1153226633Sdim uint64_t Address, const void *Decoder) { 1154234353Sdim DecodeStatus S = MCDisassembler::Success; 1155296417Sdim 1156341825Sdim if (RegNo == 15) 1157234353Sdim S = MCDisassembler::SoftFail; 1158234353Sdim 1159234353Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 1160234353Sdim 1161234353Sdim return S; 1162226633Sdim} 1163226633Sdim 1164261991Sdimstatic DecodeStatus 1165261991SdimDecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, 1166261991Sdim uint64_t Address, const void *Decoder) { 1167261991Sdim DecodeStatus S = MCDisassembler::Success; 1168261991Sdim 1169261991Sdim if (RegNo == 15) 1170261991Sdim { 1171288943Sdim Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV)); 1172261991Sdim return MCDisassembler::Success; 1173261991Sdim } 1174261991Sdim 1175261991Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 1176261991Sdim return S; 1177261991Sdim} 1178261991Sdim 1179353358Sdimstatic DecodeStatus 1180353358SdimDecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, 1181353358Sdim uint64_t Address, const void *Decoder) { 1182353358Sdim DecodeStatus S = MCDisassembler::Success; 1183353358Sdim 1184353358Sdim if (RegNo == 15) 1185353358Sdim { 1186353358Sdim Inst.addOperand(MCOperand::createReg(ARM::ZR)); 1187353358Sdim return MCDisassembler::Success; 1188353358Sdim } 1189353358Sdim 1190353358Sdim if (RegNo == 13) 1191353358Sdim Check(S, MCDisassembler::SoftFail); 1192353358Sdim 1193353358Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 1194353358Sdim return S; 1195353358Sdim} 1196353358Sdim 1197353358Sdimstatic DecodeStatus 1198353358SdimDecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, 1199353358Sdim uint64_t Address, const void *Decoder) { 1200353358Sdim DecodeStatus S = MCDisassembler::Success; 1201353358Sdim if (RegNo == 13) 1202353358Sdim return MCDisassembler::Fail; 1203353358Sdim Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder)); 1204353358Sdim return S; 1205353358Sdim} 1206353358Sdim 1207234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, 1208226633Sdim uint64_t Address, const void *Decoder) { 1209226633Sdim if (RegNo > 7) 1210226633Sdim return MCDisassembler::Fail; 1211226633Sdim return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 1212226633Sdim} 1213226633Sdim 1214261991Sdimstatic const uint16_t GPRPairDecoderTable[] = { 1215261991Sdim ARM::R0_R1, ARM::R2_R3, ARM::R4_R5, ARM::R6_R7, 1216261991Sdim ARM::R8_R9, ARM::R10_R11, ARM::R12_SP 1217261991Sdim}; 1218261991Sdim 1219261991Sdimstatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo, 1220261991Sdim uint64_t Address, const void *Decoder) { 1221261991Sdim DecodeStatus S = MCDisassembler::Success; 1222261991Sdim 1223261991Sdim if (RegNo > 13) 1224261991Sdim return MCDisassembler::Fail; 1225261991Sdim 1226261991Sdim if ((RegNo & 1) || RegNo == 0xe) 1227261991Sdim S = MCDisassembler::SoftFail; 1228261991Sdim 1229261991Sdim unsigned RegisterPair = GPRPairDecoderTable[RegNo/2]; 1230288943Sdim Inst.addOperand(MCOperand::createReg(RegisterPair)); 1231261991Sdim return S; 1232261991Sdim} 1233261991Sdim 1234360784Sdimstatic DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo, 1235360784Sdim uint64_t Address, 1236360784Sdim const void *Decoder) { 1237360784Sdim if (RegNo != 13) 1238360784Sdim return MCDisassembler::Fail; 1239360784Sdim 1240360784Sdim unsigned Register = GPRDecoderTable[RegNo]; 1241360784Sdim Inst.addOperand(MCOperand::createReg(Register)); 1242360784Sdim return MCDisassembler::Success; 1243360784Sdim} 1244360784Sdim 1245234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, 1246226633Sdim uint64_t Address, const void *Decoder) { 1247226633Sdim unsigned Register = 0; 1248226633Sdim switch (RegNo) { 1249226633Sdim case 0: 1250226633Sdim Register = ARM::R0; 1251206124Srdivacky break; 1252226633Sdim case 1: 1253226633Sdim Register = ARM::R1; 1254226633Sdim break; 1255226633Sdim case 2: 1256226633Sdim Register = ARM::R2; 1257226633Sdim break; 1258206124Srdivacky case 3: 1259226633Sdim Register = ARM::R3; 1260206124Srdivacky break; 1261226633Sdim case 9: 1262226633Sdim Register = ARM::R9; 1263226633Sdim break; 1264226633Sdim case 12: 1265226633Sdim Register = ARM::R12; 1266226633Sdim break; 1267206124Srdivacky default: 1268226633Sdim return MCDisassembler::Fail; 1269206124Srdivacky } 1270226633Sdim 1271288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1272226633Sdim return MCDisassembler::Success; 1273226633Sdim} 1274226633Sdim 1275234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, 1276226633Sdim uint64_t Address, const void *Decoder) { 1277261991Sdim DecodeStatus S = MCDisassembler::Success; 1278296417Sdim 1279296417Sdim const FeatureBitset &featureBits = 1280296417Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 1281296417Sdim 1282296417Sdim if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15) 1283261991Sdim S = MCDisassembler::SoftFail; 1284296417Sdim 1285261991Sdim Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); 1286261991Sdim return S; 1287226633Sdim} 1288226633Sdim 1289234353Sdimstatic const uint16_t SPRDecoderTable[] = { 1290226633Sdim ARM::S0, ARM::S1, ARM::S2, ARM::S3, 1291226633Sdim ARM::S4, ARM::S5, ARM::S6, ARM::S7, 1292226633Sdim ARM::S8, ARM::S9, ARM::S10, ARM::S11, 1293226633Sdim ARM::S12, ARM::S13, ARM::S14, ARM::S15, 1294226633Sdim ARM::S16, ARM::S17, ARM::S18, ARM::S19, 1295226633Sdim ARM::S20, ARM::S21, ARM::S22, ARM::S23, 1296226633Sdim ARM::S24, ARM::S25, ARM::S26, ARM::S27, 1297226633Sdim ARM::S28, ARM::S29, ARM::S30, ARM::S31 1298226633Sdim}; 1299226633Sdim 1300234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, 1301226633Sdim uint64_t Address, const void *Decoder) { 1302226633Sdim if (RegNo > 31) 1303226633Sdim return MCDisassembler::Fail; 1304226633Sdim 1305226633Sdim unsigned Register = SPRDecoderTable[RegNo]; 1306288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1307226633Sdim return MCDisassembler::Success; 1308226633Sdim} 1309226633Sdim 1310341825Sdimstatic DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo, 1311341825Sdim uint64_t Address, const void *Decoder) { 1312341825Sdim return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder); 1313341825Sdim} 1314341825Sdim 1315234353Sdimstatic const uint16_t DPRDecoderTable[] = { 1316226633Sdim ARM::D0, ARM::D1, ARM::D2, ARM::D3, 1317226633Sdim ARM::D4, ARM::D5, ARM::D6, ARM::D7, 1318226633Sdim ARM::D8, ARM::D9, ARM::D10, ARM::D11, 1319226633Sdim ARM::D12, ARM::D13, ARM::D14, ARM::D15, 1320226633Sdim ARM::D16, ARM::D17, ARM::D18, ARM::D19, 1321226633Sdim ARM::D20, ARM::D21, ARM::D22, ARM::D23, 1322226633Sdim ARM::D24, ARM::D25, ARM::D26, ARM::D27, 1323226633Sdim ARM::D28, ARM::D29, ARM::D30, ARM::D31 1324226633Sdim}; 1325226633Sdim 1326234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, 1327226633Sdim uint64_t Address, const void *Decoder) { 1328288943Sdim const FeatureBitset &featureBits = 1329288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 1330280031Sdim 1331353358Sdim bool hasD32 = featureBits[ARM::FeatureD32]; 1332288943Sdim 1333353358Sdim if (RegNo > 31 || (!hasD32 && RegNo > 15)) 1334226633Sdim return MCDisassembler::Fail; 1335226633Sdim 1336226633Sdim unsigned Register = DPRDecoderTable[RegNo]; 1337288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1338226633Sdim return MCDisassembler::Success; 1339226633Sdim} 1340226633Sdim 1341234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 1342226633Sdim uint64_t Address, const void *Decoder) { 1343226633Sdim if (RegNo > 7) 1344226633Sdim return MCDisassembler::Fail; 1345226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 1346226633Sdim} 1347226633Sdim 1348353358Sdimstatic DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo, 1349353358Sdim uint64_t Address, const void *Decoder) { 1350353358Sdim if (RegNo > 15) 1351353358Sdim return MCDisassembler::Fail; 1352353358Sdim return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder); 1353353358Sdim} 1354353358Sdim 1355226633Sdimstatic DecodeStatus 1356234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo, 1357226633Sdim uint64_t Address, const void *Decoder) { 1358226633Sdim if (RegNo > 15) 1359226633Sdim return MCDisassembler::Fail; 1360226633Sdim return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); 1361226633Sdim} 1362226633Sdim 1363234353Sdimstatic const uint16_t QPRDecoderTable[] = { 1364226633Sdim ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3, 1365226633Sdim ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7, 1366226633Sdim ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11, 1367226633Sdim ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15 1368226633Sdim}; 1369226633Sdim 1370234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, 1371226633Sdim uint64_t Address, const void *Decoder) { 1372261991Sdim if (RegNo > 31 || (RegNo & 1) != 0) 1373226633Sdim return MCDisassembler::Fail; 1374226633Sdim RegNo >>= 1; 1375226633Sdim 1376226633Sdim unsigned Register = QPRDecoderTable[RegNo]; 1377288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1378226633Sdim return MCDisassembler::Success; 1379226633Sdim} 1380226633Sdim 1381234353Sdimstatic const uint16_t DPairDecoderTable[] = { 1382234353Sdim ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6, 1383234353Sdim ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12, 1384234353Sdim ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18, 1385234353Sdim ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24, 1386234353Sdim ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30, 1387234353Sdim ARM::Q15 1388234353Sdim}; 1389234353Sdim 1390234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, 1391234353Sdim uint64_t Address, const void *Decoder) { 1392234353Sdim if (RegNo > 30) 1393234353Sdim return MCDisassembler::Fail; 1394234353Sdim 1395234353Sdim unsigned Register = DPairDecoderTable[RegNo]; 1396288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1397234353Sdim return MCDisassembler::Success; 1398234353Sdim} 1399234353Sdim 1400234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = { 1401234353Sdim ARM::D0_D2, ARM::D1_D3, ARM::D2_D4, ARM::D3_D5, 1402234353Sdim ARM::D4_D6, ARM::D5_D7, ARM::D6_D8, ARM::D7_D9, 1403234353Sdim ARM::D8_D10, ARM::D9_D11, ARM::D10_D12, ARM::D11_D13, 1404234353Sdim ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17, 1405234353Sdim ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21, 1406234353Sdim ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25, 1407234353Sdim ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29, 1408234353Sdim ARM::D28_D30, ARM::D29_D31 1409234353Sdim}; 1410234353Sdim 1411234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, 1412234353Sdim unsigned RegNo, 1413234353Sdim uint64_t Address, 1414234353Sdim const void *Decoder) { 1415234353Sdim if (RegNo > 29) 1416234353Sdim return MCDisassembler::Fail; 1417234353Sdim 1418234353Sdim unsigned Register = DPairSpacedDecoderTable[RegNo]; 1419288943Sdim Inst.addOperand(MCOperand::createReg(Register)); 1420234353Sdim return MCDisassembler::Success; 1421234353Sdim} 1422234353Sdim 1423234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, 1424226633Sdim uint64_t Address, const void *Decoder) { 1425353358Sdim DecodeStatus S = MCDisassembler::Success; 1426226633Sdim if (Val == 0xF) return MCDisassembler::Fail; 1427226633Sdim // AL predicate is not allowed on Thumb1 branches. 1428226633Sdim if (Inst.getOpcode() == ARM::tBcc && Val == 0xE) 1429226633Sdim return MCDisassembler::Fail; 1430353358Sdim if (Val != ARMCC::AL && !ARMInsts[Inst.getOpcode()].isPredicable()) 1431353358Sdim Check(S, MCDisassembler::SoftFail); 1432288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 1433226633Sdim if (Val == ARMCC::AL) { 1434288943Sdim Inst.addOperand(MCOperand::createReg(0)); 1435226633Sdim } else 1436288943Sdim Inst.addOperand(MCOperand::createReg(ARM::CPSR)); 1437353358Sdim return S; 1438226633Sdim} 1439226633Sdim 1440234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, 1441226633Sdim uint64_t Address, const void *Decoder) { 1442226633Sdim if (Val) 1443288943Sdim Inst.addOperand(MCOperand::createReg(ARM::CPSR)); 1444226633Sdim else 1445288943Sdim Inst.addOperand(MCOperand::createReg(0)); 1446226633Sdim return MCDisassembler::Success; 1447226633Sdim} 1448226633Sdim 1449234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val, 1450226633Sdim uint64_t Address, const void *Decoder) { 1451226633Sdim DecodeStatus S = MCDisassembler::Success; 1452226633Sdim 1453239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1454239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1455239462Sdim unsigned imm = fieldFromInstruction(Val, 7, 5); 1456226633Sdim 1457226633Sdim // Register-immediate 1458296417Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 1459226633Sdim return MCDisassembler::Fail; 1460226633Sdim 1461226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1462226633Sdim switch (type) { 1463226633Sdim case 0: 1464226633Sdim Shift = ARM_AM::lsl; 1465226633Sdim break; 1466226633Sdim case 1: 1467226633Sdim Shift = ARM_AM::lsr; 1468226633Sdim break; 1469226633Sdim case 2: 1470226633Sdim Shift = ARM_AM::asr; 1471226633Sdim break; 1472226633Sdim case 3: 1473226633Sdim Shift = ARM_AM::ror; 1474226633Sdim break; 1475206124Srdivacky } 1476206124Srdivacky 1477226633Sdim if (Shift == ARM_AM::ror && imm == 0) 1478226633Sdim Shift = ARM_AM::rrx; 1479226633Sdim 1480226633Sdim unsigned Op = Shift | (imm << 3); 1481288943Sdim Inst.addOperand(MCOperand::createImm(Op)); 1482226633Sdim 1483226633Sdim return S; 1484226633Sdim} 1485226633Sdim 1486234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val, 1487226633Sdim uint64_t Address, const void *Decoder) { 1488226633Sdim DecodeStatus S = MCDisassembler::Success; 1489226633Sdim 1490239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1491239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1492239462Sdim unsigned Rs = fieldFromInstruction(Val, 8, 4); 1493226633Sdim 1494226633Sdim // Register-register 1495226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1496226633Sdim return MCDisassembler::Fail; 1497226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder))) 1498226633Sdim return MCDisassembler::Fail; 1499226633Sdim 1500226633Sdim ARM_AM::ShiftOpc Shift = ARM_AM::lsl; 1501226633Sdim switch (type) { 1502226633Sdim case 0: 1503226633Sdim Shift = ARM_AM::lsl; 1504206124Srdivacky break; 1505226633Sdim case 1: 1506226633Sdim Shift = ARM_AM::lsr; 1507206124Srdivacky break; 1508226633Sdim case 2: 1509226633Sdim Shift = ARM_AM::asr; 1510206124Srdivacky break; 1511226633Sdim case 3: 1512226633Sdim Shift = ARM_AM::ror; 1513226633Sdim break; 1514226633Sdim } 1515226633Sdim 1516288943Sdim Inst.addOperand(MCOperand::createImm(Shift)); 1517226633Sdim 1518226633Sdim return S; 1519226633Sdim} 1520226633Sdim 1521234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, 1522226633Sdim uint64_t Address, const void *Decoder) { 1523226633Sdim DecodeStatus S = MCDisassembler::Success; 1524226633Sdim 1525261991Sdim bool NeedDisjointWriteback = false; 1526261991Sdim unsigned WritebackReg = 0; 1527353358Sdim bool CLRM = false; 1528226633Sdim switch (Inst.getOpcode()) { 1529261991Sdim default: 1530261991Sdim break; 1531261991Sdim case ARM::LDMIA_UPD: 1532261991Sdim case ARM::LDMDB_UPD: 1533261991Sdim case ARM::LDMIB_UPD: 1534261991Sdim case ARM::LDMDA_UPD: 1535261991Sdim case ARM::t2LDMIA_UPD: 1536261991Sdim case ARM::t2LDMDB_UPD: 1537261991Sdim case ARM::t2STMIA_UPD: 1538261991Sdim case ARM::t2STMDB_UPD: 1539261991Sdim NeedDisjointWriteback = true; 1540261991Sdim WritebackReg = Inst.getOperand(0).getReg(); 1541261991Sdim break; 1542353358Sdim case ARM::t2CLRM: 1543353358Sdim CLRM = true; 1544353358Sdim break; 1545226633Sdim } 1546226633Sdim 1547226633Sdim // Empty register lists are not allowed. 1548261991Sdim if (Val == 0) return MCDisassembler::Fail; 1549226633Sdim for (unsigned i = 0; i < 16; ++i) { 1550226633Sdim if (Val & (1 << i)) { 1551353358Sdim if (CLRM) { 1552353358Sdim if (!Check(S, DecodeCLRMGPRRegisterClass(Inst, i, Address, Decoder))) { 1553353358Sdim return MCDisassembler::Fail; 1554353358Sdim } 1555353358Sdim } else { 1556353358Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder))) 1557353358Sdim return MCDisassembler::Fail; 1558353358Sdim // Writeback not allowed if Rn is in the target list. 1559353358Sdim if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg()) 1560353358Sdim Check(S, MCDisassembler::SoftFail); 1561353358Sdim } 1562206124Srdivacky } 1563206124Srdivacky } 1564206124Srdivacky 1565226633Sdim return S; 1566226633Sdim} 1567226633Sdim 1568234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, 1569226633Sdim uint64_t Address, const void *Decoder) { 1570226633Sdim DecodeStatus S = MCDisassembler::Success; 1571226633Sdim 1572239462Sdim unsigned Vd = fieldFromInstruction(Val, 8, 5); 1573239462Sdim unsigned regs = fieldFromInstruction(Val, 0, 8); 1574226633Sdim 1575261991Sdim // In case of unpredictable encoding, tweak the operands. 1576261991Sdim if (regs == 0 || (Vd + regs) > 32) { 1577261991Sdim regs = Vd + regs > 32 ? 32 - Vd : regs; 1578261991Sdim regs = std::max( 1u, regs); 1579261991Sdim S = MCDisassembler::SoftFail; 1580261991Sdim } 1581261991Sdim 1582226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder))) 1583226633Sdim return MCDisassembler::Fail; 1584226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1585226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1586226633Sdim return MCDisassembler::Fail; 1587226633Sdim } 1588226633Sdim 1589226633Sdim return S; 1590226633Sdim} 1591226633Sdim 1592234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, 1593226633Sdim uint64_t Address, const void *Decoder) { 1594226633Sdim DecodeStatus S = MCDisassembler::Success; 1595226633Sdim 1596239462Sdim unsigned Vd = fieldFromInstruction(Val, 8, 5); 1597261991Sdim unsigned regs = fieldFromInstruction(Val, 1, 7); 1598226633Sdim 1599261991Sdim // In case of unpredictable encoding, tweak the operands. 1600261991Sdim if (regs == 0 || regs > 16 || (Vd + regs) > 32) { 1601261991Sdim regs = Vd + regs > 32 ? 32 - Vd : regs; 1602261991Sdim regs = std::max( 1u, regs); 1603261991Sdim regs = std::min(16u, regs); 1604261991Sdim S = MCDisassembler::SoftFail; 1605261991Sdim } 1606239462Sdim 1607226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 1608226633Sdim return MCDisassembler::Fail; 1609226633Sdim for (unsigned i = 0; i < (regs - 1); ++i) { 1610226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder))) 1611226633Sdim return MCDisassembler::Fail; 1612226633Sdim } 1613226633Sdim 1614226633Sdim return S; 1615226633Sdim} 1616226633Sdim 1617234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val, 1618226633Sdim uint64_t Address, const void *Decoder) { 1619226633Sdim // This operand encodes a mask of contiguous zeros between a specified MSB 1620226633Sdim // and LSB. To decode it, we create the mask of all bits MSB-and-lower, 1621226633Sdim // the mask of all bits LSB-and-lower, and then xor them to create 1622226633Sdim // the mask of that's all ones on [msb, lsb]. Finally we not it to 1623226633Sdim // create the final mask. 1624239462Sdim unsigned msb = fieldFromInstruction(Val, 5, 5); 1625239462Sdim unsigned lsb = fieldFromInstruction(Val, 0, 5); 1626226633Sdim 1627226633Sdim DecodeStatus S = MCDisassembler::Success; 1628249423Sdim if (lsb > msb) { 1629249423Sdim Check(S, MCDisassembler::SoftFail); 1630249423Sdim // The check above will cause the warning for the "potentially undefined 1631249423Sdim // instruction encoding" but we can't build a bad MCOperand value here 1632249423Sdim // with a lsb > msb or else printing the MCInst will cause a crash. 1633249423Sdim lsb = msb; 1634249423Sdim } 1635226633Sdim 1636226633Sdim uint32_t msb_mask = 0xFFFFFFFF; 1637226633Sdim if (msb != 31) msb_mask = (1U << (msb+1)) - 1; 1638226633Sdim uint32_t lsb_mask = (1U << lsb) - 1; 1639226633Sdim 1640288943Sdim Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask))); 1641226633Sdim return S; 1642226633Sdim} 1643226633Sdim 1644234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, 1645226633Sdim uint64_t Address, const void *Decoder) { 1646226633Sdim DecodeStatus S = MCDisassembler::Success; 1647226633Sdim 1648239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1649239462Sdim unsigned CRd = fieldFromInstruction(Insn, 12, 4); 1650239462Sdim unsigned coproc = fieldFromInstruction(Insn, 8, 4); 1651239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 1652239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1653239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 1654353358Sdim const FeatureBitset &featureBits = 1655353358Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 1656226633Sdim 1657226633Sdim switch (Inst.getOpcode()) { 1658226633Sdim case ARM::LDC_OFFSET: 1659226633Sdim case ARM::LDC_PRE: 1660226633Sdim case ARM::LDC_POST: 1661226633Sdim case ARM::LDC_OPTION: 1662226633Sdim case ARM::LDCL_OFFSET: 1663226633Sdim case ARM::LDCL_PRE: 1664226633Sdim case ARM::LDCL_POST: 1665226633Sdim case ARM::LDCL_OPTION: 1666226633Sdim case ARM::STC_OFFSET: 1667226633Sdim case ARM::STC_PRE: 1668226633Sdim case ARM::STC_POST: 1669226633Sdim case ARM::STC_OPTION: 1670226633Sdim case ARM::STCL_OFFSET: 1671226633Sdim case ARM::STCL_PRE: 1672226633Sdim case ARM::STCL_POST: 1673226633Sdim case ARM::STCL_OPTION: 1674226633Sdim case ARM::t2LDC_OFFSET: 1675226633Sdim case ARM::t2LDC_PRE: 1676226633Sdim case ARM::t2LDC_POST: 1677226633Sdim case ARM::t2LDC_OPTION: 1678226633Sdim case ARM::t2LDCL_OFFSET: 1679226633Sdim case ARM::t2LDCL_PRE: 1680226633Sdim case ARM::t2LDCL_POST: 1681226633Sdim case ARM::t2LDCL_OPTION: 1682226633Sdim case ARM::t2STC_OFFSET: 1683226633Sdim case ARM::t2STC_PRE: 1684226633Sdim case ARM::t2STC_POST: 1685226633Sdim case ARM::t2STC_OPTION: 1686226633Sdim case ARM::t2STCL_OFFSET: 1687226633Sdim case ARM::t2STCL_PRE: 1688226633Sdim case ARM::t2STCL_POST: 1689226633Sdim case ARM::t2STCL_OPTION: 1690353358Sdim case ARM::t2LDC2_OFFSET: 1691353358Sdim case ARM::t2LDC2L_OFFSET: 1692353358Sdim case ARM::t2LDC2_PRE: 1693353358Sdim case ARM::t2LDC2L_PRE: 1694353358Sdim case ARM::t2STC2_OFFSET: 1695353358Sdim case ARM::t2STC2L_OFFSET: 1696353358Sdim case ARM::t2STC2_PRE: 1697353358Sdim case ARM::t2STC2L_PRE: 1698353358Sdim case ARM::LDC2_OFFSET: 1699353358Sdim case ARM::LDC2L_OFFSET: 1700353358Sdim case ARM::LDC2_PRE: 1701353358Sdim case ARM::LDC2L_PRE: 1702353358Sdim case ARM::STC2_OFFSET: 1703353358Sdim case ARM::STC2L_OFFSET: 1704353358Sdim case ARM::STC2_PRE: 1705353358Sdim case ARM::STC2L_PRE: 1706353358Sdim case ARM::t2LDC2_OPTION: 1707353358Sdim case ARM::t2STC2_OPTION: 1708353358Sdim case ARM::t2LDC2_POST: 1709353358Sdim case ARM::t2LDC2L_POST: 1710353358Sdim case ARM::t2STC2_POST: 1711353358Sdim case ARM::t2STC2L_POST: 1712353358Sdim case ARM::LDC2_POST: 1713353358Sdim case ARM::LDC2L_POST: 1714353358Sdim case ARM::STC2_POST: 1715353358Sdim case ARM::STC2L_POST: 1716353358Sdim if (coproc == 0xA || coproc == 0xB || 1717353358Sdim (featureBits[ARM::HasV8_1MMainlineOps] && 1718353358Sdim (coproc == 0x8 || coproc == 0x9 || coproc == 0xA || coproc == 0xB || 1719353358Sdim coproc == 0xE || coproc == 0xF))) 1720226633Sdim return MCDisassembler::Fail; 1721206124Srdivacky break; 1722226633Sdim default: 1723226633Sdim break; 1724226633Sdim } 1725226633Sdim 1726288943Sdim if (featureBits[ARM::HasV8Ops] && (coproc != 14)) 1727261991Sdim return MCDisassembler::Fail; 1728261991Sdim 1729288943Sdim Inst.addOperand(MCOperand::createImm(coproc)); 1730288943Sdim Inst.addOperand(MCOperand::createImm(CRd)); 1731226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1732226633Sdim return MCDisassembler::Fail; 1733226633Sdim 1734226633Sdim switch (Inst.getOpcode()) { 1735226633Sdim case ARM::t2LDC2_OFFSET: 1736226633Sdim case ARM::t2LDC2L_OFFSET: 1737226633Sdim case ARM::t2LDC2_PRE: 1738226633Sdim case ARM::t2LDC2L_PRE: 1739226633Sdim case ARM::t2STC2_OFFSET: 1740226633Sdim case ARM::t2STC2L_OFFSET: 1741226633Sdim case ARM::t2STC2_PRE: 1742226633Sdim case ARM::t2STC2L_PRE: 1743226633Sdim case ARM::LDC2_OFFSET: 1744226633Sdim case ARM::LDC2L_OFFSET: 1745226633Sdim case ARM::LDC2_PRE: 1746226633Sdim case ARM::LDC2L_PRE: 1747226633Sdim case ARM::STC2_OFFSET: 1748226633Sdim case ARM::STC2L_OFFSET: 1749226633Sdim case ARM::STC2_PRE: 1750226633Sdim case ARM::STC2L_PRE: 1751226633Sdim case ARM::t2LDC_OFFSET: 1752226633Sdim case ARM::t2LDCL_OFFSET: 1753226633Sdim case ARM::t2LDC_PRE: 1754226633Sdim case ARM::t2LDCL_PRE: 1755226633Sdim case ARM::t2STC_OFFSET: 1756226633Sdim case ARM::t2STCL_OFFSET: 1757226633Sdim case ARM::t2STC_PRE: 1758226633Sdim case ARM::t2STCL_PRE: 1759226633Sdim case ARM::LDC_OFFSET: 1760226633Sdim case ARM::LDCL_OFFSET: 1761226633Sdim case ARM::LDC_PRE: 1762226633Sdim case ARM::LDCL_PRE: 1763226633Sdim case ARM::STC_OFFSET: 1764226633Sdim case ARM::STCL_OFFSET: 1765226633Sdim case ARM::STC_PRE: 1766226633Sdim case ARM::STCL_PRE: 1767226633Sdim imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm); 1768288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 1769226633Sdim break; 1770226633Sdim case ARM::t2LDC2_POST: 1771226633Sdim case ARM::t2LDC2L_POST: 1772226633Sdim case ARM::t2STC2_POST: 1773226633Sdim case ARM::t2STC2L_POST: 1774226633Sdim case ARM::LDC2_POST: 1775226633Sdim case ARM::LDC2L_POST: 1776226633Sdim case ARM::STC2_POST: 1777226633Sdim case ARM::STC2L_POST: 1778226633Sdim case ARM::t2LDC_POST: 1779226633Sdim case ARM::t2LDCL_POST: 1780226633Sdim case ARM::t2STC_POST: 1781226633Sdim case ARM::t2STCL_POST: 1782226633Sdim case ARM::LDC_POST: 1783226633Sdim case ARM::LDCL_POST: 1784226633Sdim case ARM::STC_POST: 1785226633Sdim case ARM::STCL_POST: 1786226633Sdim imm |= U << 8; 1787314564Sdim LLVM_FALLTHROUGH; 1788226633Sdim default: 1789226633Sdim // The 'option' variant doesn't encode 'U' in the immediate since 1790226633Sdim // the immediate is unsigned [0,255]. 1791288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 1792226633Sdim break; 1793226633Sdim } 1794226633Sdim 1795226633Sdim switch (Inst.getOpcode()) { 1796226633Sdim case ARM::LDC_OFFSET: 1797226633Sdim case ARM::LDC_PRE: 1798226633Sdim case ARM::LDC_POST: 1799226633Sdim case ARM::LDC_OPTION: 1800226633Sdim case ARM::LDCL_OFFSET: 1801226633Sdim case ARM::LDCL_PRE: 1802226633Sdim case ARM::LDCL_POST: 1803226633Sdim case ARM::LDCL_OPTION: 1804226633Sdim case ARM::STC_OFFSET: 1805226633Sdim case ARM::STC_PRE: 1806226633Sdim case ARM::STC_POST: 1807226633Sdim case ARM::STC_OPTION: 1808226633Sdim case ARM::STCL_OFFSET: 1809226633Sdim case ARM::STCL_PRE: 1810226633Sdim case ARM::STCL_POST: 1811226633Sdim case ARM::STCL_OPTION: 1812226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1813226633Sdim return MCDisassembler::Fail; 1814226633Sdim break; 1815226633Sdim default: 1816226633Sdim break; 1817226633Sdim } 1818226633Sdim 1819226633Sdim return S; 1820226633Sdim} 1821226633Sdim 1822226633Sdimstatic DecodeStatus 1823234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, 1824226633Sdim uint64_t Address, const void *Decoder) { 1825226633Sdim DecodeStatus S = MCDisassembler::Success; 1826226633Sdim 1827239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1828239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 1829239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1830239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 1831239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1832239462Sdim unsigned reg = fieldFromInstruction(Insn, 25, 1); 1833239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 1834239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 1835226633Sdim 1836226633Sdim // On stores, the writeback operand precedes Rt. 1837226633Sdim switch (Inst.getOpcode()) { 1838226633Sdim case ARM::STR_POST_IMM: 1839226633Sdim case ARM::STR_POST_REG: 1840226633Sdim case ARM::STRB_POST_IMM: 1841226633Sdim case ARM::STRB_POST_REG: 1842226633Sdim case ARM::STRT_POST_REG: 1843226633Sdim case ARM::STRT_POST_IMM: 1844226633Sdim case ARM::STRBT_POST_REG: 1845226633Sdim case ARM::STRBT_POST_IMM: 1846226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1847226633Sdim return MCDisassembler::Fail; 1848226633Sdim break; 1849226633Sdim default: 1850226633Sdim break; 1851226633Sdim } 1852226633Sdim 1853226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 1854226633Sdim return MCDisassembler::Fail; 1855226633Sdim 1856226633Sdim // On loads, the writeback operand comes after Rt. 1857226633Sdim switch (Inst.getOpcode()) { 1858226633Sdim case ARM::LDR_POST_IMM: 1859226633Sdim case ARM::LDR_POST_REG: 1860226633Sdim case ARM::LDRB_POST_IMM: 1861226633Sdim case ARM::LDRB_POST_REG: 1862226633Sdim case ARM::LDRBT_POST_REG: 1863226633Sdim case ARM::LDRBT_POST_IMM: 1864226633Sdim case ARM::LDRT_POST_REG: 1865226633Sdim case ARM::LDRT_POST_IMM: 1866226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1867226633Sdim return MCDisassembler::Fail; 1868226633Sdim break; 1869226633Sdim default: 1870226633Sdim break; 1871226633Sdim } 1872226633Sdim 1873226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1874226633Sdim return MCDisassembler::Fail; 1875226633Sdim 1876226633Sdim ARM_AM::AddrOpc Op = ARM_AM::add; 1877239462Sdim if (!fieldFromInstruction(Insn, 23, 1)) 1878226633Sdim Op = ARM_AM::sub; 1879226633Sdim 1880226633Sdim bool writeback = (P == 0) || (W == 1); 1881226633Sdim unsigned idx_mode = 0; 1882226633Sdim if (P && writeback) 1883226633Sdim idx_mode = ARMII::IndexModePre; 1884226633Sdim else if (!P && writeback) 1885226633Sdim idx_mode = ARMII::IndexModePost; 1886226633Sdim 1887226633Sdim if (writeback && (Rn == 15 || Rn == Rt)) 1888226633Sdim S = MCDisassembler::SoftFail; // UNPREDICTABLE 1889226633Sdim 1890226633Sdim if (reg) { 1891226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 1892226633Sdim return MCDisassembler::Fail; 1893226633Sdim ARM_AM::ShiftOpc Opc = ARM_AM::lsl; 1894239462Sdim switch( fieldFromInstruction(Insn, 5, 2)) { 1895226633Sdim case 0: 1896226633Sdim Opc = ARM_AM::lsl; 1897226633Sdim break; 1898226633Sdim case 1: 1899226633Sdim Opc = ARM_AM::lsr; 1900226633Sdim break; 1901226633Sdim case 2: 1902226633Sdim Opc = ARM_AM::asr; 1903226633Sdim break; 1904226633Sdim case 3: 1905226633Sdim Opc = ARM_AM::ror; 1906226633Sdim break; 1907206124Srdivacky default: 1908226633Sdim return MCDisassembler::Fail; 1909226633Sdim } 1910239462Sdim unsigned amt = fieldFromInstruction(Insn, 7, 5); 1911243830Sdim if (Opc == ARM_AM::ror && amt == 0) 1912243830Sdim Opc = ARM_AM::rrx; 1913226633Sdim unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode); 1914226633Sdim 1915288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 1916226633Sdim } else { 1917288943Sdim Inst.addOperand(MCOperand::createReg(0)); 1918226633Sdim unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode); 1919288943Sdim Inst.addOperand(MCOperand::createImm(tmp)); 1920226633Sdim } 1921226633Sdim 1922226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 1923226633Sdim return MCDisassembler::Fail; 1924226633Sdim 1925226633Sdim return S; 1926226633Sdim} 1927226633Sdim 1928234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val, 1929226633Sdim uint64_t Address, const void *Decoder) { 1930226633Sdim DecodeStatus S = MCDisassembler::Success; 1931226633Sdim 1932239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 1933239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 1934239462Sdim unsigned type = fieldFromInstruction(Val, 5, 2); 1935239462Sdim unsigned imm = fieldFromInstruction(Val, 7, 5); 1936239462Sdim unsigned U = fieldFromInstruction(Val, 12, 1); 1937226633Sdim 1938226633Sdim ARM_AM::ShiftOpc ShOp = ARM_AM::lsl; 1939226633Sdim switch (type) { 1940226633Sdim case 0: 1941226633Sdim ShOp = ARM_AM::lsl; 1942206124Srdivacky break; 1943226633Sdim case 1: 1944226633Sdim ShOp = ARM_AM::lsr; 1945226633Sdim break; 1946226633Sdim case 2: 1947226633Sdim ShOp = ARM_AM::asr; 1948226633Sdim break; 1949226633Sdim case 3: 1950226633Sdim ShOp = ARM_AM::ror; 1951226633Sdim break; 1952226633Sdim } 1953226633Sdim 1954243830Sdim if (ShOp == ARM_AM::ror && imm == 0) 1955243830Sdim ShOp = ARM_AM::rrx; 1956243830Sdim 1957226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 1958226633Sdim return MCDisassembler::Fail; 1959226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 1960226633Sdim return MCDisassembler::Fail; 1961226633Sdim unsigned shift; 1962226633Sdim if (U) 1963226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp); 1964226633Sdim else 1965226633Sdim shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp); 1966288943Sdim Inst.addOperand(MCOperand::createImm(shift)); 1967226633Sdim 1968226633Sdim return S; 1969226633Sdim} 1970226633Sdim 1971226633Sdimstatic DecodeStatus 1972234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn, 1973226633Sdim uint64_t Address, const void *Decoder) { 1974226633Sdim DecodeStatus S = MCDisassembler::Success; 1975226633Sdim 1976239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 1977239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 1978239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 1979239462Sdim unsigned type = fieldFromInstruction(Insn, 22, 1); 1980239462Sdim unsigned imm = fieldFromInstruction(Insn, 8, 4); 1981239462Sdim unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8; 1982239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 1983239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 1984239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 1985234353Sdim unsigned Rt2 = Rt + 1; 1986226633Sdim 1987226633Sdim bool writeback = (W == 1) | (P == 0); 1988226633Sdim 1989226633Sdim // For {LD,ST}RD, Rt must be even, else undefined. 1990226633Sdim switch (Inst.getOpcode()) { 1991226633Sdim case ARM::STRD: 1992226633Sdim case ARM::STRD_PRE: 1993226633Sdim case ARM::STRD_POST: 1994226633Sdim case ARM::LDRD: 1995226633Sdim case ARM::LDRD_PRE: 1996226633Sdim case ARM::LDRD_POST: 1997234353Sdim if (Rt & 0x1) S = MCDisassembler::SoftFail; 1998226633Sdim break; 1999226633Sdim default: 2000226633Sdim break; 2001226633Sdim } 2002234353Sdim switch (Inst.getOpcode()) { 2003234353Sdim case ARM::STRD: 2004234353Sdim case ARM::STRD_PRE: 2005234353Sdim case ARM::STRD_POST: 2006234353Sdim if (P == 0 && W == 1) 2007234353Sdim S = MCDisassembler::SoftFail; 2008296417Sdim 2009234353Sdim if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2)) 2010234353Sdim S = MCDisassembler::SoftFail; 2011234353Sdim if (type && Rm == 15) 2012234353Sdim S = MCDisassembler::SoftFail; 2013234353Sdim if (Rt2 == 15) 2014234353Sdim S = MCDisassembler::SoftFail; 2015239462Sdim if (!type && fieldFromInstruction(Insn, 8, 4)) 2016234353Sdim S = MCDisassembler::SoftFail; 2017234353Sdim break; 2018234353Sdim case ARM::STRH: 2019234353Sdim case ARM::STRH_PRE: 2020234353Sdim case ARM::STRH_POST: 2021234353Sdim if (Rt == 15) 2022234353Sdim S = MCDisassembler::SoftFail; 2023234353Sdim if (writeback && (Rn == 15 || Rn == Rt)) 2024234353Sdim S = MCDisassembler::SoftFail; 2025234353Sdim if (!type && Rm == 15) 2026234353Sdim S = MCDisassembler::SoftFail; 2027234353Sdim break; 2028234353Sdim case ARM::LDRD: 2029234353Sdim case ARM::LDRD_PRE: 2030234353Sdim case ARM::LDRD_POST: 2031321369Sdim if (type && Rn == 15) { 2032234353Sdim if (Rt2 == 15) 2033234353Sdim S = MCDisassembler::SoftFail; 2034234353Sdim break; 2035234353Sdim } 2036234353Sdim if (P == 0 && W == 1) 2037234353Sdim S = MCDisassembler::SoftFail; 2038234353Sdim if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2)) 2039234353Sdim S = MCDisassembler::SoftFail; 2040234353Sdim if (!type && writeback && Rn == 15) 2041234353Sdim S = MCDisassembler::SoftFail; 2042234353Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 2043234353Sdim S = MCDisassembler::SoftFail; 2044234353Sdim break; 2045234353Sdim case ARM::LDRH: 2046234353Sdim case ARM::LDRH_PRE: 2047234353Sdim case ARM::LDRH_POST: 2048321369Sdim if (type && Rn == 15) { 2049234353Sdim if (Rt == 15) 2050234353Sdim S = MCDisassembler::SoftFail; 2051234353Sdim break; 2052234353Sdim } 2053234353Sdim if (Rt == 15) 2054234353Sdim S = MCDisassembler::SoftFail; 2055234353Sdim if (!type && Rm == 15) 2056234353Sdim S = MCDisassembler::SoftFail; 2057234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 2058234353Sdim S = MCDisassembler::SoftFail; 2059234353Sdim break; 2060234353Sdim case ARM::LDRSH: 2061234353Sdim case ARM::LDRSH_PRE: 2062234353Sdim case ARM::LDRSH_POST: 2063234353Sdim case ARM::LDRSB: 2064234353Sdim case ARM::LDRSB_PRE: 2065234353Sdim case ARM::LDRSB_POST: 2066321369Sdim if (type && Rn == 15) { 2067234353Sdim if (Rt == 15) 2068234353Sdim S = MCDisassembler::SoftFail; 2069234353Sdim break; 2070234353Sdim } 2071234353Sdim if (type && (Rt == 15 || (writeback && Rn == Rt))) 2072234353Sdim S = MCDisassembler::SoftFail; 2073234353Sdim if (!type && (Rt == 15 || Rm == 15)) 2074234353Sdim S = MCDisassembler::SoftFail; 2075234353Sdim if (!type && writeback && (Rn == 15 || Rn == Rt)) 2076234353Sdim S = MCDisassembler::SoftFail; 2077234353Sdim break; 2078234353Sdim default: 2079234353Sdim break; 2080234353Sdim } 2081226633Sdim 2082226633Sdim if (writeback) { // Writeback 2083226633Sdim if (P) 2084226633Sdim U |= ARMII::IndexModePre << 9; 2085226633Sdim else 2086226633Sdim U |= ARMII::IndexModePost << 9; 2087226633Sdim 2088226633Sdim // On stores, the writeback operand precedes Rt. 2089226633Sdim switch (Inst.getOpcode()) { 2090226633Sdim case ARM::STRD: 2091226633Sdim case ARM::STRD_PRE: 2092226633Sdim case ARM::STRD_POST: 2093226633Sdim case ARM::STRH: 2094226633Sdim case ARM::STRH_PRE: 2095226633Sdim case ARM::STRH_POST: 2096226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2097226633Sdim return MCDisassembler::Fail; 2098226633Sdim break; 2099226633Sdim default: 2100226633Sdim break; 2101226633Sdim } 2102226633Sdim } 2103226633Sdim 2104226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 2105226633Sdim return MCDisassembler::Fail; 2106226633Sdim switch (Inst.getOpcode()) { 2107226633Sdim case ARM::STRD: 2108226633Sdim case ARM::STRD_PRE: 2109226633Sdim case ARM::STRD_POST: 2110226633Sdim case ARM::LDRD: 2111226633Sdim case ARM::LDRD_PRE: 2112226633Sdim case ARM::LDRD_POST: 2113226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) 2114226633Sdim return MCDisassembler::Fail; 2115226633Sdim break; 2116226633Sdim default: 2117226633Sdim break; 2118226633Sdim } 2119226633Sdim 2120226633Sdim if (writeback) { 2121226633Sdim // On loads, the writeback operand comes after Rt. 2122226633Sdim switch (Inst.getOpcode()) { 2123226633Sdim case ARM::LDRD: 2124226633Sdim case ARM::LDRD_PRE: 2125226633Sdim case ARM::LDRD_POST: 2126226633Sdim case ARM::LDRH: 2127226633Sdim case ARM::LDRH_PRE: 2128226633Sdim case ARM::LDRH_POST: 2129226633Sdim case ARM::LDRSH: 2130226633Sdim case ARM::LDRSH_PRE: 2131226633Sdim case ARM::LDRSH_POST: 2132226633Sdim case ARM::LDRSB: 2133226633Sdim case ARM::LDRSB_PRE: 2134226633Sdim case ARM::LDRSB_POST: 2135226633Sdim case ARM::LDRHTr: 2136226633Sdim case ARM::LDRSBTr: 2137226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2138226633Sdim return MCDisassembler::Fail; 2139226633Sdim break; 2140226633Sdim default: 2141226633Sdim break; 2142226633Sdim } 2143226633Sdim } 2144226633Sdim 2145226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2146226633Sdim return MCDisassembler::Fail; 2147226633Sdim 2148226633Sdim if (type) { 2149288943Sdim Inst.addOperand(MCOperand::createReg(0)); 2150288943Sdim Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm)); 2151226633Sdim } else { 2152226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2153226633Sdim return MCDisassembler::Fail; 2154288943Sdim Inst.addOperand(MCOperand::createImm(U)); 2155226633Sdim } 2156226633Sdim 2157226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2158226633Sdim return MCDisassembler::Fail; 2159226633Sdim 2160226633Sdim return S; 2161226633Sdim} 2162226633Sdim 2163234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn, 2164226633Sdim uint64_t Address, const void *Decoder) { 2165226633Sdim DecodeStatus S = MCDisassembler::Success; 2166226633Sdim 2167239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2168239462Sdim unsigned mode = fieldFromInstruction(Insn, 23, 2); 2169226633Sdim 2170226633Sdim switch (mode) { 2171226633Sdim case 0: 2172226633Sdim mode = ARM_AM::da; 2173226633Sdim break; 2174226633Sdim case 1: 2175226633Sdim mode = ARM_AM::ia; 2176226633Sdim break; 2177226633Sdim case 2: 2178226633Sdim mode = ARM_AM::db; 2179226633Sdim break; 2180226633Sdim case 3: 2181226633Sdim mode = ARM_AM::ib; 2182226633Sdim break; 2183226633Sdim } 2184226633Sdim 2185288943Sdim Inst.addOperand(MCOperand::createImm(mode)); 2186226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2187226633Sdim return MCDisassembler::Fail; 2188226633Sdim 2189226633Sdim return S; 2190226633Sdim} 2191226633Sdim 2192261991Sdimstatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn, 2193261991Sdim uint64_t Address, const void *Decoder) { 2194261991Sdim DecodeStatus S = MCDisassembler::Success; 2195261991Sdim 2196261991Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2197261991Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2198261991Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2199261991Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2200261991Sdim 2201261991Sdim if (pred == 0xF) 2202261991Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 2203261991Sdim 2204261991Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2205261991Sdim return MCDisassembler::Fail; 2206261991Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 2207261991Sdim return MCDisassembler::Fail; 2208261991Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 2209261991Sdim return MCDisassembler::Fail; 2210261991Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2211261991Sdim return MCDisassembler::Fail; 2212261991Sdim return S; 2213261991Sdim} 2214261991Sdim 2215234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst, 2216226633Sdim unsigned Insn, 2217226633Sdim uint64_t Address, const void *Decoder) { 2218226633Sdim DecodeStatus S = MCDisassembler::Success; 2219226633Sdim 2220239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2221239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2222239462Sdim unsigned reglist = fieldFromInstruction(Insn, 0, 16); 2223226633Sdim 2224226633Sdim if (pred == 0xF) { 2225261991Sdim // Ambiguous with RFE and SRS 2226226633Sdim switch (Inst.getOpcode()) { 2227226633Sdim case ARM::LDMDA: 2228226633Sdim Inst.setOpcode(ARM::RFEDA); 2229226633Sdim break; 2230226633Sdim case ARM::LDMDA_UPD: 2231226633Sdim Inst.setOpcode(ARM::RFEDA_UPD); 2232226633Sdim break; 2233226633Sdim case ARM::LDMDB: 2234226633Sdim Inst.setOpcode(ARM::RFEDB); 2235226633Sdim break; 2236226633Sdim case ARM::LDMDB_UPD: 2237226633Sdim Inst.setOpcode(ARM::RFEDB_UPD); 2238226633Sdim break; 2239226633Sdim case ARM::LDMIA: 2240226633Sdim Inst.setOpcode(ARM::RFEIA); 2241226633Sdim break; 2242226633Sdim case ARM::LDMIA_UPD: 2243226633Sdim Inst.setOpcode(ARM::RFEIA_UPD); 2244226633Sdim break; 2245226633Sdim case ARM::LDMIB: 2246226633Sdim Inst.setOpcode(ARM::RFEIB); 2247226633Sdim break; 2248226633Sdim case ARM::LDMIB_UPD: 2249226633Sdim Inst.setOpcode(ARM::RFEIB_UPD); 2250226633Sdim break; 2251226633Sdim case ARM::STMDA: 2252226633Sdim Inst.setOpcode(ARM::SRSDA); 2253226633Sdim break; 2254226633Sdim case ARM::STMDA_UPD: 2255226633Sdim Inst.setOpcode(ARM::SRSDA_UPD); 2256226633Sdim break; 2257226633Sdim case ARM::STMDB: 2258226633Sdim Inst.setOpcode(ARM::SRSDB); 2259226633Sdim break; 2260226633Sdim case ARM::STMDB_UPD: 2261226633Sdim Inst.setOpcode(ARM::SRSDB_UPD); 2262226633Sdim break; 2263226633Sdim case ARM::STMIA: 2264226633Sdim Inst.setOpcode(ARM::SRSIA); 2265226633Sdim break; 2266226633Sdim case ARM::STMIA_UPD: 2267226633Sdim Inst.setOpcode(ARM::SRSIA_UPD); 2268226633Sdim break; 2269226633Sdim case ARM::STMIB: 2270226633Sdim Inst.setOpcode(ARM::SRSIB); 2271226633Sdim break; 2272226633Sdim case ARM::STMIB_UPD: 2273226633Sdim Inst.setOpcode(ARM::SRSIB_UPD); 2274226633Sdim break; 2275206124Srdivacky default: 2276261991Sdim return MCDisassembler::Fail; 2277226633Sdim } 2278226633Sdim 2279226633Sdim // For stores (which become SRS's, the only operand is the mode. 2280239462Sdim if (fieldFromInstruction(Insn, 20, 1) == 0) { 2281261991Sdim // Check SRS encoding constraints 2282261991Sdim if (!(fieldFromInstruction(Insn, 22, 1) == 1 && 2283261991Sdim fieldFromInstruction(Insn, 20, 1) == 0)) 2284261991Sdim return MCDisassembler::Fail; 2285261991Sdim 2286226633Sdim Inst.addOperand( 2287288943Sdim MCOperand::createImm(fieldFromInstruction(Insn, 0, 4))); 2288226633Sdim return S; 2289226633Sdim } 2290226633Sdim 2291226633Sdim return DecodeRFEInstruction(Inst, Insn, Address, Decoder); 2292226633Sdim } 2293226633Sdim 2294226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2295226633Sdim return MCDisassembler::Fail; 2296226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2297226633Sdim return MCDisassembler::Fail; // Tied 2298226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2299226633Sdim return MCDisassembler::Fail; 2300226633Sdim if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder))) 2301226633Sdim return MCDisassembler::Fail; 2302226633Sdim 2303226633Sdim return S; 2304226633Sdim} 2305226633Sdim 2306309124Sdim// Check for UNPREDICTABLE predicated ESB instruction 2307309124Sdimstatic DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn, 2308309124Sdim uint64_t Address, const void *Decoder) { 2309309124Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2310309124Sdim unsigned imm8 = fieldFromInstruction(Insn, 0, 8); 2311309124Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 2312309124Sdim const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits(); 2313309124Sdim 2314309124Sdim DecodeStatus S = MCDisassembler::Success; 2315309124Sdim 2316309124Sdim Inst.addOperand(MCOperand::createImm(imm8)); 2317309124Sdim 2318309124Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2319309124Sdim return MCDisassembler::Fail; 2320309124Sdim 2321309124Sdim // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP, 2322309124Sdim // so all predicates should be allowed. 2323309124Sdim if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0)) 2324309124Sdim S = MCDisassembler::SoftFail; 2325309124Sdim 2326309124Sdim return S; 2327309124Sdim} 2328309124Sdim 2329234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, 2330226633Sdim uint64_t Address, const void *Decoder) { 2331239462Sdim unsigned imod = fieldFromInstruction(Insn, 18, 2); 2332239462Sdim unsigned M = fieldFromInstruction(Insn, 17, 1); 2333239462Sdim unsigned iflags = fieldFromInstruction(Insn, 6, 3); 2334239462Sdim unsigned mode = fieldFromInstruction(Insn, 0, 5); 2335226633Sdim 2336226633Sdim DecodeStatus S = MCDisassembler::Success; 2337226633Sdim 2338261991Sdim // This decoder is called from multiple location that do not check 2339261991Sdim // the full encoding is valid before they do. 2340261991Sdim if (fieldFromInstruction(Insn, 5, 1) != 0 || 2341261991Sdim fieldFromInstruction(Insn, 16, 1) != 0 || 2342261991Sdim fieldFromInstruction(Insn, 20, 8) != 0x10) 2343261991Sdim return MCDisassembler::Fail; 2344261991Sdim 2345226633Sdim // imod == '01' --> UNPREDICTABLE 2346226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 2347226633Sdim // return failure here. The '01' imod value is unprintable, so there's 2348226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 2349226633Sdim 2350226633Sdim if (imod == 1) return MCDisassembler::Fail; 2351226633Sdim 2352226633Sdim if (imod && M) { 2353226633Sdim Inst.setOpcode(ARM::CPS3p); 2354288943Sdim Inst.addOperand(MCOperand::createImm(imod)); 2355288943Sdim Inst.addOperand(MCOperand::createImm(iflags)); 2356288943Sdim Inst.addOperand(MCOperand::createImm(mode)); 2357226633Sdim } else if (imod && !M) { 2358226633Sdim Inst.setOpcode(ARM::CPS2p); 2359288943Sdim Inst.addOperand(MCOperand::createImm(imod)); 2360288943Sdim Inst.addOperand(MCOperand::createImm(iflags)); 2361226633Sdim if (mode) S = MCDisassembler::SoftFail; 2362226633Sdim } else if (!imod && M) { 2363226633Sdim Inst.setOpcode(ARM::CPS1p); 2364288943Sdim Inst.addOperand(MCOperand::createImm(mode)); 2365226633Sdim if (iflags) S = MCDisassembler::SoftFail; 2366226633Sdim } else { 2367226633Sdim // imod == '00' && M == '0' --> UNPREDICTABLE 2368226633Sdim Inst.setOpcode(ARM::CPS1p); 2369288943Sdim Inst.addOperand(MCOperand::createImm(mode)); 2370226633Sdim S = MCDisassembler::SoftFail; 2371226633Sdim } 2372226633Sdim 2373226633Sdim return S; 2374226633Sdim} 2375226633Sdim 2376234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, 2377226633Sdim uint64_t Address, const void *Decoder) { 2378239462Sdim unsigned imod = fieldFromInstruction(Insn, 9, 2); 2379239462Sdim unsigned M = fieldFromInstruction(Insn, 8, 1); 2380239462Sdim unsigned iflags = fieldFromInstruction(Insn, 5, 3); 2381239462Sdim unsigned mode = fieldFromInstruction(Insn, 0, 5); 2382226633Sdim 2383226633Sdim DecodeStatus S = MCDisassembler::Success; 2384226633Sdim 2385226633Sdim // imod == '01' --> UNPREDICTABLE 2386226633Sdim // NOTE: Even though this is technically UNPREDICTABLE, we choose to 2387226633Sdim // return failure here. The '01' imod value is unprintable, so there's 2388226633Sdim // nothing useful we could do even if we returned UNPREDICTABLE. 2389226633Sdim 2390226633Sdim if (imod == 1) return MCDisassembler::Fail; 2391226633Sdim 2392226633Sdim if (imod && M) { 2393226633Sdim Inst.setOpcode(ARM::t2CPS3p); 2394288943Sdim Inst.addOperand(MCOperand::createImm(imod)); 2395288943Sdim Inst.addOperand(MCOperand::createImm(iflags)); 2396288943Sdim Inst.addOperand(MCOperand::createImm(mode)); 2397226633Sdim } else if (imod && !M) { 2398226633Sdim Inst.setOpcode(ARM::t2CPS2p); 2399288943Sdim Inst.addOperand(MCOperand::createImm(imod)); 2400288943Sdim Inst.addOperand(MCOperand::createImm(iflags)); 2401226633Sdim if (mode) S = MCDisassembler::SoftFail; 2402226633Sdim } else if (!imod && M) { 2403226633Sdim Inst.setOpcode(ARM::t2CPS1p); 2404288943Sdim Inst.addOperand(MCOperand::createImm(mode)); 2405226633Sdim if (iflags) S = MCDisassembler::SoftFail; 2406226633Sdim } else { 2407251662Sdim // imod == '00' && M == '0' --> this is a HINT instruction 2408251662Sdim int imm = fieldFromInstruction(Insn, 0, 8); 2409251662Sdim // HINT are defined only for immediate in [0..4] 2410251662Sdim if(imm > 4) return MCDisassembler::Fail; 2411251662Sdim Inst.setOpcode(ARM::t2HINT); 2412288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 2413226633Sdim } 2414226633Sdim 2415226633Sdim return S; 2416226633Sdim} 2417226633Sdim 2418234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, 2419226633Sdim uint64_t Address, const void *Decoder) { 2420226633Sdim DecodeStatus S = MCDisassembler::Success; 2421226633Sdim 2422239462Sdim unsigned Rd = fieldFromInstruction(Insn, 8, 4); 2423226633Sdim unsigned imm = 0; 2424226633Sdim 2425239462Sdim imm |= (fieldFromInstruction(Insn, 0, 8) << 0); 2426239462Sdim imm |= (fieldFromInstruction(Insn, 12, 3) << 8); 2427239462Sdim imm |= (fieldFromInstruction(Insn, 16, 4) << 12); 2428239462Sdim imm |= (fieldFromInstruction(Insn, 26, 1) << 11); 2429226633Sdim 2430226633Sdim if (Inst.getOpcode() == ARM::t2MOVTi16) 2431226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 2432226633Sdim return MCDisassembler::Fail; 2433226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) 2434226633Sdim return MCDisassembler::Fail; 2435226633Sdim 2436226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 2437288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 2438226633Sdim 2439226633Sdim return S; 2440226633Sdim} 2441226633Sdim 2442234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, 2443226633Sdim uint64_t Address, const void *Decoder) { 2444226633Sdim DecodeStatus S = MCDisassembler::Success; 2445226633Sdim 2446239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2447239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2448226633Sdim unsigned imm = 0; 2449226633Sdim 2450239462Sdim imm |= (fieldFromInstruction(Insn, 0, 12) << 0); 2451239462Sdim imm |= (fieldFromInstruction(Insn, 16, 4) << 12); 2452226633Sdim 2453226633Sdim if (Inst.getOpcode() == ARM::MOVTi16) 2454251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2455226633Sdim return MCDisassembler::Fail; 2456251662Sdim 2457251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2458226633Sdim return MCDisassembler::Fail; 2459226633Sdim 2460226633Sdim if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) 2461288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 2462226633Sdim 2463226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2464226633Sdim return MCDisassembler::Fail; 2465226633Sdim 2466226633Sdim return S; 2467226633Sdim} 2468226633Sdim 2469234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, 2470226633Sdim uint64_t Address, const void *Decoder) { 2471226633Sdim DecodeStatus S = MCDisassembler::Success; 2472226633Sdim 2473239462Sdim unsigned Rd = fieldFromInstruction(Insn, 16, 4); 2474239462Sdim unsigned Rn = fieldFromInstruction(Insn, 0, 4); 2475239462Sdim unsigned Rm = fieldFromInstruction(Insn, 8, 4); 2476239462Sdim unsigned Ra = fieldFromInstruction(Insn, 12, 4); 2477239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2478226633Sdim 2479226633Sdim if (pred == 0xF) 2480226633Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 2481226633Sdim 2482226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 2483226633Sdim return MCDisassembler::Fail; 2484226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 2485226633Sdim return MCDisassembler::Fail; 2486226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 2487226633Sdim return MCDisassembler::Fail; 2488226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder))) 2489226633Sdim return MCDisassembler::Fail; 2490226633Sdim 2491226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2492226633Sdim return MCDisassembler::Fail; 2493226633Sdim 2494226633Sdim return S; 2495226633Sdim} 2496226633Sdim 2497288943Sdimstatic DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn, 2498288943Sdim uint64_t Address, const void *Decoder) { 2499288943Sdim DecodeStatus S = MCDisassembler::Success; 2500288943Sdim 2501288943Sdim unsigned Pred = fieldFromInstruction(Insn, 28, 4); 2502288943Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2503288943Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2504288943Sdim 2505288943Sdim if (Pred == 0xF) 2506288943Sdim return DecodeSETPANInstruction(Inst, Insn, Address, Decoder); 2507288943Sdim 2508288943Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2509288943Sdim return MCDisassembler::Fail; 2510288943Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2511288943Sdim return MCDisassembler::Fail; 2512288943Sdim if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder))) 2513288943Sdim return MCDisassembler::Fail; 2514288943Sdim 2515288943Sdim return S; 2516288943Sdim} 2517288943Sdim 2518288943Sdimstatic DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn, 2519288943Sdim uint64_t Address, const void *Decoder) { 2520288943Sdim DecodeStatus S = MCDisassembler::Success; 2521288943Sdim 2522288943Sdim unsigned Imm = fieldFromInstruction(Insn, 9, 1); 2523288943Sdim 2524288943Sdim const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 2525288943Sdim const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits(); 2526288943Sdim 2527341825Sdim if (!FeatureBits[ARM::HasV8_1aOps] || 2528288943Sdim !FeatureBits[ARM::HasV8Ops]) 2529288943Sdim return MCDisassembler::Fail; 2530288943Sdim 2531288943Sdim // Decoder can be called from DecodeTST, which does not check the full 2532288943Sdim // encoding is valid. 2533288943Sdim if (fieldFromInstruction(Insn, 20,12) != 0xf11 || 2534288943Sdim fieldFromInstruction(Insn, 4,4) != 0) 2535288943Sdim return MCDisassembler::Fail; 2536288943Sdim if (fieldFromInstruction(Insn, 10,10) != 0 || 2537288943Sdim fieldFromInstruction(Insn, 0,4) != 0) 2538288943Sdim S = MCDisassembler::SoftFail; 2539288943Sdim 2540288943Sdim Inst.setOpcode(ARM::SETPAN); 2541288943Sdim Inst.addOperand(MCOperand::createImm(Imm)); 2542288943Sdim 2543288943Sdim return S; 2544288943Sdim} 2545288943Sdim 2546234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, 2547226633Sdim uint64_t Address, const void *Decoder) { 2548226633Sdim DecodeStatus S = MCDisassembler::Success; 2549226633Sdim 2550239462Sdim unsigned add = fieldFromInstruction(Val, 12, 1); 2551239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 12); 2552239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 2553226633Sdim 2554226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2555226633Sdim return MCDisassembler::Fail; 2556226633Sdim 2557226633Sdim if (!add) imm *= -1; 2558226633Sdim if (imm == 0 && !add) imm = INT32_MIN; 2559288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 2560226633Sdim if (Rn == 15) 2561226633Sdim tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder); 2562226633Sdim 2563226633Sdim return S; 2564226633Sdim} 2565226633Sdim 2566234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, 2567226633Sdim uint64_t Address, const void *Decoder) { 2568226633Sdim DecodeStatus S = MCDisassembler::Success; 2569226633Sdim 2570239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 2571309124Sdim // U == 1 to add imm, 0 to subtract it. 2572239462Sdim unsigned U = fieldFromInstruction(Val, 8, 1); 2573239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 2574226633Sdim 2575226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2576226633Sdim return MCDisassembler::Fail; 2577226633Sdim 2578226633Sdim if (U) 2579288943Sdim Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm))); 2580226633Sdim else 2581288943Sdim Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm))); 2582226633Sdim 2583226633Sdim return S; 2584226633Sdim} 2585226633Sdim 2586309124Sdimstatic DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val, 2587309124Sdim uint64_t Address, const void *Decoder) { 2588309124Sdim DecodeStatus S = MCDisassembler::Success; 2589309124Sdim 2590309124Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 2591309124Sdim // U == 1 to add imm, 0 to subtract it. 2592309124Sdim unsigned U = fieldFromInstruction(Val, 8, 1); 2593309124Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 2594309124Sdim 2595309124Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 2596309124Sdim return MCDisassembler::Fail; 2597309124Sdim 2598309124Sdim if (U) 2599309124Sdim Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm))); 2600309124Sdim else 2601309124Sdim Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm))); 2602309124Sdim 2603309124Sdim return S; 2604309124Sdim} 2605309124Sdim 2606234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, 2607226633Sdim uint64_t Address, const void *Decoder) { 2608226633Sdim return DecodeGPRRegisterClass(Inst, Val, Address, Decoder); 2609226633Sdim} 2610226633Sdim 2611226633Sdimstatic DecodeStatus 2612234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn, 2613234353Sdim uint64_t Address, const void *Decoder) { 2614243830Sdim DecodeStatus Status = MCDisassembler::Success; 2615243830Sdim 2616243830Sdim // Note the J1 and J2 values are from the encoded instruction. So here 2617243830Sdim // change them to I1 and I2 values via as documented: 2618243830Sdim // I1 = NOT(J1 EOR S); 2619243830Sdim // I2 = NOT(J2 EOR S); 2620243830Sdim // and build the imm32 with one trailing zero as documented: 2621243830Sdim // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); 2622243830Sdim unsigned S = fieldFromInstruction(Insn, 26, 1); 2623243830Sdim unsigned J1 = fieldFromInstruction(Insn, 13, 1); 2624243830Sdim unsigned J2 = fieldFromInstruction(Insn, 11, 1); 2625243830Sdim unsigned I1 = !(J1 ^ S); 2626243830Sdim unsigned I2 = !(J2 ^ S); 2627243830Sdim unsigned imm10 = fieldFromInstruction(Insn, 16, 10); 2628243830Sdim unsigned imm11 = fieldFromInstruction(Insn, 0, 11); 2629243830Sdim unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11; 2630261991Sdim int imm32 = SignExtend32<25>(tmp << 1); 2631243830Sdim if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, 2632234353Sdim true, 4, Inst, Decoder)) 2633288943Sdim Inst.addOperand(MCOperand::createImm(imm32)); 2634243830Sdim 2635243830Sdim return Status; 2636234353Sdim} 2637234353Sdim 2638234353Sdimstatic DecodeStatus 2639234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn, 2640226633Sdim uint64_t Address, const void *Decoder) { 2641226633Sdim DecodeStatus S = MCDisassembler::Success; 2642226633Sdim 2643239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 2644239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2; 2645226633Sdim 2646226633Sdim if (pred == 0xF) { 2647226633Sdim Inst.setOpcode(ARM::BLXi); 2648239462Sdim imm |= fieldFromInstruction(Insn, 24, 1) << 1; 2649234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2650234353Sdim true, 4, Inst, Decoder)) 2651288943Sdim Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm))); 2652226633Sdim return S; 2653226633Sdim } 2654226633Sdim 2655234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, 2656234353Sdim true, 4, Inst, Decoder)) 2657288943Sdim Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm))); 2658226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 2659226633Sdim return MCDisassembler::Fail; 2660226633Sdim 2661226633Sdim return S; 2662226633Sdim} 2663226633Sdim 2664234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, 2665226633Sdim uint64_t Address, const void *Decoder) { 2666226633Sdim DecodeStatus S = MCDisassembler::Success; 2667226633Sdim 2668239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 2669239462Sdim unsigned align = fieldFromInstruction(Val, 4, 2); 2670226633Sdim 2671226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2672226633Sdim return MCDisassembler::Fail; 2673226633Sdim if (!align) 2674288943Sdim Inst.addOperand(MCOperand::createImm(0)); 2675226633Sdim else 2676288943Sdim Inst.addOperand(MCOperand::createImm(4 << align)); 2677226633Sdim 2678226633Sdim return S; 2679226633Sdim} 2680226633Sdim 2681234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn, 2682226633Sdim uint64_t Address, const void *Decoder) { 2683226633Sdim DecodeStatus S = MCDisassembler::Success; 2684226633Sdim 2685239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 2686239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 2687239462Sdim unsigned wb = fieldFromInstruction(Insn, 16, 4); 2688239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 2689239462Sdim Rn |= fieldFromInstruction(Insn, 4, 2) << 4; 2690239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 2691226633Sdim 2692226633Sdim // First output register 2693234353Sdim switch (Inst.getOpcode()) { 2694234353Sdim case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8: 2695234353Sdim case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register: 2696234353Sdim case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register: 2697234353Sdim case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register: 2698234353Sdim case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register: 2699234353Sdim case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8: 2700234353Sdim case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register: 2701234353Sdim case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register: 2702234353Sdim case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register: 2703234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 2704234353Sdim return MCDisassembler::Fail; 2705234353Sdim break; 2706234353Sdim case ARM::VLD2b16: 2707234353Sdim case ARM::VLD2b32: 2708234353Sdim case ARM::VLD2b8: 2709234353Sdim case ARM::VLD2b16wb_fixed: 2710234353Sdim case ARM::VLD2b16wb_register: 2711234353Sdim case ARM::VLD2b32wb_fixed: 2712234353Sdim case ARM::VLD2b32wb_register: 2713234353Sdim case ARM::VLD2b8wb_fixed: 2714234353Sdim case ARM::VLD2b8wb_register: 2715234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 2716234353Sdim return MCDisassembler::Fail; 2717234353Sdim break; 2718234353Sdim default: 2719234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 2720234353Sdim return MCDisassembler::Fail; 2721234353Sdim } 2722226633Sdim 2723226633Sdim // Second output register 2724226633Sdim switch (Inst.getOpcode()) { 2725226633Sdim case ARM::VLD3d8: 2726226633Sdim case ARM::VLD3d16: 2727226633Sdim case ARM::VLD3d32: 2728226633Sdim case ARM::VLD3d8_UPD: 2729226633Sdim case ARM::VLD3d16_UPD: 2730226633Sdim case ARM::VLD3d32_UPD: 2731226633Sdim case ARM::VLD4d8: 2732226633Sdim case ARM::VLD4d16: 2733226633Sdim case ARM::VLD4d32: 2734226633Sdim case ARM::VLD4d8_UPD: 2735226633Sdim case ARM::VLD4d16_UPD: 2736226633Sdim case ARM::VLD4d32_UPD: 2737226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 2738226633Sdim return MCDisassembler::Fail; 2739206124Srdivacky break; 2740226633Sdim case ARM::VLD3q8: 2741226633Sdim case ARM::VLD3q16: 2742226633Sdim case ARM::VLD3q32: 2743226633Sdim case ARM::VLD3q8_UPD: 2744226633Sdim case ARM::VLD3q16_UPD: 2745226633Sdim case ARM::VLD3q32_UPD: 2746226633Sdim case ARM::VLD4q8: 2747226633Sdim case ARM::VLD4q16: 2748226633Sdim case ARM::VLD4q32: 2749226633Sdim case ARM::VLD4q8_UPD: 2750226633Sdim case ARM::VLD4q16_UPD: 2751226633Sdim case ARM::VLD4q32_UPD: 2752226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2753226633Sdim return MCDisassembler::Fail; 2754327952Sdim break; 2755206124Srdivacky default: 2756226633Sdim break; 2757226633Sdim } 2758226633Sdim 2759226633Sdim // Third output register 2760226633Sdim switch(Inst.getOpcode()) { 2761226633Sdim case ARM::VLD3d8: 2762226633Sdim case ARM::VLD3d16: 2763226633Sdim case ARM::VLD3d32: 2764226633Sdim case ARM::VLD3d8_UPD: 2765226633Sdim case ARM::VLD3d16_UPD: 2766226633Sdim case ARM::VLD3d32_UPD: 2767226633Sdim case ARM::VLD4d8: 2768226633Sdim case ARM::VLD4d16: 2769226633Sdim case ARM::VLD4d32: 2770226633Sdim case ARM::VLD4d8_UPD: 2771226633Sdim case ARM::VLD4d16_UPD: 2772226633Sdim case ARM::VLD4d32_UPD: 2773226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 2774226633Sdim return MCDisassembler::Fail; 2775226633Sdim break; 2776226633Sdim case ARM::VLD3q8: 2777226633Sdim case ARM::VLD3q16: 2778226633Sdim case ARM::VLD3q32: 2779226633Sdim case ARM::VLD3q8_UPD: 2780226633Sdim case ARM::VLD3q16_UPD: 2781226633Sdim case ARM::VLD3q32_UPD: 2782226633Sdim case ARM::VLD4q8: 2783226633Sdim case ARM::VLD4q16: 2784226633Sdim case ARM::VLD4q32: 2785226633Sdim case ARM::VLD4q8_UPD: 2786226633Sdim case ARM::VLD4q16_UPD: 2787226633Sdim case ARM::VLD4q32_UPD: 2788226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 2789226633Sdim return MCDisassembler::Fail; 2790226633Sdim break; 2791226633Sdim default: 2792226633Sdim break; 2793226633Sdim } 2794226633Sdim 2795226633Sdim // Fourth output register 2796226633Sdim switch (Inst.getOpcode()) { 2797226633Sdim case ARM::VLD4d8: 2798226633Sdim case ARM::VLD4d16: 2799226633Sdim case ARM::VLD4d32: 2800226633Sdim case ARM::VLD4d8_UPD: 2801226633Sdim case ARM::VLD4d16_UPD: 2802226633Sdim case ARM::VLD4d32_UPD: 2803226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 2804226633Sdim return MCDisassembler::Fail; 2805226633Sdim break; 2806226633Sdim case ARM::VLD4q8: 2807226633Sdim case ARM::VLD4q16: 2808226633Sdim case ARM::VLD4q32: 2809226633Sdim case ARM::VLD4q8_UPD: 2810226633Sdim case ARM::VLD4q16_UPD: 2811226633Sdim case ARM::VLD4q32_UPD: 2812226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 2813226633Sdim return MCDisassembler::Fail; 2814226633Sdim break; 2815226633Sdim default: 2816226633Sdim break; 2817226633Sdim } 2818226633Sdim 2819226633Sdim // Writeback operand 2820226633Sdim switch (Inst.getOpcode()) { 2821234353Sdim case ARM::VLD1d8wb_fixed: 2822234353Sdim case ARM::VLD1d16wb_fixed: 2823234353Sdim case ARM::VLD1d32wb_fixed: 2824234353Sdim case ARM::VLD1d64wb_fixed: 2825234353Sdim case ARM::VLD1d8wb_register: 2826234353Sdim case ARM::VLD1d16wb_register: 2827234353Sdim case ARM::VLD1d32wb_register: 2828234353Sdim case ARM::VLD1d64wb_register: 2829234353Sdim case ARM::VLD1q8wb_fixed: 2830234353Sdim case ARM::VLD1q16wb_fixed: 2831234353Sdim case ARM::VLD1q32wb_fixed: 2832234353Sdim case ARM::VLD1q64wb_fixed: 2833234353Sdim case ARM::VLD1q8wb_register: 2834234353Sdim case ARM::VLD1q16wb_register: 2835234353Sdim case ARM::VLD1q32wb_register: 2836234353Sdim case ARM::VLD1q64wb_register: 2837234353Sdim case ARM::VLD1d8Twb_fixed: 2838234353Sdim case ARM::VLD1d8Twb_register: 2839234353Sdim case ARM::VLD1d16Twb_fixed: 2840234353Sdim case ARM::VLD1d16Twb_register: 2841234353Sdim case ARM::VLD1d32Twb_fixed: 2842234353Sdim case ARM::VLD1d32Twb_register: 2843234353Sdim case ARM::VLD1d64Twb_fixed: 2844234353Sdim case ARM::VLD1d64Twb_register: 2845234353Sdim case ARM::VLD1d8Qwb_fixed: 2846234353Sdim case ARM::VLD1d8Qwb_register: 2847234353Sdim case ARM::VLD1d16Qwb_fixed: 2848234353Sdim case ARM::VLD1d16Qwb_register: 2849234353Sdim case ARM::VLD1d32Qwb_fixed: 2850234353Sdim case ARM::VLD1d32Qwb_register: 2851234353Sdim case ARM::VLD1d64Qwb_fixed: 2852234353Sdim case ARM::VLD1d64Qwb_register: 2853234353Sdim case ARM::VLD2d8wb_fixed: 2854234353Sdim case ARM::VLD2d16wb_fixed: 2855234353Sdim case ARM::VLD2d32wb_fixed: 2856234353Sdim case ARM::VLD2q8wb_fixed: 2857234353Sdim case ARM::VLD2q16wb_fixed: 2858234353Sdim case ARM::VLD2q32wb_fixed: 2859234353Sdim case ARM::VLD2d8wb_register: 2860234353Sdim case ARM::VLD2d16wb_register: 2861234353Sdim case ARM::VLD2d32wb_register: 2862234353Sdim case ARM::VLD2q8wb_register: 2863234353Sdim case ARM::VLD2q16wb_register: 2864234353Sdim case ARM::VLD2q32wb_register: 2865234353Sdim case ARM::VLD2b8wb_fixed: 2866234353Sdim case ARM::VLD2b16wb_fixed: 2867234353Sdim case ARM::VLD2b32wb_fixed: 2868234353Sdim case ARM::VLD2b8wb_register: 2869234353Sdim case ARM::VLD2b16wb_register: 2870234353Sdim case ARM::VLD2b32wb_register: 2871288943Sdim Inst.addOperand(MCOperand::createImm(0)); 2872234353Sdim break; 2873226633Sdim case ARM::VLD3d8_UPD: 2874226633Sdim case ARM::VLD3d16_UPD: 2875226633Sdim case ARM::VLD3d32_UPD: 2876226633Sdim case ARM::VLD3q8_UPD: 2877226633Sdim case ARM::VLD3q16_UPD: 2878226633Sdim case ARM::VLD3q32_UPD: 2879226633Sdim case ARM::VLD4d8_UPD: 2880226633Sdim case ARM::VLD4d16_UPD: 2881226633Sdim case ARM::VLD4d32_UPD: 2882226633Sdim case ARM::VLD4q8_UPD: 2883226633Sdim case ARM::VLD4q16_UPD: 2884226633Sdim case ARM::VLD4q32_UPD: 2885226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 2886226633Sdim return MCDisassembler::Fail; 2887226633Sdim break; 2888226633Sdim default: 2889226633Sdim break; 2890226633Sdim } 2891226633Sdim 2892226633Sdim // AddrMode6 Base (register+alignment) 2893226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 2894226633Sdim return MCDisassembler::Fail; 2895226633Sdim 2896226633Sdim // AddrMode6 Offset (register) 2897234353Sdim switch (Inst.getOpcode()) { 2898234353Sdim default: 2899234353Sdim // The below have been updated to have explicit am6offset split 2900234353Sdim // between fixed and register offset. For those instructions not 2901234353Sdim // yet updated, we need to add an additional reg0 operand for the 2902234353Sdim // fixed variant. 2903234353Sdim // 2904234353Sdim // The fixed offset encodes as Rm == 0xd, so we check for that. 2905234353Sdim if (Rm == 0xd) { 2906288943Sdim Inst.addOperand(MCOperand::createReg(0)); 2907234353Sdim break; 2908234353Sdim } 2909234353Sdim // Fall through to handle the register offset variant. 2910314564Sdim LLVM_FALLTHROUGH; 2911234353Sdim case ARM::VLD1d8wb_fixed: 2912234353Sdim case ARM::VLD1d16wb_fixed: 2913234353Sdim case ARM::VLD1d32wb_fixed: 2914234353Sdim case ARM::VLD1d64wb_fixed: 2915234353Sdim case ARM::VLD1d8Twb_fixed: 2916234353Sdim case ARM::VLD1d16Twb_fixed: 2917234353Sdim case ARM::VLD1d32Twb_fixed: 2918234353Sdim case ARM::VLD1d64Twb_fixed: 2919234353Sdim case ARM::VLD1d8Qwb_fixed: 2920234353Sdim case ARM::VLD1d16Qwb_fixed: 2921234353Sdim case ARM::VLD1d32Qwb_fixed: 2922234353Sdim case ARM::VLD1d64Qwb_fixed: 2923234353Sdim case ARM::VLD1d8wb_register: 2924234353Sdim case ARM::VLD1d16wb_register: 2925234353Sdim case ARM::VLD1d32wb_register: 2926234353Sdim case ARM::VLD1d64wb_register: 2927234353Sdim case ARM::VLD1q8wb_fixed: 2928234353Sdim case ARM::VLD1q16wb_fixed: 2929234353Sdim case ARM::VLD1q32wb_fixed: 2930234353Sdim case ARM::VLD1q64wb_fixed: 2931234353Sdim case ARM::VLD1q8wb_register: 2932234353Sdim case ARM::VLD1q16wb_register: 2933234353Sdim case ARM::VLD1q32wb_register: 2934234353Sdim case ARM::VLD1q64wb_register: 2935234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 2936234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 2937234353Sdim // increment and we need to add the register operand to the instruction. 2938234353Sdim if (Rm != 0xD && Rm != 0xF && 2939234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 2940226633Sdim return MCDisassembler::Fail; 2941234353Sdim break; 2942234353Sdim case ARM::VLD2d8wb_fixed: 2943234353Sdim case ARM::VLD2d16wb_fixed: 2944234353Sdim case ARM::VLD2d32wb_fixed: 2945234353Sdim case ARM::VLD2b8wb_fixed: 2946234353Sdim case ARM::VLD2b16wb_fixed: 2947234353Sdim case ARM::VLD2b32wb_fixed: 2948234353Sdim case ARM::VLD2q8wb_fixed: 2949234353Sdim case ARM::VLD2q16wb_fixed: 2950234353Sdim case ARM::VLD2q32wb_fixed: 2951234353Sdim break; 2952226633Sdim } 2953226633Sdim 2954226633Sdim return S; 2955226633Sdim} 2956226633Sdim 2957261991Sdimstatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn, 2958261991Sdim uint64_t Address, const void *Decoder) { 2959261991Sdim unsigned type = fieldFromInstruction(Insn, 8, 4); 2960261991Sdim unsigned align = fieldFromInstruction(Insn, 4, 2); 2961261991Sdim if (type == 6 && (align & 2)) return MCDisassembler::Fail; 2962261991Sdim if (type == 7 && (align & 2)) return MCDisassembler::Fail; 2963261991Sdim if (type == 10 && align == 3) return MCDisassembler::Fail; 2964261991Sdim 2965261991Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2966261991Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2967261991Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2968261991Sdim} 2969261991Sdim 2970261991Sdimstatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn, 2971261991Sdim uint64_t Address, const void *Decoder) { 2972261991Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2973261991Sdim if (size == 3) return MCDisassembler::Fail; 2974261991Sdim 2975261991Sdim unsigned type = fieldFromInstruction(Insn, 8, 4); 2976261991Sdim unsigned align = fieldFromInstruction(Insn, 4, 2); 2977261991Sdim if (type == 8 && align == 3) return MCDisassembler::Fail; 2978261991Sdim if (type == 9 && align == 3) return MCDisassembler::Fail; 2979261991Sdim 2980261991Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2981261991Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2982261991Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2983261991Sdim} 2984261991Sdim 2985261991Sdimstatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn, 2986261991Sdim uint64_t Address, const void *Decoder) { 2987261991Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 2988261991Sdim if (size == 3) return MCDisassembler::Fail; 2989261991Sdim 2990261991Sdim unsigned align = fieldFromInstruction(Insn, 4, 2); 2991261991Sdim if (align & 2) return MCDisassembler::Fail; 2992261991Sdim 2993261991Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 2994261991Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 2995261991Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 2996261991Sdim} 2997261991Sdim 2998261991Sdimstatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn, 2999261991Sdim uint64_t Address, const void *Decoder) { 3000261991Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 3001261991Sdim if (size == 3) return MCDisassembler::Fail; 3002261991Sdim 3003261991Sdim unsigned load = fieldFromInstruction(Insn, 21, 1); 3004261991Sdim return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder) 3005261991Sdim : DecodeVSTInstruction(Inst, Insn, Address, Decoder); 3006261991Sdim} 3007261991Sdim 3008234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn, 3009226633Sdim uint64_t Address, const void *Decoder) { 3010226633Sdim DecodeStatus S = MCDisassembler::Success; 3011226633Sdim 3012239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3013239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3014239462Sdim unsigned wb = fieldFromInstruction(Insn, 16, 4); 3015239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3016239462Sdim Rn |= fieldFromInstruction(Insn, 4, 2) << 4; 3017239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3018226633Sdim 3019226633Sdim // Writeback Operand 3020226633Sdim switch (Inst.getOpcode()) { 3021234353Sdim case ARM::VST1d8wb_fixed: 3022234353Sdim case ARM::VST1d16wb_fixed: 3023234353Sdim case ARM::VST1d32wb_fixed: 3024234353Sdim case ARM::VST1d64wb_fixed: 3025234353Sdim case ARM::VST1d8wb_register: 3026234353Sdim case ARM::VST1d16wb_register: 3027234353Sdim case ARM::VST1d32wb_register: 3028234353Sdim case ARM::VST1d64wb_register: 3029234353Sdim case ARM::VST1q8wb_fixed: 3030234353Sdim case ARM::VST1q16wb_fixed: 3031234353Sdim case ARM::VST1q32wb_fixed: 3032234353Sdim case ARM::VST1q64wb_fixed: 3033234353Sdim case ARM::VST1q8wb_register: 3034234353Sdim case ARM::VST1q16wb_register: 3035234353Sdim case ARM::VST1q32wb_register: 3036234353Sdim case ARM::VST1q64wb_register: 3037234353Sdim case ARM::VST1d8Twb_fixed: 3038234353Sdim case ARM::VST1d16Twb_fixed: 3039234353Sdim case ARM::VST1d32Twb_fixed: 3040234353Sdim case ARM::VST1d64Twb_fixed: 3041234353Sdim case ARM::VST1d8Twb_register: 3042234353Sdim case ARM::VST1d16Twb_register: 3043234353Sdim case ARM::VST1d32Twb_register: 3044234353Sdim case ARM::VST1d64Twb_register: 3045234353Sdim case ARM::VST1d8Qwb_fixed: 3046234353Sdim case ARM::VST1d16Qwb_fixed: 3047234353Sdim case ARM::VST1d32Qwb_fixed: 3048234353Sdim case ARM::VST1d64Qwb_fixed: 3049234353Sdim case ARM::VST1d8Qwb_register: 3050234353Sdim case ARM::VST1d16Qwb_register: 3051234353Sdim case ARM::VST1d32Qwb_register: 3052234353Sdim case ARM::VST1d64Qwb_register: 3053234353Sdim case ARM::VST2d8wb_fixed: 3054234353Sdim case ARM::VST2d16wb_fixed: 3055234353Sdim case ARM::VST2d32wb_fixed: 3056234353Sdim case ARM::VST2d8wb_register: 3057234353Sdim case ARM::VST2d16wb_register: 3058234353Sdim case ARM::VST2d32wb_register: 3059234353Sdim case ARM::VST2q8wb_fixed: 3060234353Sdim case ARM::VST2q16wb_fixed: 3061234353Sdim case ARM::VST2q32wb_fixed: 3062234353Sdim case ARM::VST2q8wb_register: 3063234353Sdim case ARM::VST2q16wb_register: 3064234353Sdim case ARM::VST2q32wb_register: 3065234353Sdim case ARM::VST2b8wb_fixed: 3066234353Sdim case ARM::VST2b16wb_fixed: 3067234353Sdim case ARM::VST2b32wb_fixed: 3068234353Sdim case ARM::VST2b8wb_register: 3069234353Sdim case ARM::VST2b16wb_register: 3070234353Sdim case ARM::VST2b32wb_register: 3071234353Sdim if (Rm == 0xF) 3072234353Sdim return MCDisassembler::Fail; 3073288943Sdim Inst.addOperand(MCOperand::createImm(0)); 3074234353Sdim break; 3075226633Sdim case ARM::VST3d8_UPD: 3076226633Sdim case ARM::VST3d16_UPD: 3077226633Sdim case ARM::VST3d32_UPD: 3078226633Sdim case ARM::VST3q8_UPD: 3079226633Sdim case ARM::VST3q16_UPD: 3080226633Sdim case ARM::VST3q32_UPD: 3081226633Sdim case ARM::VST4d8_UPD: 3082226633Sdim case ARM::VST4d16_UPD: 3083226633Sdim case ARM::VST4d32_UPD: 3084226633Sdim case ARM::VST4q8_UPD: 3085226633Sdim case ARM::VST4q16_UPD: 3086226633Sdim case ARM::VST4q32_UPD: 3087226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) 3088226633Sdim return MCDisassembler::Fail; 3089226633Sdim break; 3090226633Sdim default: 3091226633Sdim break; 3092226633Sdim } 3093226633Sdim 3094226633Sdim // AddrMode6 Base (register+alignment) 3095226633Sdim if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) 3096226633Sdim return MCDisassembler::Fail; 3097226633Sdim 3098226633Sdim // AddrMode6 Offset (register) 3099234353Sdim switch (Inst.getOpcode()) { 3100234353Sdim default: 3101234353Sdim if (Rm == 0xD) 3102288943Sdim Inst.addOperand(MCOperand::createReg(0)); 3103234353Sdim else if (Rm != 0xF) { 3104234353Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3105234353Sdim return MCDisassembler::Fail; 3106234353Sdim } 3107234353Sdim break; 3108234353Sdim case ARM::VST1d8wb_fixed: 3109234353Sdim case ARM::VST1d16wb_fixed: 3110234353Sdim case ARM::VST1d32wb_fixed: 3111234353Sdim case ARM::VST1d64wb_fixed: 3112234353Sdim case ARM::VST1q8wb_fixed: 3113234353Sdim case ARM::VST1q16wb_fixed: 3114234353Sdim case ARM::VST1q32wb_fixed: 3115234353Sdim case ARM::VST1q64wb_fixed: 3116234353Sdim case ARM::VST1d8Twb_fixed: 3117234353Sdim case ARM::VST1d16Twb_fixed: 3118234353Sdim case ARM::VST1d32Twb_fixed: 3119234353Sdim case ARM::VST1d64Twb_fixed: 3120234353Sdim case ARM::VST1d8Qwb_fixed: 3121234353Sdim case ARM::VST1d16Qwb_fixed: 3122234353Sdim case ARM::VST1d32Qwb_fixed: 3123234353Sdim case ARM::VST1d64Qwb_fixed: 3124234353Sdim case ARM::VST2d8wb_fixed: 3125234353Sdim case ARM::VST2d16wb_fixed: 3126234353Sdim case ARM::VST2d32wb_fixed: 3127234353Sdim case ARM::VST2q8wb_fixed: 3128234353Sdim case ARM::VST2q16wb_fixed: 3129234353Sdim case ARM::VST2q32wb_fixed: 3130234353Sdim case ARM::VST2b8wb_fixed: 3131234353Sdim case ARM::VST2b16wb_fixed: 3132234353Sdim case ARM::VST2b32wb_fixed: 3133234353Sdim break; 3134226633Sdim } 3135226633Sdim 3136226633Sdim // First input register 3137234353Sdim switch (Inst.getOpcode()) { 3138234353Sdim case ARM::VST1q16: 3139234353Sdim case ARM::VST1q32: 3140234353Sdim case ARM::VST1q64: 3141234353Sdim case ARM::VST1q8: 3142234353Sdim case ARM::VST1q16wb_fixed: 3143234353Sdim case ARM::VST1q16wb_register: 3144234353Sdim case ARM::VST1q32wb_fixed: 3145234353Sdim case ARM::VST1q32wb_register: 3146234353Sdim case ARM::VST1q64wb_fixed: 3147234353Sdim case ARM::VST1q64wb_register: 3148234353Sdim case ARM::VST1q8wb_fixed: 3149234353Sdim case ARM::VST1q8wb_register: 3150234353Sdim case ARM::VST2d16: 3151234353Sdim case ARM::VST2d32: 3152234353Sdim case ARM::VST2d8: 3153234353Sdim case ARM::VST2d16wb_fixed: 3154234353Sdim case ARM::VST2d16wb_register: 3155234353Sdim case ARM::VST2d32wb_fixed: 3156234353Sdim case ARM::VST2d32wb_register: 3157234353Sdim case ARM::VST2d8wb_fixed: 3158234353Sdim case ARM::VST2d8wb_register: 3159234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 3160234353Sdim return MCDisassembler::Fail; 3161234353Sdim break; 3162234353Sdim case ARM::VST2b16: 3163234353Sdim case ARM::VST2b32: 3164234353Sdim case ARM::VST2b8: 3165234353Sdim case ARM::VST2b16wb_fixed: 3166234353Sdim case ARM::VST2b16wb_register: 3167234353Sdim case ARM::VST2b32wb_fixed: 3168234353Sdim case ARM::VST2b32wb_register: 3169234353Sdim case ARM::VST2b8wb_fixed: 3170234353Sdim case ARM::VST2b8wb_register: 3171234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 3172234353Sdim return MCDisassembler::Fail; 3173234353Sdim break; 3174234353Sdim default: 3175234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3176234353Sdim return MCDisassembler::Fail; 3177234353Sdim } 3178226633Sdim 3179226633Sdim // Second input register 3180226633Sdim switch (Inst.getOpcode()) { 3181226633Sdim case ARM::VST3d8: 3182226633Sdim case ARM::VST3d16: 3183226633Sdim case ARM::VST3d32: 3184226633Sdim case ARM::VST3d8_UPD: 3185226633Sdim case ARM::VST3d16_UPD: 3186226633Sdim case ARM::VST3d32_UPD: 3187226633Sdim case ARM::VST4d8: 3188226633Sdim case ARM::VST4d16: 3189226633Sdim case ARM::VST4d32: 3190226633Sdim case ARM::VST4d8_UPD: 3191226633Sdim case ARM::VST4d16_UPD: 3192226633Sdim case ARM::VST4d32_UPD: 3193226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) 3194226633Sdim return MCDisassembler::Fail; 3195226633Sdim break; 3196226633Sdim case ARM::VST3q8: 3197226633Sdim case ARM::VST3q16: 3198226633Sdim case ARM::VST3q32: 3199226633Sdim case ARM::VST3q8_UPD: 3200226633Sdim case ARM::VST3q16_UPD: 3201226633Sdim case ARM::VST3q32_UPD: 3202226633Sdim case ARM::VST4q8: 3203226633Sdim case ARM::VST4q16: 3204226633Sdim case ARM::VST4q32: 3205226633Sdim case ARM::VST4q8_UPD: 3206226633Sdim case ARM::VST4q16_UPD: 3207226633Sdim case ARM::VST4q32_UPD: 3208226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 3209226633Sdim return MCDisassembler::Fail; 3210226633Sdim break; 3211226633Sdim default: 3212226633Sdim break; 3213226633Sdim } 3214226633Sdim 3215226633Sdim // Third input register 3216226633Sdim switch (Inst.getOpcode()) { 3217226633Sdim case ARM::VST3d8: 3218226633Sdim case ARM::VST3d16: 3219226633Sdim case ARM::VST3d32: 3220226633Sdim case ARM::VST3d8_UPD: 3221226633Sdim case ARM::VST3d16_UPD: 3222226633Sdim case ARM::VST3d32_UPD: 3223226633Sdim case ARM::VST4d8: 3224226633Sdim case ARM::VST4d16: 3225226633Sdim case ARM::VST4d32: 3226226633Sdim case ARM::VST4d8_UPD: 3227226633Sdim case ARM::VST4d16_UPD: 3228226633Sdim case ARM::VST4d32_UPD: 3229226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) 3230226633Sdim return MCDisassembler::Fail; 3231226633Sdim break; 3232226633Sdim case ARM::VST3q8: 3233226633Sdim case ARM::VST3q16: 3234226633Sdim case ARM::VST3q32: 3235226633Sdim case ARM::VST3q8_UPD: 3236226633Sdim case ARM::VST3q16_UPD: 3237226633Sdim case ARM::VST3q32_UPD: 3238226633Sdim case ARM::VST4q8: 3239226633Sdim case ARM::VST4q16: 3240226633Sdim case ARM::VST4q32: 3241226633Sdim case ARM::VST4q8_UPD: 3242226633Sdim case ARM::VST4q16_UPD: 3243226633Sdim case ARM::VST4q32_UPD: 3244226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) 3245226633Sdim return MCDisassembler::Fail; 3246226633Sdim break; 3247226633Sdim default: 3248226633Sdim break; 3249226633Sdim } 3250226633Sdim 3251226633Sdim // Fourth input register 3252226633Sdim switch (Inst.getOpcode()) { 3253226633Sdim case ARM::VST4d8: 3254226633Sdim case ARM::VST4d16: 3255226633Sdim case ARM::VST4d32: 3256226633Sdim case ARM::VST4d8_UPD: 3257226633Sdim case ARM::VST4d16_UPD: 3258226633Sdim case ARM::VST4d32_UPD: 3259226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) 3260226633Sdim return MCDisassembler::Fail; 3261226633Sdim break; 3262226633Sdim case ARM::VST4q8: 3263226633Sdim case ARM::VST4q16: 3264226633Sdim case ARM::VST4q32: 3265226633Sdim case ARM::VST4q8_UPD: 3266226633Sdim case ARM::VST4q16_UPD: 3267226633Sdim case ARM::VST4q32_UPD: 3268226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) 3269226633Sdim return MCDisassembler::Fail; 3270226633Sdim break; 3271226633Sdim default: 3272226633Sdim break; 3273226633Sdim } 3274226633Sdim 3275226633Sdim return S; 3276226633Sdim} 3277226633Sdim 3278234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn, 3279226633Sdim uint64_t Address, const void *Decoder) { 3280226633Sdim DecodeStatus S = MCDisassembler::Success; 3281226633Sdim 3282239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3283239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3284239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3285239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3286239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 3287239462Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 3288226633Sdim 3289243830Sdim if (size == 0 && align == 1) 3290243830Sdim return MCDisassembler::Fail; 3291226633Sdim align *= (1 << size); 3292226633Sdim 3293234353Sdim switch (Inst.getOpcode()) { 3294234353Sdim case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8: 3295234353Sdim case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register: 3296234353Sdim case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register: 3297234353Sdim case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register: 3298234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 3299226633Sdim return MCDisassembler::Fail; 3300234353Sdim break; 3301234353Sdim default: 3302234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3303234353Sdim return MCDisassembler::Fail; 3304234353Sdim break; 3305226633Sdim } 3306226633Sdim if (Rm != 0xF) { 3307226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3308226633Sdim return MCDisassembler::Fail; 3309226633Sdim } 3310226633Sdim 3311226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3312226633Sdim return MCDisassembler::Fail; 3313288943Sdim Inst.addOperand(MCOperand::createImm(align)); 3314226633Sdim 3315234353Sdim // The fixed offset post-increment encodes Rm == 0xd. The no-writeback 3316234353Sdim // variant encodes Rm == 0xf. Anything else is a register offset post- 3317234353Sdim // increment and we need to add the register operand to the instruction. 3318234353Sdim if (Rm != 0xD && Rm != 0xF && 3319234353Sdim !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3320234353Sdim return MCDisassembler::Fail; 3321226633Sdim 3322226633Sdim return S; 3323226633Sdim} 3324226633Sdim 3325234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, 3326226633Sdim uint64_t Address, const void *Decoder) { 3327226633Sdim DecodeStatus S = MCDisassembler::Success; 3328226633Sdim 3329239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3330239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3331239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3332239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3333239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 3334239462Sdim unsigned size = 1 << fieldFromInstruction(Insn, 6, 2); 3335226633Sdim align *= 2*size; 3336226633Sdim 3337234353Sdim switch (Inst.getOpcode()) { 3338234353Sdim case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8: 3339234353Sdim case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register: 3340234353Sdim case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register: 3341234353Sdim case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register: 3342234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) 3343226633Sdim return MCDisassembler::Fail; 3344234353Sdim break; 3345234353Sdim case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2: 3346234353Sdim case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register: 3347234353Sdim case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register: 3348234353Sdim case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register: 3349234353Sdim if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) 3350234353Sdim return MCDisassembler::Fail; 3351234353Sdim break; 3352234353Sdim default: 3353234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3354234353Sdim return MCDisassembler::Fail; 3355234353Sdim break; 3356226633Sdim } 3357226633Sdim 3358234353Sdim if (Rm != 0xF) 3359288943Sdim Inst.addOperand(MCOperand::createImm(0)); 3360234353Sdim 3361226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3362226633Sdim return MCDisassembler::Fail; 3363288943Sdim Inst.addOperand(MCOperand::createImm(align)); 3364226633Sdim 3365234982Sdim if (Rm != 0xD && Rm != 0xF) { 3366226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3367226633Sdim return MCDisassembler::Fail; 3368226633Sdim } 3369226633Sdim 3370226633Sdim return S; 3371226633Sdim} 3372226633Sdim 3373234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn, 3374226633Sdim uint64_t Address, const void *Decoder) { 3375226633Sdim DecodeStatus S = MCDisassembler::Success; 3376226633Sdim 3377239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3378239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3379239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3380239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3381239462Sdim unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; 3382226633Sdim 3383226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3384226633Sdim return MCDisassembler::Fail; 3385226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 3386226633Sdim return MCDisassembler::Fail; 3387226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 3388226633Sdim return MCDisassembler::Fail; 3389226633Sdim if (Rm != 0xF) { 3390226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3391226633Sdim return MCDisassembler::Fail; 3392226633Sdim } 3393226633Sdim 3394226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3395226633Sdim return MCDisassembler::Fail; 3396288943Sdim Inst.addOperand(MCOperand::createImm(0)); 3397226633Sdim 3398226633Sdim if (Rm == 0xD) 3399288943Sdim Inst.addOperand(MCOperand::createReg(0)); 3400226633Sdim else if (Rm != 0xF) { 3401226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3402226633Sdim return MCDisassembler::Fail; 3403226633Sdim } 3404226633Sdim 3405226633Sdim return S; 3406226633Sdim} 3407226633Sdim 3408234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn, 3409226633Sdim uint64_t Address, const void *Decoder) { 3410226633Sdim DecodeStatus S = MCDisassembler::Success; 3411226633Sdim 3412239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3413239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3414239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3415239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3416239462Sdim unsigned size = fieldFromInstruction(Insn, 6, 2); 3417239462Sdim unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; 3418239462Sdim unsigned align = fieldFromInstruction(Insn, 4, 1); 3419226633Sdim 3420226633Sdim if (size == 0x3) { 3421243830Sdim if (align == 0) 3422243830Sdim return MCDisassembler::Fail; 3423226633Sdim align = 16; 3424226633Sdim } else { 3425226633Sdim if (size == 2) { 3426226633Sdim align *= 8; 3427226633Sdim } else { 3428226633Sdim size = 1 << size; 3429226633Sdim align *= 4*size; 3430206124Srdivacky } 3431206124Srdivacky } 3432206124Srdivacky 3433226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3434226633Sdim return MCDisassembler::Fail; 3435226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) 3436226633Sdim return MCDisassembler::Fail; 3437226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) 3438226633Sdim return MCDisassembler::Fail; 3439226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder))) 3440226633Sdim return MCDisassembler::Fail; 3441226633Sdim if (Rm != 0xF) { 3442226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3443226633Sdim return MCDisassembler::Fail; 3444226633Sdim } 3445226633Sdim 3446226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3447226633Sdim return MCDisassembler::Fail; 3448288943Sdim Inst.addOperand(MCOperand::createImm(align)); 3449226633Sdim 3450226633Sdim if (Rm == 0xD) 3451288943Sdim Inst.addOperand(MCOperand::createReg(0)); 3452226633Sdim else if (Rm != 0xF) { 3453226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 3454226633Sdim return MCDisassembler::Fail; 3455226633Sdim } 3456226633Sdim 3457226633Sdim return S; 3458206124Srdivacky} 3459206124Srdivacky 3460226633Sdimstatic DecodeStatus 3461360784SdimDecodeVMOVModImmInstruction(MCInst &Inst, unsigned Insn, 3462226633Sdim uint64_t Address, const void *Decoder) { 3463226633Sdim DecodeStatus S = MCDisassembler::Success; 3464206124Srdivacky 3465239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3466239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3467239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 3468239462Sdim imm |= fieldFromInstruction(Insn, 16, 3) << 4; 3469239462Sdim imm |= fieldFromInstruction(Insn, 24, 1) << 7; 3470239462Sdim imm |= fieldFromInstruction(Insn, 8, 4) << 8; 3471239462Sdim imm |= fieldFromInstruction(Insn, 5, 1) << 12; 3472239462Sdim unsigned Q = fieldFromInstruction(Insn, 6, 1); 3473206124Srdivacky 3474226633Sdim if (Q) { 3475226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 3476226633Sdim return MCDisassembler::Fail; 3477226633Sdim } else { 3478226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3479226633Sdim return MCDisassembler::Fail; 3480226633Sdim } 3481206124Srdivacky 3482288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 3483206124Srdivacky 3484226633Sdim switch (Inst.getOpcode()) { 3485226633Sdim case ARM::VORRiv4i16: 3486226633Sdim case ARM::VORRiv2i32: 3487226633Sdim case ARM::VBICiv4i16: 3488226633Sdim case ARM::VBICiv2i32: 3489226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3490226633Sdim return MCDisassembler::Fail; 3491226633Sdim break; 3492226633Sdim case ARM::VORRiv8i16: 3493226633Sdim case ARM::VORRiv4i32: 3494226633Sdim case ARM::VBICiv8i16: 3495226633Sdim case ARM::VBICiv4i32: 3496226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 3497226633Sdim return MCDisassembler::Fail; 3498226633Sdim break; 3499226633Sdim default: 3500226633Sdim break; 3501226633Sdim } 3502206124Srdivacky 3503226633Sdim return S; 3504226633Sdim} 3505226633Sdim 3506353358Sdimstatic DecodeStatus 3507353358SdimDecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn, 3508353358Sdim uint64_t Address, const void *Decoder) { 3509353358Sdim DecodeStatus S = MCDisassembler::Success; 3510353358Sdim 3511353358Sdim unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) | 3512353358Sdim fieldFromInstruction(Insn, 13, 3)); 3513353358Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 3514353358Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 3515353358Sdim imm |= fieldFromInstruction(Insn, 16, 3) << 4; 3516353358Sdim imm |= fieldFromInstruction(Insn, 28, 1) << 7; 3517353358Sdim imm |= cmode << 8; 3518353358Sdim imm |= fieldFromInstruction(Insn, 5, 1) << 12; 3519353358Sdim 3520353358Sdim if (cmode == 0xF && Inst.getOpcode() == ARM::MVE_VMVNimmi32) 3521353358Sdim return MCDisassembler::Fail; 3522353358Sdim 3523353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 3524353358Sdim return MCDisassembler::Fail; 3525353358Sdim 3526353358Sdim Inst.addOperand(MCOperand::createImm(imm)); 3527353358Sdim 3528353358Sdim Inst.addOperand(MCOperand::createImm(ARMVCC::None)); 3529353358Sdim Inst.addOperand(MCOperand::createReg(0)); 3530353358Sdim Inst.addOperand(MCOperand::createImm(0)); 3531353358Sdim 3532353358Sdim return S; 3533353358Sdim} 3534353358Sdim 3535353358Sdimstatic DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn, 3536353358Sdim uint64_t Address, const void *Decoder) { 3537353358Sdim DecodeStatus S = MCDisassembler::Success; 3538353358Sdim 3539353358Sdim unsigned Qd = fieldFromInstruction(Insn, 13, 3); 3540353358Sdim Qd |= fieldFromInstruction(Insn, 22, 1) << 3; 3541353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 3542353358Sdim return MCDisassembler::Fail; 3543353358Sdim Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV)); 3544353358Sdim 3545353358Sdim unsigned Qn = fieldFromInstruction(Insn, 17, 3); 3546353358Sdim Qn |= fieldFromInstruction(Insn, 7, 1) << 3; 3547353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder))) 3548353358Sdim return MCDisassembler::Fail; 3549353358Sdim unsigned Qm = fieldFromInstruction(Insn, 1, 3); 3550353358Sdim Qm |= fieldFromInstruction(Insn, 5, 1) << 3; 3551353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) 3552353358Sdim return MCDisassembler::Fail; 3553353358Sdim if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR 3554353358Sdim Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV)); 3555353358Sdim Inst.addOperand(MCOperand::createImm(Qd)); 3556353358Sdim 3557353358Sdim return S; 3558353358Sdim} 3559353358Sdim 3560234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn, 3561226633Sdim uint64_t Address, const void *Decoder) { 3562226633Sdim DecodeStatus S = MCDisassembler::Success; 3563226633Sdim 3564239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3565239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3566239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3567239462Sdim Rm |= fieldFromInstruction(Insn, 5, 1) << 4; 3568239462Sdim unsigned size = fieldFromInstruction(Insn, 18, 2); 3569226633Sdim 3570226633Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) 3571226633Sdim return MCDisassembler::Fail; 3572226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 3573226633Sdim return MCDisassembler::Fail; 3574288943Sdim Inst.addOperand(MCOperand::createImm(8 << size)); 3575226633Sdim 3576226633Sdim return S; 3577226633Sdim} 3578226633Sdim 3579234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, 3580226633Sdim uint64_t Address, const void *Decoder) { 3581288943Sdim Inst.addOperand(MCOperand::createImm(8 - Val)); 3582226633Sdim return MCDisassembler::Success; 3583226633Sdim} 3584226633Sdim 3585234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, 3586226633Sdim uint64_t Address, const void *Decoder) { 3587288943Sdim Inst.addOperand(MCOperand::createImm(16 - Val)); 3588226633Sdim return MCDisassembler::Success; 3589226633Sdim} 3590226633Sdim 3591234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, 3592226633Sdim uint64_t Address, const void *Decoder) { 3593288943Sdim Inst.addOperand(MCOperand::createImm(32 - Val)); 3594226633Sdim return MCDisassembler::Success; 3595226633Sdim} 3596226633Sdim 3597234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, 3598226633Sdim uint64_t Address, const void *Decoder) { 3599288943Sdim Inst.addOperand(MCOperand::createImm(64 - Val)); 3600226633Sdim return MCDisassembler::Success; 3601226633Sdim} 3602226633Sdim 3603234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, 3604226633Sdim uint64_t Address, const void *Decoder) { 3605226633Sdim DecodeStatus S = MCDisassembler::Success; 3606226633Sdim 3607239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 3608239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 3609239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3610239462Sdim Rn |= fieldFromInstruction(Insn, 7, 1) << 4; 3611239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 3612239462Sdim Rm |= fieldFromInstruction(Insn, 5, 1) << 4; 3613239462Sdim unsigned op = fieldFromInstruction(Insn, 6, 1); 3614226633Sdim 3615226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3616226633Sdim return MCDisassembler::Fail; 3617226633Sdim if (op) { 3618226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 3619226633Sdim return MCDisassembler::Fail; // Writeback 3620206124Srdivacky } 3621226633Sdim 3622234353Sdim switch (Inst.getOpcode()) { 3623234353Sdim case ARM::VTBL2: 3624234353Sdim case ARM::VTBX2: 3625234353Sdim if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder))) 3626234353Sdim return MCDisassembler::Fail; 3627234353Sdim break; 3628234353Sdim default: 3629234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder))) 3630234353Sdim return MCDisassembler::Fail; 3631226633Sdim } 3632226633Sdim 3633226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) 3634226633Sdim return MCDisassembler::Fail; 3635226633Sdim 3636226633Sdim return S; 3637206124Srdivacky} 3638206124Srdivacky 3639234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, 3640226633Sdim uint64_t Address, const void *Decoder) { 3641226633Sdim DecodeStatus S = MCDisassembler::Success; 3642221345Sdim 3643239462Sdim unsigned dst = fieldFromInstruction(Insn, 8, 3); 3644239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 3645221345Sdim 3646226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder))) 3647226633Sdim return MCDisassembler::Fail; 3648226633Sdim 3649226633Sdim switch(Inst.getOpcode()) { 3650226633Sdim default: 3651226633Sdim return MCDisassembler::Fail; 3652226633Sdim case ARM::tADR: 3653226633Sdim break; // tADR does not explicitly represent the PC as an operand. 3654226633Sdim case ARM::tADDrSPi: 3655288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 3656226633Sdim break; 3657221345Sdim } 3658226633Sdim 3659288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 3660226633Sdim return S; 3661221345Sdim} 3662221345Sdim 3663234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, 3664226633Sdim uint64_t Address, const void *Decoder) { 3665234353Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4, 3666234353Sdim true, 2, Inst, Decoder)) 3667288943Sdim Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1))); 3668226633Sdim return MCDisassembler::Success; 3669226633Sdim} 3670206124Srdivacky 3671234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, 3672226633Sdim uint64_t Address, const void *Decoder) { 3673239462Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4, 3674234353Sdim true, 4, Inst, Decoder)) 3675288943Sdim Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val))); 3676226633Sdim return MCDisassembler::Success; 3677226633Sdim} 3678206124Srdivacky 3679234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, 3680226633Sdim uint64_t Address, const void *Decoder) { 3681249423Sdim if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4, 3682234353Sdim true, 2, Inst, Decoder)) 3683288943Sdim Inst.addOperand(MCOperand::createImm(Val << 1)); 3684226633Sdim return MCDisassembler::Success; 3685226633Sdim} 3686206124Srdivacky 3687234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, 3688226633Sdim uint64_t Address, const void *Decoder) { 3689226633Sdim DecodeStatus S = MCDisassembler::Success; 3690206124Srdivacky 3691239462Sdim unsigned Rn = fieldFromInstruction(Val, 0, 3); 3692239462Sdim unsigned Rm = fieldFromInstruction(Val, 3, 3); 3693226633Sdim 3694226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3695226633Sdim return MCDisassembler::Fail; 3696226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder))) 3697226633Sdim return MCDisassembler::Fail; 3698226633Sdim 3699226633Sdim return S; 3700226633Sdim} 3701226633Sdim 3702234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, 3703226633Sdim uint64_t Address, const void *Decoder) { 3704226633Sdim DecodeStatus S = MCDisassembler::Success; 3705226633Sdim 3706239462Sdim unsigned Rn = fieldFromInstruction(Val, 0, 3); 3707239462Sdim unsigned imm = fieldFromInstruction(Val, 3, 5); 3708226633Sdim 3709226633Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 3710226633Sdim return MCDisassembler::Fail; 3711288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 3712226633Sdim 3713226633Sdim return S; 3714226633Sdim} 3715226633Sdim 3716234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, 3717226633Sdim uint64_t Address, const void *Decoder) { 3718226633Sdim unsigned imm = Val << 2; 3719226633Sdim 3720288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 3721226633Sdim tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder); 3722226633Sdim 3723226633Sdim return MCDisassembler::Success; 3724226633Sdim} 3725226633Sdim 3726234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, 3727226633Sdim uint64_t Address, const void *Decoder) { 3728288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 3729288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 3730226633Sdim 3731226633Sdim return MCDisassembler::Success; 3732226633Sdim} 3733226633Sdim 3734234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, 3735226633Sdim uint64_t Address, const void *Decoder) { 3736226633Sdim DecodeStatus S = MCDisassembler::Success; 3737226633Sdim 3738239462Sdim unsigned Rn = fieldFromInstruction(Val, 6, 4); 3739239462Sdim unsigned Rm = fieldFromInstruction(Val, 2, 4); 3740239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 2); 3741226633Sdim 3742261991Sdim // Thumb stores cannot use PC as dest register. 3743261991Sdim switch (Inst.getOpcode()) { 3744261991Sdim case ARM::t2STRHs: 3745261991Sdim case ARM::t2STRBs: 3746261991Sdim case ARM::t2STRs: 3747261991Sdim if (Rn == 15) 3748261991Sdim return MCDisassembler::Fail; 3749327952Sdim break; 3750261991Sdim default: 3751261991Sdim break; 3752261991Sdim } 3753261991Sdim 3754226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 3755226633Sdim return MCDisassembler::Fail; 3756226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 3757226633Sdim return MCDisassembler::Fail; 3758288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 3759226633Sdim 3760226633Sdim return S; 3761226633Sdim} 3762226633Sdim 3763234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn, 3764226633Sdim uint64_t Address, const void *Decoder) { 3765226633Sdim DecodeStatus S = MCDisassembler::Success; 3766226633Sdim 3767261991Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3768261991Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3769261991Sdim 3770288943Sdim const FeatureBitset &featureBits = 3771288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 3772280031Sdim 3773288943Sdim bool hasMP = featureBits[ARM::FeatureMP]; 3774288943Sdim bool hasV7Ops = featureBits[ARM::HasV7Ops]; 3775288943Sdim 3776261991Sdim if (Rn == 15) { 3777261991Sdim switch (Inst.getOpcode()) { 3778261991Sdim case ARM::t2LDRBs: 3779261991Sdim Inst.setOpcode(ARM::t2LDRBpci); 3780261991Sdim break; 3781261991Sdim case ARM::t2LDRHs: 3782261991Sdim Inst.setOpcode(ARM::t2LDRHpci); 3783261991Sdim break; 3784261991Sdim case ARM::t2LDRSHs: 3785261991Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3786261991Sdim break; 3787261991Sdim case ARM::t2LDRSBs: 3788261991Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3789261991Sdim break; 3790261991Sdim case ARM::t2LDRs: 3791261991Sdim Inst.setOpcode(ARM::t2LDRpci); 3792261991Sdim break; 3793261991Sdim case ARM::t2PLDs: 3794261991Sdim Inst.setOpcode(ARM::t2PLDpci); 3795261991Sdim break; 3796261991Sdim case ARM::t2PLIs: 3797261991Sdim Inst.setOpcode(ARM::t2PLIpci); 3798261991Sdim break; 3799261991Sdim default: 3800261991Sdim return MCDisassembler::Fail; 3801261991Sdim } 3802261991Sdim 3803261991Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3804261991Sdim } 3805261991Sdim 3806261991Sdim if (Rt == 15) { 3807261991Sdim switch (Inst.getOpcode()) { 3808261991Sdim case ARM::t2LDRSHs: 3809261991Sdim return MCDisassembler::Fail; 3810261991Sdim case ARM::t2LDRHs: 3811261991Sdim Inst.setOpcode(ARM::t2PLDWs); 3812261991Sdim break; 3813280031Sdim case ARM::t2LDRSBs: 3814280031Sdim Inst.setOpcode(ARM::t2PLIs); 3815327952Sdim break; 3816261991Sdim default: 3817261991Sdim break; 3818261991Sdim } 3819261991Sdim } 3820261991Sdim 3821226633Sdim switch (Inst.getOpcode()) { 3822226633Sdim case ARM::t2PLDs: 3823280031Sdim break; 3824226633Sdim case ARM::t2PLIs: 3825280031Sdim if (!hasV7Ops) 3826280031Sdim return MCDisassembler::Fail; 3827226633Sdim break; 3828280031Sdim case ARM::t2PLDWs: 3829280031Sdim if (!hasV7Ops || !hasMP) 3830280031Sdim return MCDisassembler::Fail; 3831280031Sdim break; 3832261991Sdim default: 3833261991Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3834261991Sdim return MCDisassembler::Fail; 3835261991Sdim } 3836261991Sdim 3837261991Sdim unsigned addrmode = fieldFromInstruction(Insn, 4, 2); 3838261991Sdim addrmode |= fieldFromInstruction(Insn, 0, 4) << 2; 3839261991Sdim addrmode |= fieldFromInstruction(Insn, 16, 4) << 6; 3840261991Sdim if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder))) 3841226633Sdim return MCDisassembler::Fail; 3842261991Sdim 3843261991Sdim return S; 3844261991Sdim} 3845261991Sdim 3846261991Sdimstatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn, 3847261991Sdim uint64_t Address, const void* Decoder) { 3848261991Sdim DecodeStatus S = MCDisassembler::Success; 3849261991Sdim 3850261991Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3851261991Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3852261991Sdim unsigned U = fieldFromInstruction(Insn, 9, 1); 3853261991Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 3854261991Sdim imm |= (U << 8); 3855261991Sdim imm |= (Rn << 9); 3856280031Sdim unsigned add = fieldFromInstruction(Insn, 9, 1); 3857261991Sdim 3858288943Sdim const FeatureBitset &featureBits = 3859288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 3860280031Sdim 3861288943Sdim bool hasMP = featureBits[ARM::FeatureMP]; 3862288943Sdim bool hasV7Ops = featureBits[ARM::HasV7Ops]; 3863288943Sdim 3864261991Sdim if (Rn == 15) { 3865261991Sdim switch (Inst.getOpcode()) { 3866261991Sdim case ARM::t2LDRi8: 3867261991Sdim Inst.setOpcode(ARM::t2LDRpci); 3868261991Sdim break; 3869261991Sdim case ARM::t2LDRBi8: 3870261991Sdim Inst.setOpcode(ARM::t2LDRBpci); 3871261991Sdim break; 3872261991Sdim case ARM::t2LDRSBi8: 3873261991Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3874261991Sdim break; 3875261991Sdim case ARM::t2LDRHi8: 3876261991Sdim Inst.setOpcode(ARM::t2LDRHpci); 3877261991Sdim break; 3878261991Sdim case ARM::t2LDRSHi8: 3879261991Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3880261991Sdim break; 3881261991Sdim case ARM::t2PLDi8: 3882261991Sdim Inst.setOpcode(ARM::t2PLDpci); 3883261991Sdim break; 3884261991Sdim case ARM::t2PLIi8: 3885261991Sdim Inst.setOpcode(ARM::t2PLIpci); 3886261991Sdim break; 3887261991Sdim default: 3888261991Sdim return MCDisassembler::Fail; 3889206124Srdivacky } 3890261991Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3891226633Sdim } 3892206124Srdivacky 3893261991Sdim if (Rt == 15) { 3894261991Sdim switch (Inst.getOpcode()) { 3895261991Sdim case ARM::t2LDRSHi8: 3896261991Sdim return MCDisassembler::Fail; 3897280031Sdim case ARM::t2LDRHi8: 3898280031Sdim if (!add) 3899280031Sdim Inst.setOpcode(ARM::t2PLDWi8); 3900280031Sdim break; 3901280031Sdim case ARM::t2LDRSBi8: 3902280031Sdim Inst.setOpcode(ARM::t2PLIi8); 3903280031Sdim break; 3904261991Sdim default: 3905261991Sdim break; 3906261991Sdim } 3907261991Sdim } 3908261991Sdim 3909261991Sdim switch (Inst.getOpcode()) { 3910261991Sdim case ARM::t2PLDi8: 3911280031Sdim break; 3912261991Sdim case ARM::t2PLIi8: 3913280031Sdim if (!hasV7Ops) 3914280031Sdim return MCDisassembler::Fail; 3915280031Sdim break; 3916261991Sdim case ARM::t2PLDWi8: 3917280031Sdim if (!hasV7Ops || !hasMP) 3918280031Sdim return MCDisassembler::Fail; 3919280031Sdim break; 3920261991Sdim default: 3921261991Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 3922261991Sdim return MCDisassembler::Fail; 3923261991Sdim } 3924261991Sdim 3925261991Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder))) 3926261991Sdim return MCDisassembler::Fail; 3927261991Sdim return S; 3928261991Sdim} 3929261991Sdim 3930261991Sdimstatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn, 3931261991Sdim uint64_t Address, const void* Decoder) { 3932261991Sdim DecodeStatus S = MCDisassembler::Success; 3933261991Sdim 3934239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 3935261991Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 3936261991Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 3937261991Sdim imm |= (Rn << 13); 3938261991Sdim 3939288943Sdim const FeatureBitset &featureBits = 3940288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 3941280031Sdim 3942288943Sdim bool hasMP = featureBits[ARM::FeatureMP]; 3943288943Sdim bool hasV7Ops = featureBits[ARM::HasV7Ops]; 3944288943Sdim 3945261991Sdim if (Rn == 15) { 3946226633Sdim switch (Inst.getOpcode()) { 3947261991Sdim case ARM::t2LDRi12: 3948261991Sdim Inst.setOpcode(ARM::t2LDRpci); 3949261991Sdim break; 3950261991Sdim case ARM::t2LDRHi12: 3951261991Sdim Inst.setOpcode(ARM::t2LDRHpci); 3952261991Sdim break; 3953261991Sdim case ARM::t2LDRSHi12: 3954261991Sdim Inst.setOpcode(ARM::t2LDRSHpci); 3955261991Sdim break; 3956261991Sdim case ARM::t2LDRBi12: 3957261991Sdim Inst.setOpcode(ARM::t2LDRBpci); 3958261991Sdim break; 3959261991Sdim case ARM::t2LDRSBi12: 3960261991Sdim Inst.setOpcode(ARM::t2LDRSBpci); 3961261991Sdim break; 3962261991Sdim case ARM::t2PLDi12: 3963261991Sdim Inst.setOpcode(ARM::t2PLDpci); 3964261991Sdim break; 3965261991Sdim case ARM::t2PLIi12: 3966261991Sdim Inst.setOpcode(ARM::t2PLIpci); 3967261991Sdim break; 3968261991Sdim default: 3969261991Sdim return MCDisassembler::Fail; 3970261991Sdim } 3971261991Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 3972261991Sdim } 3973261991Sdim 3974261991Sdim if (Rt == 15) { 3975261991Sdim switch (Inst.getOpcode()) { 3976261991Sdim case ARM::t2LDRSHi12: 3977261991Sdim return MCDisassembler::Fail; 3978261991Sdim case ARM::t2LDRHi12: 3979280031Sdim Inst.setOpcode(ARM::t2PLDWi12); 3980261991Sdim break; 3981280031Sdim case ARM::t2LDRSBi12: 3982280031Sdim Inst.setOpcode(ARM::t2PLIi12); 3983280031Sdim break; 3984261991Sdim default: 3985261991Sdim break; 3986261991Sdim } 3987261991Sdim } 3988261991Sdim 3989261991Sdim switch (Inst.getOpcode()) { 3990261991Sdim case ARM::t2PLDi12: 3991280031Sdim break; 3992261991Sdim case ARM::t2PLIi12: 3993280031Sdim if (!hasV7Ops) 3994280031Sdim return MCDisassembler::Fail; 3995261991Sdim break; 3996280031Sdim case ARM::t2PLDWi12: 3997280031Sdim if (!hasV7Ops || !hasMP) 3998280031Sdim return MCDisassembler::Fail; 3999280031Sdim break; 4000261991Sdim default: 4001261991Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4002261991Sdim return MCDisassembler::Fail; 4003261991Sdim } 4004261991Sdim 4005261991Sdim if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder))) 4006261991Sdim return MCDisassembler::Fail; 4007261991Sdim return S; 4008261991Sdim} 4009261991Sdim 4010261991Sdimstatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, 4011261991Sdim uint64_t Address, const void* Decoder) { 4012261991Sdim DecodeStatus S = MCDisassembler::Success; 4013261991Sdim 4014261991Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4015261991Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4016261991Sdim unsigned imm = fieldFromInstruction(Insn, 0, 8); 4017261991Sdim imm |= (Rn << 9); 4018261991Sdim 4019261991Sdim if (Rn == 15) { 4020261991Sdim switch (Inst.getOpcode()) { 4021261991Sdim case ARM::t2LDRT: 4022261991Sdim Inst.setOpcode(ARM::t2LDRpci); 4023261991Sdim break; 4024261991Sdim case ARM::t2LDRBT: 4025261991Sdim Inst.setOpcode(ARM::t2LDRBpci); 4026261991Sdim break; 4027261991Sdim case ARM::t2LDRHT: 4028261991Sdim Inst.setOpcode(ARM::t2LDRHpci); 4029261991Sdim break; 4030261991Sdim case ARM::t2LDRSBT: 4031261991Sdim Inst.setOpcode(ARM::t2LDRSBpci); 4032261991Sdim break; 4033261991Sdim case ARM::t2LDRSHT: 4034261991Sdim Inst.setOpcode(ARM::t2LDRSHpci); 4035261991Sdim break; 4036261991Sdim default: 4037261991Sdim return MCDisassembler::Fail; 4038261991Sdim } 4039261991Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 4040261991Sdim } 4041261991Sdim 4042261991Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 4043261991Sdim return MCDisassembler::Fail; 4044261991Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder))) 4045261991Sdim return MCDisassembler::Fail; 4046261991Sdim return S; 4047261991Sdim} 4048261991Sdim 4049261991Sdimstatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn, 4050261991Sdim uint64_t Address, const void* Decoder) { 4051261991Sdim DecodeStatus S = MCDisassembler::Success; 4052261991Sdim 4053261991Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4054261991Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 4055261991Sdim int imm = fieldFromInstruction(Insn, 0, 12); 4056261991Sdim 4057288943Sdim const FeatureBitset &featureBits = 4058288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 4059280031Sdim 4060288943Sdim bool hasV7Ops = featureBits[ARM::HasV7Ops]; 4061288943Sdim 4062261991Sdim if (Rt == 15) { 4063261991Sdim switch (Inst.getOpcode()) { 4064261991Sdim case ARM::t2LDRBpci: 4065261991Sdim case ARM::t2LDRHpci: 4066261991Sdim Inst.setOpcode(ARM::t2PLDpci); 4067226633Sdim break; 4068261991Sdim case ARM::t2LDRSBpci: 4069261991Sdim Inst.setOpcode(ARM::t2PLIpci); 4070226633Sdim break; 4071261991Sdim case ARM::t2LDRSHpci: 4072261991Sdim return MCDisassembler::Fail; 4073261991Sdim default: 4074226633Sdim break; 4075206124Srdivacky } 4076261991Sdim } 4077206124Srdivacky 4078261991Sdim switch(Inst.getOpcode()) { 4079261991Sdim case ARM::t2PLDpci: 4080280031Sdim break; 4081261991Sdim case ARM::t2PLIpci: 4082280031Sdim if (!hasV7Ops) 4083280031Sdim return MCDisassembler::Fail; 4084261991Sdim break; 4085261991Sdim default: 4086261991Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4087261991Sdim return MCDisassembler::Fail; 4088261991Sdim } 4089221345Sdim 4090261991Sdim if (!U) { 4091261991Sdim // Special case for #-0. 4092261991Sdim if (imm == 0) 4093261991Sdim imm = INT32_MIN; 4094261991Sdim else 4095261991Sdim imm = -imm; 4096226633Sdim } 4097288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4098226633Sdim 4099226633Sdim return S; 4100226633Sdim} 4101226633Sdim 4102234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, 4103226633Sdim uint64_t Address, const void *Decoder) { 4104239462Sdim if (Val == 0) 4105288943Sdim Inst.addOperand(MCOperand::createImm(INT32_MIN)); 4106239462Sdim else { 4107239462Sdim int imm = Val & 0xFF; 4108226633Sdim 4109239462Sdim if (!(Val & 0x100)) imm *= -1; 4110288943Sdim Inst.addOperand(MCOperand::createImm(imm * 4)); 4111239462Sdim } 4112239462Sdim 4113226633Sdim return MCDisassembler::Success; 4114226633Sdim} 4115226633Sdim 4116353358Sdimstatic DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address, 4117353358Sdim const void *Decoder) { 4118353358Sdim if (Val == 0) 4119353358Sdim Inst.addOperand(MCOperand::createImm(INT32_MIN)); 4120353358Sdim else { 4121353358Sdim int imm = Val & 0x7F; 4122353358Sdim 4123353358Sdim if (!(Val & 0x80)) 4124353358Sdim imm *= -1; 4125353358Sdim Inst.addOperand(MCOperand::createImm(imm * 4)); 4126353358Sdim } 4127353358Sdim 4128353358Sdim return MCDisassembler::Success; 4129353358Sdim} 4130353358Sdim 4131234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, 4132226633Sdim uint64_t Address, const void *Decoder) { 4133226633Sdim DecodeStatus S = MCDisassembler::Success; 4134226633Sdim 4135239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 4136239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 9); 4137226633Sdim 4138226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4139226633Sdim return MCDisassembler::Fail; 4140226633Sdim if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder))) 4141226633Sdim return MCDisassembler::Fail; 4142226633Sdim 4143226633Sdim return S; 4144226633Sdim} 4145226633Sdim 4146353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val, 4147353358Sdim uint64_t Address, 4148353358Sdim const void *Decoder) { 4149353358Sdim DecodeStatus S = MCDisassembler::Success; 4150353358Sdim 4151353358Sdim unsigned Rn = fieldFromInstruction(Val, 8, 4); 4152353358Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 4153353358Sdim 4154353358Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4155353358Sdim return MCDisassembler::Fail; 4156353358Sdim if (!Check(S, DecodeT2Imm7S4(Inst, imm, Address, Decoder))) 4157353358Sdim return MCDisassembler::Fail; 4158353358Sdim 4159353358Sdim return S; 4160353358Sdim} 4161353358Sdim 4162234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, 4163226633Sdim uint64_t Address, const void *Decoder) { 4164226633Sdim DecodeStatus S = MCDisassembler::Success; 4165226633Sdim 4166239462Sdim unsigned Rn = fieldFromInstruction(Val, 8, 4); 4167239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 4168226633Sdim 4169226633Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4170226633Sdim return MCDisassembler::Fail; 4171226633Sdim 4172288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4173226633Sdim 4174226633Sdim return S; 4175226633Sdim} 4176226633Sdim 4177234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, 4178226633Sdim uint64_t Address, const void *Decoder) { 4179226633Sdim int imm = Val & 0xFF; 4180226633Sdim if (Val == 0) 4181226633Sdim imm = INT32_MIN; 4182226633Sdim else if (!(Val & 0x100)) 4183226633Sdim imm *= -1; 4184288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4185226633Sdim 4186226633Sdim return MCDisassembler::Success; 4187226633Sdim} 4188226633Sdim 4189353358Sdimtemplate<int shift> 4190353358Sdimstatic DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, 4191353358Sdim uint64_t Address, const void *Decoder) { 4192353358Sdim int imm = Val & 0x7F; 4193353358Sdim if (Val == 0) 4194353358Sdim imm = INT32_MIN; 4195353358Sdim else if (!(Val & 0x80)) 4196353358Sdim imm *= -1; 4197353358Sdim if (imm != INT32_MIN) 4198353358Sdim imm *= (1U << shift); 4199353358Sdim Inst.addOperand(MCOperand::createImm(imm)); 4200353358Sdim 4201353358Sdim return MCDisassembler::Success; 4202353358Sdim} 4203353358Sdim 4204234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, 4205226633Sdim uint64_t Address, const void *Decoder) { 4206226633Sdim DecodeStatus S = MCDisassembler::Success; 4207226633Sdim 4208239462Sdim unsigned Rn = fieldFromInstruction(Val, 9, 4); 4209239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 9); 4210226633Sdim 4211261991Sdim // Thumb stores cannot use PC as dest register. 4212261991Sdim switch (Inst.getOpcode()) { 4213261991Sdim case ARM::t2STRT: 4214261991Sdim case ARM::t2STRBT: 4215261991Sdim case ARM::t2STRHT: 4216261991Sdim case ARM::t2STRi8: 4217261991Sdim case ARM::t2STRHi8: 4218261991Sdim case ARM::t2STRBi8: 4219261991Sdim if (Rn == 15) 4220261991Sdim return MCDisassembler::Fail; 4221261991Sdim break; 4222261991Sdim default: 4223261991Sdim break; 4224261991Sdim } 4225261991Sdim 4226226633Sdim // Some instructions always use an additive offset. 4227226633Sdim switch (Inst.getOpcode()) { 4228226633Sdim case ARM::t2LDRT: 4229226633Sdim case ARM::t2LDRBT: 4230226633Sdim case ARM::t2LDRHT: 4231226633Sdim case ARM::t2LDRSBT: 4232226633Sdim case ARM::t2LDRSHT: 4233226633Sdim case ARM::t2STRT: 4234226633Sdim case ARM::t2STRBT: 4235226633Sdim case ARM::t2STRHT: 4236226633Sdim imm |= 0x100; 4237226633Sdim break; 4238226633Sdim default: 4239226633Sdim break; 4240226633Sdim } 4241226633Sdim 4242226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4243226633Sdim return MCDisassembler::Fail; 4244226633Sdim if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder))) 4245226633Sdim return MCDisassembler::Fail; 4246226633Sdim 4247226633Sdim return S; 4248226633Sdim} 4249226633Sdim 4250353358Sdimtemplate<int shift> 4251353358Sdimstatic DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val, 4252353358Sdim uint64_t Address, 4253353358Sdim const void *Decoder) { 4254353358Sdim DecodeStatus S = MCDisassembler::Success; 4255353358Sdim 4256353358Sdim unsigned Rn = fieldFromInstruction(Val, 8, 3); 4257353358Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 4258353358Sdim 4259353358Sdim if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) 4260353358Sdim return MCDisassembler::Fail; 4261353358Sdim if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder))) 4262353358Sdim return MCDisassembler::Fail; 4263353358Sdim 4264353358Sdim return S; 4265353358Sdim} 4266353358Sdim 4267353358Sdimtemplate<int shift, int WriteBack> 4268353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val, 4269353358Sdim uint64_t Address, 4270353358Sdim const void *Decoder) { 4271353358Sdim DecodeStatus S = MCDisassembler::Success; 4272353358Sdim 4273353358Sdim unsigned Rn = fieldFromInstruction(Val, 8, 4); 4274353358Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 4275353358Sdim if (WriteBack) { 4276353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 4277353358Sdim return MCDisassembler::Fail; 4278353358Sdim } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4279353358Sdim return MCDisassembler::Fail; 4280353358Sdim if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder))) 4281353358Sdim return MCDisassembler::Fail; 4282353358Sdim 4283353358Sdim return S; 4284353358Sdim} 4285353358Sdim 4286234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn, 4287226633Sdim uint64_t Address, const void *Decoder) { 4288226633Sdim DecodeStatus S = MCDisassembler::Success; 4289226633Sdim 4290239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4291239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4292239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 4293239462Sdim addr |= fieldFromInstruction(Insn, 9, 1) << 8; 4294226633Sdim addr |= Rn << 9; 4295239462Sdim unsigned load = fieldFromInstruction(Insn, 20, 1); 4296226633Sdim 4297261991Sdim if (Rn == 15) { 4298261991Sdim switch (Inst.getOpcode()) { 4299261991Sdim case ARM::t2LDR_PRE: 4300261991Sdim case ARM::t2LDR_POST: 4301261991Sdim Inst.setOpcode(ARM::t2LDRpci); 4302261991Sdim break; 4303261991Sdim case ARM::t2LDRB_PRE: 4304261991Sdim case ARM::t2LDRB_POST: 4305261991Sdim Inst.setOpcode(ARM::t2LDRBpci); 4306261991Sdim break; 4307261991Sdim case ARM::t2LDRH_PRE: 4308261991Sdim case ARM::t2LDRH_POST: 4309261991Sdim Inst.setOpcode(ARM::t2LDRHpci); 4310261991Sdim break; 4311261991Sdim case ARM::t2LDRSB_PRE: 4312261991Sdim case ARM::t2LDRSB_POST: 4313261991Sdim if (Rt == 15) 4314261991Sdim Inst.setOpcode(ARM::t2PLIpci); 4315261991Sdim else 4316261991Sdim Inst.setOpcode(ARM::t2LDRSBpci); 4317261991Sdim break; 4318261991Sdim case ARM::t2LDRSH_PRE: 4319261991Sdim case ARM::t2LDRSH_POST: 4320261991Sdim Inst.setOpcode(ARM::t2LDRSHpci); 4321261991Sdim break; 4322261991Sdim default: 4323261991Sdim return MCDisassembler::Fail; 4324261991Sdim } 4325261991Sdim return DecodeT2LoadLabel(Inst, Insn, Address, Decoder); 4326261991Sdim } 4327261991Sdim 4328226633Sdim if (!load) { 4329226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4330226633Sdim return MCDisassembler::Fail; 4331226633Sdim } 4332226633Sdim 4333249423Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4334226633Sdim return MCDisassembler::Fail; 4335226633Sdim 4336226633Sdim if (load) { 4337226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4338226633Sdim return MCDisassembler::Fail; 4339226633Sdim } 4340226633Sdim 4341226633Sdim if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder))) 4342226633Sdim return MCDisassembler::Fail; 4343226633Sdim 4344226633Sdim return S; 4345226633Sdim} 4346226633Sdim 4347234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, 4348226633Sdim uint64_t Address, const void *Decoder) { 4349226633Sdim DecodeStatus S = MCDisassembler::Success; 4350226633Sdim 4351239462Sdim unsigned Rn = fieldFromInstruction(Val, 13, 4); 4352239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 12); 4353226633Sdim 4354261991Sdim // Thumb stores cannot use PC as dest register. 4355261991Sdim switch (Inst.getOpcode()) { 4356261991Sdim case ARM::t2STRi12: 4357261991Sdim case ARM::t2STRBi12: 4358261991Sdim case ARM::t2STRHi12: 4359261991Sdim if (Rn == 15) 4360261991Sdim return MCDisassembler::Fail; 4361327952Sdim break; 4362261991Sdim default: 4363261991Sdim break; 4364261991Sdim } 4365261991Sdim 4366226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4367226633Sdim return MCDisassembler::Fail; 4368288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4369226633Sdim 4370226633Sdim return S; 4371226633Sdim} 4372226633Sdim 4373234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn, 4374226633Sdim uint64_t Address, const void *Decoder) { 4375239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 7); 4376226633Sdim 4377288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 4378288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 4379288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4380226633Sdim 4381226633Sdim return MCDisassembler::Success; 4382226633Sdim} 4383226633Sdim 4384234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, 4385226633Sdim uint64_t Address, const void *Decoder) { 4386226633Sdim DecodeStatus S = MCDisassembler::Success; 4387226633Sdim 4388226633Sdim if (Inst.getOpcode() == ARM::tADDrSP) { 4389239462Sdim unsigned Rdm = fieldFromInstruction(Insn, 0, 3); 4390239462Sdim Rdm |= fieldFromInstruction(Insn, 7, 1) << 3; 4391226633Sdim 4392226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 4393226633Sdim return MCDisassembler::Fail; 4394288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 4395226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) 4396226633Sdim return MCDisassembler::Fail; 4397226633Sdim } else if (Inst.getOpcode() == ARM::tADDspr) { 4398239462Sdim unsigned Rm = fieldFromInstruction(Insn, 3, 4); 4399226633Sdim 4400288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 4401288943Sdim Inst.addOperand(MCOperand::createReg(ARM::SP)); 4402226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4403226633Sdim return MCDisassembler::Fail; 4404226633Sdim } 4405226633Sdim 4406226633Sdim return S; 4407226633Sdim} 4408226633Sdim 4409234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, 4410226633Sdim uint64_t Address, const void *Decoder) { 4411239462Sdim unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2; 4412239462Sdim unsigned flags = fieldFromInstruction(Insn, 0, 3); 4413226633Sdim 4414288943Sdim Inst.addOperand(MCOperand::createImm(imod)); 4415288943Sdim Inst.addOperand(MCOperand::createImm(flags)); 4416226633Sdim 4417226633Sdim return MCDisassembler::Success; 4418226633Sdim} 4419226633Sdim 4420234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, 4421226633Sdim uint64_t Address, const void *Decoder) { 4422226633Sdim DecodeStatus S = MCDisassembler::Success; 4423239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4424239462Sdim unsigned add = fieldFromInstruction(Insn, 4, 1); 4425226633Sdim 4426234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) 4427226633Sdim return MCDisassembler::Fail; 4428288943Sdim Inst.addOperand(MCOperand::createImm(add)); 4429226633Sdim 4430226633Sdim return S; 4431226633Sdim} 4432226633Sdim 4433353358Sdimstatic DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn, 4434353358Sdim uint64_t Address, const void *Decoder) { 4435353358Sdim DecodeStatus S = MCDisassembler::Success; 4436353358Sdim unsigned Rn = fieldFromInstruction(Insn, 3, 4); 4437353358Sdim unsigned Qm = fieldFromInstruction(Insn, 0, 3); 4438353358Sdim 4439353358Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 4440353358Sdim return MCDisassembler::Fail; 4441353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) 4442353358Sdim return MCDisassembler::Fail; 4443353358Sdim 4444353358Sdim return S; 4445353358Sdim} 4446353358Sdim 4447353358Sdimtemplate<int shift> 4448353358Sdimstatic DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn, 4449353358Sdim uint64_t Address, const void *Decoder) { 4450353358Sdim DecodeStatus S = MCDisassembler::Success; 4451353358Sdim unsigned Qm = fieldFromInstruction(Insn, 8, 3); 4452353358Sdim int imm = fieldFromInstruction(Insn, 0, 7); 4453353358Sdim 4454353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) 4455353358Sdim return MCDisassembler::Fail; 4456353358Sdim 4457353358Sdim if(!fieldFromInstruction(Insn, 7, 1)) { 4458353358Sdim if (imm == 0) 4459353358Sdim imm = INT32_MIN; // indicate -0 4460353358Sdim else 4461353358Sdim imm *= -1; 4462353358Sdim } 4463353358Sdim if (imm != INT32_MIN) 4464353358Sdim imm *= (1U << shift); 4465353358Sdim Inst.addOperand(MCOperand::createImm(imm)); 4466353358Sdim 4467353358Sdim return S; 4468353358Sdim} 4469353358Sdim 4470234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val, 4471226633Sdim uint64_t Address, const void *Decoder) { 4472239462Sdim // Val is passed in as S:J1:J2:imm10H:imm10L:'0' 4473239462Sdim // Note only one trailing zero not two. Also the J1 and J2 values are from 4474239462Sdim // the encoded instruction. So here change to I1 and I2 values via: 4475239462Sdim // I1 = NOT(J1 EOR S); 4476239462Sdim // I2 = NOT(J2 EOR S); 4477239462Sdim // and build the imm32 with two trailing zeros as documented: 4478239462Sdim // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32); 4479239462Sdim unsigned S = (Val >> 23) & 1; 4480239462Sdim unsigned J1 = (Val >> 22) & 1; 4481239462Sdim unsigned J2 = (Val >> 21) & 1; 4482239462Sdim unsigned I1 = !(J1 ^ S); 4483239462Sdim unsigned I2 = !(J2 ^ S); 4484239462Sdim unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); 4485239462Sdim int imm32 = SignExtend32<25>(tmp << 1); 4486239462Sdim 4487234353Sdim if (!tryAddingSymbolicOperand(Address, 4488239462Sdim (Address & ~2u) + imm32 + 4, 4489226633Sdim true, 4, Inst, Decoder)) 4490288943Sdim Inst.addOperand(MCOperand::createImm(imm32)); 4491226633Sdim return MCDisassembler::Success; 4492226633Sdim} 4493226633Sdim 4494234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val, 4495226633Sdim uint64_t Address, const void *Decoder) { 4496226633Sdim if (Val == 0xA || Val == 0xB) 4497226633Sdim return MCDisassembler::Fail; 4498226633Sdim 4499288943Sdim const FeatureBitset &featureBits = 4500288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 4501288943Sdim 4502353358Sdim if (!isValidCoprocessorNumber(Val, featureBits)) 4503261991Sdim return MCDisassembler::Fail; 4504261991Sdim 4505288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 4506226633Sdim return MCDisassembler::Success; 4507226633Sdim} 4508226633Sdim 4509226633Sdimstatic DecodeStatus 4510234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn, 4511226633Sdim uint64_t Address, const void *Decoder) { 4512226633Sdim DecodeStatus S = MCDisassembler::Success; 4513226633Sdim 4514239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4515239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4516226633Sdim 4517226633Sdim if (Rn == ARM::SP) S = MCDisassembler::SoftFail; 4518226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4519226633Sdim return MCDisassembler::Fail; 4520226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 4521226633Sdim return MCDisassembler::Fail; 4522226633Sdim return S; 4523226633Sdim} 4524226633Sdim 4525226633Sdimstatic DecodeStatus 4526234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn, 4527226633Sdim uint64_t Address, const void *Decoder) { 4528226633Sdim DecodeStatus S = MCDisassembler::Success; 4529226633Sdim 4530239462Sdim unsigned pred = fieldFromInstruction(Insn, 22, 4); 4531226633Sdim if (pred == 0xE || pred == 0xF) { 4532239462Sdim unsigned opc = fieldFromInstruction(Insn, 4, 28); 4533226633Sdim switch (opc) { 4534226633Sdim default: 4535226633Sdim return MCDisassembler::Fail; 4536226633Sdim case 0xf3bf8f4: 4537226633Sdim Inst.setOpcode(ARM::t2DSB); 4538226633Sdim break; 4539226633Sdim case 0xf3bf8f5: 4540226633Sdim Inst.setOpcode(ARM::t2DMB); 4541226633Sdim break; 4542226633Sdim case 0xf3bf8f6: 4543226633Sdim Inst.setOpcode(ARM::t2ISB); 4544226633Sdim break; 4545221345Sdim } 4546206124Srdivacky 4547239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 4); 4548226633Sdim return DecodeMemBarrierOption(Inst, imm, Address, Decoder); 4549226633Sdim } 4550226633Sdim 4551239462Sdim unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1; 4552239462Sdim brtarget |= fieldFromInstruction(Insn, 11, 1) << 19; 4553239462Sdim brtarget |= fieldFromInstruction(Insn, 13, 1) << 18; 4554239462Sdim brtarget |= fieldFromInstruction(Insn, 16, 6) << 12; 4555239462Sdim brtarget |= fieldFromInstruction(Insn, 26, 1) << 20; 4556226633Sdim 4557226633Sdim if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder))) 4558226633Sdim return MCDisassembler::Fail; 4559226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4560226633Sdim return MCDisassembler::Fail; 4561226633Sdim 4562226633Sdim return S; 4563226633Sdim} 4564226633Sdim 4565226633Sdim// Decode a shifted immediate operand. These basically consist 4566226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either 4567226633Sdim// a splat operation or a rotation. 4568234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, 4569226633Sdim uint64_t Address, const void *Decoder) { 4570239462Sdim unsigned ctrl = fieldFromInstruction(Val, 10, 2); 4571226633Sdim if (ctrl == 0) { 4572239462Sdim unsigned byte = fieldFromInstruction(Val, 8, 2); 4573239462Sdim unsigned imm = fieldFromInstruction(Val, 0, 8); 4574226633Sdim switch (byte) { 4575226633Sdim case 0: 4576288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4577226633Sdim break; 4578226633Sdim case 1: 4579288943Sdim Inst.addOperand(MCOperand::createImm((imm << 16) | imm)); 4580226633Sdim break; 4581226633Sdim case 2: 4582288943Sdim Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8))); 4583226633Sdim break; 4584226633Sdim case 3: 4585288943Sdim Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) | 4586226633Sdim (imm << 8) | imm)); 4587226633Sdim break; 4588221345Sdim } 4589226633Sdim } else { 4590239462Sdim unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80; 4591239462Sdim unsigned rot = fieldFromInstruction(Val, 7, 5); 4592226633Sdim unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31)); 4593288943Sdim Inst.addOperand(MCOperand::createImm(imm)); 4594226633Sdim } 4595221345Sdim 4596226633Sdim return MCDisassembler::Success; 4597226633Sdim} 4598206124Srdivacky 4599226633Sdimstatic DecodeStatus 4600234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val, 4601321369Sdim uint64_t Address, const void *Decoder) { 4602239462Sdim if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4, 4603234353Sdim true, 2, Inst, Decoder)) 4604288943Sdim Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1))); 4605226633Sdim return MCDisassembler::Success; 4606226633Sdim} 4607226633Sdim 4608234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, 4609321369Sdim uint64_t Address, 4610321369Sdim const void *Decoder) { 4611239462Sdim // Val is passed in as S:J1:J2:imm10:imm11 4612239462Sdim // Note no trailing zero after imm11. Also the J1 and J2 values are from 4613239462Sdim // the encoded instruction. So here change to I1 and I2 values via: 4614239462Sdim // I1 = NOT(J1 EOR S); 4615239462Sdim // I2 = NOT(J2 EOR S); 4616239462Sdim // and build the imm32 with one trailing zero as documented: 4617239462Sdim // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); 4618239462Sdim unsigned S = (Val >> 23) & 1; 4619239462Sdim unsigned J1 = (Val >> 22) & 1; 4620239462Sdim unsigned J2 = (Val >> 21) & 1; 4621239462Sdim unsigned I1 = !(J1 ^ S); 4622239462Sdim unsigned I2 = !(J2 ^ S); 4623239462Sdim unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); 4624239462Sdim int imm32 = SignExtend32<25>(tmp << 1); 4625239462Sdim 4626239462Sdim if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, 4627234353Sdim true, 4, Inst, Decoder)) 4628288943Sdim Inst.addOperand(MCOperand::createImm(imm32)); 4629226633Sdim return MCDisassembler::Success; 4630226633Sdim} 4631226633Sdim 4632234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val, 4633226633Sdim uint64_t Address, const void *Decoder) { 4634239462Sdim if (Val & ~0xf) 4635226633Sdim return MCDisassembler::Fail; 4636206124Srdivacky 4637288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 4638226633Sdim return MCDisassembler::Success; 4639206124Srdivacky} 4640206124Srdivacky 4641261991Sdimstatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val, 4642261991Sdim uint64_t Address, const void *Decoder) { 4643261991Sdim if (Val & ~0xf) 4644261991Sdim return MCDisassembler::Fail; 4645261991Sdim 4646288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 4647261991Sdim return MCDisassembler::Success; 4648261991Sdim} 4649261991Sdim 4650234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, 4651226633Sdim uint64_t Address, const void *Decoder) { 4652280031Sdim DecodeStatus S = MCDisassembler::Success; 4653288943Sdim const FeatureBitset &FeatureBits = 4654288943Sdim ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); 4655288943Sdim 4656288943Sdim if (FeatureBits[ARM::FeatureMClass]) { 4657280031Sdim unsigned ValLow = Val & 0xff; 4658280031Sdim 4659280031Sdim // Validate the SYSm value first. 4660280031Sdim switch (ValLow) { 4661280031Sdim case 0: // apsr 4662280031Sdim case 1: // iapsr 4663280031Sdim case 2: // eapsr 4664280031Sdim case 3: // xpsr 4665280031Sdim case 5: // ipsr 4666280031Sdim case 6: // epsr 4667280031Sdim case 7: // iepsr 4668280031Sdim case 8: // msp 4669280031Sdim case 9: // psp 4670280031Sdim case 16: // primask 4671280031Sdim case 20: // control 4672280031Sdim break; 4673280031Sdim case 17: // basepri 4674280031Sdim case 18: // basepri_max 4675280031Sdim case 19: // faultmask 4676288943Sdim if (!(FeatureBits[ARM::HasV7Ops])) 4677280031Sdim // Values basepri, basepri_max and faultmask are only valid for v7m. 4678280031Sdim return MCDisassembler::Fail; 4679280031Sdim break; 4680309124Sdim case 0x8a: // msplim_ns 4681309124Sdim case 0x8b: // psplim_ns 4682309124Sdim case 0x91: // basepri_ns 4683309124Sdim case 0x93: // faultmask_ns 4684309124Sdim if (!(FeatureBits[ARM::HasV8MMainlineOps])) 4685309124Sdim return MCDisassembler::Fail; 4686314564Sdim LLVM_FALLTHROUGH; 4687309124Sdim case 10: // msplim 4688309124Sdim case 11: // psplim 4689309124Sdim case 0x88: // msp_ns 4690309124Sdim case 0x89: // psp_ns 4691309124Sdim case 0x90: // primask_ns 4692309124Sdim case 0x94: // control_ns 4693309124Sdim case 0x98: // sp_ns 4694309124Sdim if (!(FeatureBits[ARM::Feature8MSecExt])) 4695309124Sdim return MCDisassembler::Fail; 4696309124Sdim break; 4697280031Sdim default: 4698341825Sdim // Architecturally defined as unpredictable 4699341825Sdim S = MCDisassembler::SoftFail; 4700341825Sdim break; 4701280031Sdim } 4702280031Sdim 4703280031Sdim if (Inst.getOpcode() == ARM::t2MSR_M) { 4704280031Sdim unsigned Mask = fieldFromInstruction(Val, 10, 2); 4705288943Sdim if (!(FeatureBits[ARM::HasV7Ops])) { 4706280031Sdim // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are 4707280031Sdim // unpredictable. 4708280031Sdim if (Mask != 2) 4709280031Sdim S = MCDisassembler::SoftFail; 4710280031Sdim } 4711280031Sdim else { 4712280031Sdim // The ARMv7-M architecture stores an additional 2-bit mask value in 4713280031Sdim // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and 4714280031Sdim // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if 4715280031Sdim // the NZCVQ bits should be moved by the instruction. Bit mask{0} 4716280031Sdim // indicates the move for the GE{3:0} bits, the mask{0} bit can be set 4717280031Sdim // only if the processor includes the DSP extension. 4718280031Sdim if (Mask == 0 || (Mask != 2 && ValLow > 3) || 4719296417Sdim (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1))) 4720280031Sdim S = MCDisassembler::SoftFail; 4721280031Sdim } 4722280031Sdim } 4723280031Sdim } else { 4724280031Sdim // A/R class 4725280031Sdim if (Val == 0) 4726280031Sdim return MCDisassembler::Fail; 4727280031Sdim } 4728288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 4729280031Sdim return S; 4730280031Sdim} 4731280031Sdim 4732280031Sdimstatic DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val, 4733280031Sdim uint64_t Address, const void *Decoder) { 4734280031Sdim unsigned R = fieldFromInstruction(Val, 5, 1); 4735280031Sdim unsigned SysM = fieldFromInstruction(Val, 0, 5); 4736280031Sdim 4737280031Sdim // The table of encodings for these banked registers comes from B9.2.3 of the 4738280031Sdim // ARM ARM. There are patterns, but nothing regular enough to make this logic 4739280031Sdim // neater. So by fiat, these values are UNPREDICTABLE: 4740341825Sdim if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM)) 4741341825Sdim return MCDisassembler::Fail; 4742280031Sdim 4743288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 4744226633Sdim return MCDisassembler::Success; 4745226633Sdim} 4746206124Srdivacky 4747234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, 4748226633Sdim uint64_t Address, const void *Decoder) { 4749226633Sdim DecodeStatus S = MCDisassembler::Success; 4750206124Srdivacky 4751239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4752239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4753239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4754206124Srdivacky 4755261991Sdim if (Rn == 0xF) 4756261991Sdim S = MCDisassembler::SoftFail; 4757206274Srdivacky 4758261991Sdim if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder))) 4759226633Sdim return MCDisassembler::Fail; 4760226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4761226633Sdim return MCDisassembler::Fail; 4762226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4763226633Sdim return MCDisassembler::Fail; 4764206124Srdivacky 4765226633Sdim return S; 4766226633Sdim} 4767206124Srdivacky 4768234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, 4769321369Sdim uint64_t Address, 4770321369Sdim const void *Decoder) { 4771226633Sdim DecodeStatus S = MCDisassembler::Success; 4772221345Sdim 4773239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4774239462Sdim unsigned Rt = fieldFromInstruction(Insn, 0, 4); 4775239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4776239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4777206124Srdivacky 4778251662Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) 4779226633Sdim return MCDisassembler::Fail; 4780226633Sdim 4781261991Sdim if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1) 4782261991Sdim S = MCDisassembler::SoftFail; 4783226633Sdim 4784261991Sdim if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder))) 4785226633Sdim return MCDisassembler::Fail; 4786226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4787226633Sdim return MCDisassembler::Fail; 4788226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4789226633Sdim return MCDisassembler::Fail; 4790226633Sdim 4791226633Sdim return S; 4792206124Srdivacky} 4793206124Srdivacky 4794234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, 4795226633Sdim uint64_t Address, const void *Decoder) { 4796226633Sdim DecodeStatus S = MCDisassembler::Success; 4797206274Srdivacky 4798239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4799239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4800239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4801239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4802239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4803239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4804206124Srdivacky 4805226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4806206124Srdivacky 4807226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4808226633Sdim return MCDisassembler::Fail; 4809226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4810226633Sdim return MCDisassembler::Fail; 4811226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 4812226633Sdim return MCDisassembler::Fail; 4813226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4814226633Sdim return MCDisassembler::Fail; 4815206124Srdivacky 4816226633Sdim return S; 4817226633Sdim} 4818206124Srdivacky 4819234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, 4820226633Sdim uint64_t Address, const void *Decoder) { 4821226633Sdim DecodeStatus S = MCDisassembler::Success; 4822226633Sdim 4823239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4824239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4825239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4826239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4827239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4828239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4829239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4830226633Sdim 4831226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4832226633Sdim if (Rm == 0xF) S = MCDisassembler::SoftFail; 4833226633Sdim 4834226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4835226633Sdim return MCDisassembler::Fail; 4836226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4837226633Sdim return MCDisassembler::Fail; 4838226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 4839226633Sdim return MCDisassembler::Fail; 4840226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4841226633Sdim return MCDisassembler::Fail; 4842226633Sdim 4843226633Sdim return S; 4844226633Sdim} 4845226633Sdim 4846234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, 4847226633Sdim uint64_t Address, const void *Decoder) { 4848226633Sdim DecodeStatus S = MCDisassembler::Success; 4849226633Sdim 4850239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4851239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4852239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4853239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4854239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4855239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4856226633Sdim 4857226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4858226633Sdim 4859226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4860226633Sdim return MCDisassembler::Fail; 4861226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4862226633Sdim return MCDisassembler::Fail; 4863226633Sdim if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) 4864226633Sdim return MCDisassembler::Fail; 4865226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4866226633Sdim return MCDisassembler::Fail; 4867226633Sdim 4868226633Sdim return S; 4869226633Sdim} 4870226633Sdim 4871234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, 4872226633Sdim uint64_t Address, const void *Decoder) { 4873226633Sdim DecodeStatus S = MCDisassembler::Success; 4874226633Sdim 4875239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4876239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 4877239462Sdim unsigned imm = fieldFromInstruction(Insn, 0, 12); 4878239462Sdim imm |= fieldFromInstruction(Insn, 16, 4) << 13; 4879239462Sdim imm |= fieldFromInstruction(Insn, 23, 1) << 12; 4880239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 4881226633Sdim 4882226633Sdim if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; 4883226633Sdim 4884226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4885226633Sdim return MCDisassembler::Fail; 4886226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 4887226633Sdim return MCDisassembler::Fail; 4888226633Sdim if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) 4889226633Sdim return MCDisassembler::Fail; 4890226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 4891226633Sdim return MCDisassembler::Fail; 4892226633Sdim 4893226633Sdim return S; 4894226633Sdim} 4895226633Sdim 4896234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, 4897226633Sdim uint64_t Address, const void *Decoder) { 4898226633Sdim DecodeStatus S = MCDisassembler::Success; 4899226633Sdim 4900239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4901239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4902239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4903239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4904239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4905226633Sdim 4906226633Sdim unsigned align = 0; 4907226633Sdim unsigned index = 0; 4908226633Sdim switch (size) { 4909226633Sdim default: 4910226633Sdim return MCDisassembler::Fail; 4911226633Sdim case 0: 4912239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4913226633Sdim return MCDisassembler::Fail; // UNDEFINED 4914239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4915226633Sdim break; 4916226633Sdim case 1: 4917239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4918226633Sdim return MCDisassembler::Fail; // UNDEFINED 4919239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4920239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4921226633Sdim align = 2; 4922226633Sdim break; 4923226633Sdim case 2: 4924239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4925226633Sdim return MCDisassembler::Fail; // UNDEFINED 4926239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4927243830Sdim 4928243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4929243830Sdim case 0 : 4930243830Sdim align = 0; break; 4931243830Sdim case 3: 4932243830Sdim align = 4; break; 4933243830Sdim default: 4934243830Sdim return MCDisassembler::Fail; 4935243830Sdim } 4936243830Sdim break; 4937206124Srdivacky } 4938206124Srdivacky 4939226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4940226633Sdim return MCDisassembler::Fail; 4941226633Sdim if (Rm != 0xF) { // Writeback 4942226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4943226633Sdim return MCDisassembler::Fail; 4944226633Sdim } 4945226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 4946226633Sdim return MCDisassembler::Fail; 4947288943Sdim Inst.addOperand(MCOperand::createImm(align)); 4948226633Sdim if (Rm != 0xF) { 4949226633Sdim if (Rm != 0xD) { 4950226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 4951226633Sdim return MCDisassembler::Fail; 4952226633Sdim } else 4953288943Sdim Inst.addOperand(MCOperand::createReg(0)); 4954226633Sdim } 4955206124Srdivacky 4956226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 4957226633Sdim return MCDisassembler::Fail; 4958288943Sdim Inst.addOperand(MCOperand::createImm(index)); 4959206124Srdivacky 4960226633Sdim return S; 4961226633Sdim} 4962206124Srdivacky 4963234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, 4964226633Sdim uint64_t Address, const void *Decoder) { 4965226633Sdim DecodeStatus S = MCDisassembler::Success; 4966206124Srdivacky 4967239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 4968239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 4969239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 4970239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 4971239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 4972207618Srdivacky 4973226633Sdim unsigned align = 0; 4974226633Sdim unsigned index = 0; 4975226633Sdim switch (size) { 4976226633Sdim default: 4977226633Sdim return MCDisassembler::Fail; 4978226633Sdim case 0: 4979239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4980226633Sdim return MCDisassembler::Fail; // UNDEFINED 4981239462Sdim index = fieldFromInstruction(Insn, 5, 3); 4982226633Sdim break; 4983226633Sdim case 1: 4984239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 4985226633Sdim return MCDisassembler::Fail; // UNDEFINED 4986239462Sdim index = fieldFromInstruction(Insn, 6, 2); 4987239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 4988226633Sdim align = 2; 4989226633Sdim break; 4990226633Sdim case 2: 4991239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 4992226633Sdim return MCDisassembler::Fail; // UNDEFINED 4993239462Sdim index = fieldFromInstruction(Insn, 7, 1); 4994243830Sdim 4995243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 4996341825Sdim case 0: 4997243830Sdim align = 0; break; 4998243830Sdim case 3: 4999243830Sdim align = 4; break; 5000243830Sdim default: 5001243830Sdim return MCDisassembler::Fail; 5002243830Sdim } 5003243830Sdim break; 5004226633Sdim } 5005221345Sdim 5006226633Sdim if (Rm != 0xF) { // Writeback 5007226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5008226633Sdim return MCDisassembler::Fail; 5009226633Sdim } 5010226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5011226633Sdim return MCDisassembler::Fail; 5012288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5013226633Sdim if (Rm != 0xF) { 5014226633Sdim if (Rm != 0xD) { 5015226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5016226633Sdim return MCDisassembler::Fail; 5017226633Sdim } else 5018288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5019226633Sdim } 5020206124Srdivacky 5021226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5022226633Sdim return MCDisassembler::Fail; 5023288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5024226633Sdim 5025226633Sdim return S; 5026206124Srdivacky} 5027206124Srdivacky 5028234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, 5029226633Sdim uint64_t Address, const void *Decoder) { 5030226633Sdim DecodeStatus S = MCDisassembler::Success; 5031226633Sdim 5032239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5033239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 5034239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 5035239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 5036239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 5037226633Sdim 5038226633Sdim unsigned align = 0; 5039226633Sdim unsigned index = 0; 5040226633Sdim unsigned inc = 1; 5041226633Sdim switch (size) { 5042226633Sdim default: 5043226633Sdim return MCDisassembler::Fail; 5044226633Sdim case 0: 5045239462Sdim index = fieldFromInstruction(Insn, 5, 3); 5046239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5047226633Sdim align = 2; 5048226633Sdim break; 5049226633Sdim case 1: 5050239462Sdim index = fieldFromInstruction(Insn, 6, 2); 5051239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5052226633Sdim align = 4; 5053239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5054226633Sdim inc = 2; 5055226633Sdim break; 5056226633Sdim case 2: 5057239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5058226633Sdim return MCDisassembler::Fail; // UNDEFINED 5059239462Sdim index = fieldFromInstruction(Insn, 7, 1); 5060239462Sdim if (fieldFromInstruction(Insn, 4, 1) != 0) 5061226633Sdim align = 8; 5062239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 5063226633Sdim inc = 2; 5064226633Sdim break; 5065207618Srdivacky } 5066226633Sdim 5067226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5068226633Sdim return MCDisassembler::Fail; 5069226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5070226633Sdim return MCDisassembler::Fail; 5071226633Sdim if (Rm != 0xF) { // Writeback 5072226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5073226633Sdim return MCDisassembler::Fail; 5074226633Sdim } 5075226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5076226633Sdim return MCDisassembler::Fail; 5077288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5078226633Sdim if (Rm != 0xF) { 5079226633Sdim if (Rm != 0xD) { 5080226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5081226633Sdim return MCDisassembler::Fail; 5082226633Sdim } else 5083288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5084226633Sdim } 5085226633Sdim 5086226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5087226633Sdim return MCDisassembler::Fail; 5088226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5089226633Sdim return MCDisassembler::Fail; 5090288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5091226633Sdim 5092226633Sdim return S; 5093206124Srdivacky} 5094206124Srdivacky 5095234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, 5096226633Sdim uint64_t Address, const void *Decoder) { 5097226633Sdim DecodeStatus S = MCDisassembler::Success; 5098207618Srdivacky 5099239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5100239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 5101239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 5102239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 5103239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 5104226633Sdim 5105226633Sdim unsigned align = 0; 5106226633Sdim unsigned index = 0; 5107226633Sdim unsigned inc = 1; 5108226633Sdim switch (size) { 5109226633Sdim default: 5110226633Sdim return MCDisassembler::Fail; 5111226633Sdim case 0: 5112239462Sdim index = fieldFromInstruction(Insn, 5, 3); 5113239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5114226633Sdim align = 2; 5115226633Sdim break; 5116226633Sdim case 1: 5117239462Sdim index = fieldFromInstruction(Insn, 6, 2); 5118239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5119226633Sdim align = 4; 5120239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5121226633Sdim inc = 2; 5122226633Sdim break; 5123226633Sdim case 2: 5124239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5125226633Sdim return MCDisassembler::Fail; // UNDEFINED 5126239462Sdim index = fieldFromInstruction(Insn, 7, 1); 5127239462Sdim if (fieldFromInstruction(Insn, 4, 1) != 0) 5128226633Sdim align = 8; 5129239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 5130226633Sdim inc = 2; 5131226633Sdim break; 5132207618Srdivacky } 5133226633Sdim 5134226633Sdim if (Rm != 0xF) { // Writeback 5135226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5136226633Sdim return MCDisassembler::Fail; 5137207618Srdivacky } 5138226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5139226633Sdim return MCDisassembler::Fail; 5140288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5141226633Sdim if (Rm != 0xF) { 5142226633Sdim if (Rm != 0xD) { 5143226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5144226633Sdim return MCDisassembler::Fail; 5145226633Sdim } else 5146288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5147226633Sdim } 5148207618Srdivacky 5149226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5150226633Sdim return MCDisassembler::Fail; 5151226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5152226633Sdim return MCDisassembler::Fail; 5153288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5154207618Srdivacky 5155226633Sdim return S; 5156206124Srdivacky} 5157206124Srdivacky 5158234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, 5159226633Sdim uint64_t Address, const void *Decoder) { 5160226633Sdim DecodeStatus S = MCDisassembler::Success; 5161226633Sdim 5162239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5163239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 5164239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 5165239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 5166239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 5167226633Sdim 5168226633Sdim unsigned align = 0; 5169226633Sdim unsigned index = 0; 5170226633Sdim unsigned inc = 1; 5171226633Sdim switch (size) { 5172226633Sdim default: 5173226633Sdim return MCDisassembler::Fail; 5174226633Sdim case 0: 5175239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5176226633Sdim return MCDisassembler::Fail; // UNDEFINED 5177239462Sdim index = fieldFromInstruction(Insn, 5, 3); 5178226633Sdim break; 5179226633Sdim case 1: 5180239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5181226633Sdim return MCDisassembler::Fail; // UNDEFINED 5182239462Sdim index = fieldFromInstruction(Insn, 6, 2); 5183239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5184226633Sdim inc = 2; 5185226633Sdim break; 5186226633Sdim case 2: 5187239462Sdim if (fieldFromInstruction(Insn, 4, 2)) 5188226633Sdim return MCDisassembler::Fail; // UNDEFINED 5189239462Sdim index = fieldFromInstruction(Insn, 7, 1); 5190239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 5191226633Sdim inc = 2; 5192226633Sdim break; 5193206124Srdivacky } 5194226633Sdim 5195226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5196226633Sdim return MCDisassembler::Fail; 5197226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5198226633Sdim return MCDisassembler::Fail; 5199226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 5200226633Sdim return MCDisassembler::Fail; 5201226633Sdim 5202226633Sdim if (Rm != 0xF) { // Writeback 5203226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5204226633Sdim return MCDisassembler::Fail; 5205226633Sdim } 5206226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5207226633Sdim return MCDisassembler::Fail; 5208288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5209226633Sdim if (Rm != 0xF) { 5210226633Sdim if (Rm != 0xD) { 5211226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5212226633Sdim return MCDisassembler::Fail; 5213226633Sdim } else 5214288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5215226633Sdim } 5216226633Sdim 5217226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5218226633Sdim return MCDisassembler::Fail; 5219226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5220226633Sdim return MCDisassembler::Fail; 5221226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 5222226633Sdim return MCDisassembler::Fail; 5223288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5224226633Sdim 5225226633Sdim return S; 5226206124Srdivacky} 5227206124Srdivacky 5228234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, 5229226633Sdim uint64_t Address, const void *Decoder) { 5230226633Sdim DecodeStatus S = MCDisassembler::Success; 5231226633Sdim 5232239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5233239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 5234239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 5235239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 5236239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 5237226633Sdim 5238226633Sdim unsigned align = 0; 5239226633Sdim unsigned index = 0; 5240226633Sdim unsigned inc = 1; 5241226633Sdim switch (size) { 5242226633Sdim default: 5243226633Sdim return MCDisassembler::Fail; 5244226633Sdim case 0: 5245239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5246226633Sdim return MCDisassembler::Fail; // UNDEFINED 5247239462Sdim index = fieldFromInstruction(Insn, 5, 3); 5248226633Sdim break; 5249226633Sdim case 1: 5250239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5251226633Sdim return MCDisassembler::Fail; // UNDEFINED 5252239462Sdim index = fieldFromInstruction(Insn, 6, 2); 5253239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5254226633Sdim inc = 2; 5255226633Sdim break; 5256226633Sdim case 2: 5257239462Sdim if (fieldFromInstruction(Insn, 4, 2)) 5258226633Sdim return MCDisassembler::Fail; // UNDEFINED 5259239462Sdim index = fieldFromInstruction(Insn, 7, 1); 5260239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 5261226633Sdim inc = 2; 5262226633Sdim break; 5263226633Sdim } 5264226633Sdim 5265226633Sdim if (Rm != 0xF) { // Writeback 5266226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5267226633Sdim return MCDisassembler::Fail; 5268226633Sdim } 5269226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5270226633Sdim return MCDisassembler::Fail; 5271288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5272226633Sdim if (Rm != 0xF) { 5273226633Sdim if (Rm != 0xD) { 5274226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5275226633Sdim return MCDisassembler::Fail; 5276226633Sdim } else 5277288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5278226633Sdim } 5279226633Sdim 5280226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5281226633Sdim return MCDisassembler::Fail; 5282226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5283226633Sdim return MCDisassembler::Fail; 5284226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 5285226633Sdim return MCDisassembler::Fail; 5286288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5287226633Sdim 5288226633Sdim return S; 5289206124Srdivacky} 5290206124Srdivacky 5291234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, 5292226633Sdim uint64_t Address, const void *Decoder) { 5293226633Sdim DecodeStatus S = MCDisassembler::Success; 5294226633Sdim 5295239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5296239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 5297239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 5298239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 5299239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 5300226633Sdim 5301226633Sdim unsigned align = 0; 5302226633Sdim unsigned index = 0; 5303226633Sdim unsigned inc = 1; 5304226633Sdim switch (size) { 5305226633Sdim default: 5306226633Sdim return MCDisassembler::Fail; 5307226633Sdim case 0: 5308239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5309226633Sdim align = 4; 5310239462Sdim index = fieldFromInstruction(Insn, 5, 3); 5311226633Sdim break; 5312226633Sdim case 1: 5313239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5314226633Sdim align = 8; 5315239462Sdim index = fieldFromInstruction(Insn, 6, 2); 5316239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5317226633Sdim inc = 2; 5318226633Sdim break; 5319226633Sdim case 2: 5320243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 5321243830Sdim case 0: 5322243830Sdim align = 0; break; 5323243830Sdim case 3: 5324243830Sdim return MCDisassembler::Fail; 5325243830Sdim default: 5326243830Sdim align = 4 << fieldFromInstruction(Insn, 4, 2); break; 5327243830Sdim } 5328243830Sdim 5329239462Sdim index = fieldFromInstruction(Insn, 7, 1); 5330239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 5331226633Sdim inc = 2; 5332226633Sdim break; 5333226633Sdim } 5334226633Sdim 5335226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5336226633Sdim return MCDisassembler::Fail; 5337226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5338226633Sdim return MCDisassembler::Fail; 5339226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 5340226633Sdim return MCDisassembler::Fail; 5341226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 5342226633Sdim return MCDisassembler::Fail; 5343226633Sdim 5344226633Sdim if (Rm != 0xF) { // Writeback 5345226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5346226633Sdim return MCDisassembler::Fail; 5347226633Sdim } 5348226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5349226633Sdim return MCDisassembler::Fail; 5350288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5351226633Sdim if (Rm != 0xF) { 5352226633Sdim if (Rm != 0xD) { 5353226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5354226633Sdim return MCDisassembler::Fail; 5355226633Sdim } else 5356288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5357226633Sdim } 5358226633Sdim 5359226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5360226633Sdim return MCDisassembler::Fail; 5361226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5362226633Sdim return MCDisassembler::Fail; 5363226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 5364226633Sdim return MCDisassembler::Fail; 5365226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 5366226633Sdim return MCDisassembler::Fail; 5367288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5368226633Sdim 5369226633Sdim return S; 5370206124Srdivacky} 5371206124Srdivacky 5372234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, 5373226633Sdim uint64_t Address, const void *Decoder) { 5374226633Sdim DecodeStatus S = MCDisassembler::Success; 5375226633Sdim 5376239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5377239462Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 5378239462Sdim unsigned Rd = fieldFromInstruction(Insn, 12, 4); 5379239462Sdim Rd |= fieldFromInstruction(Insn, 22, 1) << 4; 5380239462Sdim unsigned size = fieldFromInstruction(Insn, 10, 2); 5381226633Sdim 5382226633Sdim unsigned align = 0; 5383226633Sdim unsigned index = 0; 5384226633Sdim unsigned inc = 1; 5385226633Sdim switch (size) { 5386226633Sdim default: 5387226633Sdim return MCDisassembler::Fail; 5388226633Sdim case 0: 5389239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5390226633Sdim align = 4; 5391239462Sdim index = fieldFromInstruction(Insn, 5, 3); 5392226633Sdim break; 5393226633Sdim case 1: 5394239462Sdim if (fieldFromInstruction(Insn, 4, 1)) 5395226633Sdim align = 8; 5396239462Sdim index = fieldFromInstruction(Insn, 6, 2); 5397239462Sdim if (fieldFromInstruction(Insn, 5, 1)) 5398226633Sdim inc = 2; 5399226633Sdim break; 5400226633Sdim case 2: 5401243830Sdim switch (fieldFromInstruction(Insn, 4, 2)) { 5402243830Sdim case 0: 5403243830Sdim align = 0; break; 5404243830Sdim case 3: 5405243830Sdim return MCDisassembler::Fail; 5406243830Sdim default: 5407243830Sdim align = 4 << fieldFromInstruction(Insn, 4, 2); break; 5408243830Sdim } 5409243830Sdim 5410239462Sdim index = fieldFromInstruction(Insn, 7, 1); 5411239462Sdim if (fieldFromInstruction(Insn, 6, 1)) 5412226633Sdim inc = 2; 5413226633Sdim break; 5414226633Sdim } 5415226633Sdim 5416226633Sdim if (Rm != 0xF) { // Writeback 5417226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5418226633Sdim return MCDisassembler::Fail; 5419226633Sdim } 5420226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) 5421226633Sdim return MCDisassembler::Fail; 5422288943Sdim Inst.addOperand(MCOperand::createImm(align)); 5423226633Sdim if (Rm != 0xF) { 5424226633Sdim if (Rm != 0xD) { 5425226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) 5426226633Sdim return MCDisassembler::Fail; 5427226633Sdim } else 5428288943Sdim Inst.addOperand(MCOperand::createReg(0)); 5429226633Sdim } 5430226633Sdim 5431226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) 5432226633Sdim return MCDisassembler::Fail; 5433226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) 5434226633Sdim return MCDisassembler::Fail; 5435226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) 5436226633Sdim return MCDisassembler::Fail; 5437226633Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) 5438226633Sdim return MCDisassembler::Fail; 5439288943Sdim Inst.addOperand(MCOperand::createImm(index)); 5440226633Sdim 5441226633Sdim return S; 5442206124Srdivacky} 5443206124Srdivacky 5444234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, 5445226633Sdim uint64_t Address, const void *Decoder) { 5446226633Sdim DecodeStatus S = MCDisassembler::Success; 5447239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 5448239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 5449239462Sdim unsigned Rm = fieldFromInstruction(Insn, 5, 1); 5450239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 5451239462Sdim Rm |= fieldFromInstruction(Insn, 0, 4) << 1; 5452226633Sdim 5453226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 5454226633Sdim S = MCDisassembler::SoftFail; 5455226633Sdim 5456226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 5457226633Sdim return MCDisassembler::Fail; 5458226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 5459226633Sdim return MCDisassembler::Fail; 5460226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 5461226633Sdim return MCDisassembler::Fail; 5462226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 5463226633Sdim return MCDisassembler::Fail; 5464226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 5465226633Sdim return MCDisassembler::Fail; 5466226633Sdim 5467226633Sdim return S; 5468207618Srdivacky} 5469207618Srdivacky 5470234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, 5471226633Sdim uint64_t Address, const void *Decoder) { 5472226633Sdim DecodeStatus S = MCDisassembler::Success; 5473239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 5474239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 5475239462Sdim unsigned Rm = fieldFromInstruction(Insn, 5, 1); 5476239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 5477239462Sdim Rm |= fieldFromInstruction(Insn, 0, 4) << 1; 5478226633Sdim 5479226633Sdim if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) 5480226633Sdim S = MCDisassembler::SoftFail; 5481226633Sdim 5482226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) 5483226633Sdim return MCDisassembler::Fail; 5484226633Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) 5485226633Sdim return MCDisassembler::Fail; 5486226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) 5487226633Sdim return MCDisassembler::Fail; 5488226633Sdim if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) 5489226633Sdim return MCDisassembler::Fail; 5490226633Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 5491226633Sdim return MCDisassembler::Fail; 5492226633Sdim 5493226633Sdim return S; 5494207618Srdivacky} 5495226633Sdim 5496234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, 5497226633Sdim uint64_t Address, const void *Decoder) { 5498226633Sdim DecodeStatus S = MCDisassembler::Success; 5499239462Sdim unsigned pred = fieldFromInstruction(Insn, 4, 4); 5500239462Sdim unsigned mask = fieldFromInstruction(Insn, 0, 4); 5501226633Sdim 5502226633Sdim if (pred == 0xF) { 5503226633Sdim pred = 0xE; 5504226633Sdim S = MCDisassembler::SoftFail; 5505226633Sdim } 5506226633Sdim 5507261991Sdim if (mask == 0x0) 5508261991Sdim return MCDisassembler::Fail; 5509226633Sdim 5510353358Sdim // IT masks are encoded as a sequence of replacement low-order bits 5511353358Sdim // for the condition code. So if the low bit of the starting 5512353358Sdim // condition code is 1, then we have to flip all the bits above the 5513353358Sdim // terminating bit (which is the lowest 1 bit). 5514353358Sdim if (pred & 1) { 5515353358Sdim unsigned LowBit = mask & -mask; 5516353358Sdim unsigned BitsAboveLowBit = 0xF & (-LowBit << 1); 5517353358Sdim mask ^= BitsAboveLowBit; 5518353358Sdim } 5519353358Sdim 5520288943Sdim Inst.addOperand(MCOperand::createImm(pred)); 5521288943Sdim Inst.addOperand(MCOperand::createImm(mask)); 5522226633Sdim return S; 5523226633Sdim} 5524226633Sdim 5525226633Sdimstatic DecodeStatus 5526234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn, 5527226633Sdim uint64_t Address, const void *Decoder) { 5528226633Sdim DecodeStatus S = MCDisassembler::Success; 5529226633Sdim 5530239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 5531239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); 5532239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5533239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 5534239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 5535239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 5536239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 5537226633Sdim bool writeback = (W == 1) | (P == 0); 5538226633Sdim 5539226633Sdim addr |= (U << 8) | (Rn << 9); 5540226633Sdim 5541226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 5542226633Sdim Check(S, MCDisassembler::SoftFail); 5543226633Sdim if (Rt == Rt2) 5544226633Sdim Check(S, MCDisassembler::SoftFail); 5545226633Sdim 5546226633Sdim // Rt 5547226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 5548226633Sdim return MCDisassembler::Fail; 5549226633Sdim // Rt2 5550226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 5551226633Sdim return MCDisassembler::Fail; 5552226633Sdim // Writeback operand 5553226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 5554226633Sdim return MCDisassembler::Fail; 5555226633Sdim // addr 5556226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 5557226633Sdim return MCDisassembler::Fail; 5558226633Sdim 5559226633Sdim return S; 5560226633Sdim} 5561226633Sdim 5562226633Sdimstatic DecodeStatus 5563234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn, 5564226633Sdim uint64_t Address, const void *Decoder) { 5565226633Sdim DecodeStatus S = MCDisassembler::Success; 5566226633Sdim 5567239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 5568239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); 5569239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5570239462Sdim unsigned addr = fieldFromInstruction(Insn, 0, 8); 5571239462Sdim unsigned W = fieldFromInstruction(Insn, 21, 1); 5572239462Sdim unsigned U = fieldFromInstruction(Insn, 23, 1); 5573239462Sdim unsigned P = fieldFromInstruction(Insn, 24, 1); 5574226633Sdim bool writeback = (W == 1) | (P == 0); 5575226633Sdim 5576226633Sdim addr |= (U << 8) | (Rn << 9); 5577226633Sdim 5578226633Sdim if (writeback && (Rn == Rt || Rn == Rt2)) 5579226633Sdim Check(S, MCDisassembler::SoftFail); 5580226633Sdim 5581226633Sdim // Writeback operand 5582226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 5583226633Sdim return MCDisassembler::Fail; 5584226633Sdim // Rt 5585226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) 5586226633Sdim return MCDisassembler::Fail; 5587226633Sdim // Rt2 5588226633Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) 5589226633Sdim return MCDisassembler::Fail; 5590226633Sdim // addr 5591226633Sdim if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) 5592226633Sdim return MCDisassembler::Fail; 5593226633Sdim 5594226633Sdim return S; 5595226633Sdim} 5596226633Sdim 5597234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, 5598226633Sdim uint64_t Address, const void *Decoder) { 5599239462Sdim unsigned sign1 = fieldFromInstruction(Insn, 21, 1); 5600239462Sdim unsigned sign2 = fieldFromInstruction(Insn, 23, 1); 5601226633Sdim if (sign1 != sign2) return MCDisassembler::Fail; 5602360784Sdim const unsigned Rd = fieldFromInstruction(Insn, 8, 4); 5603360784Sdim assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst"); 5604360784Sdim DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder); 5605226633Sdim 5606239462Sdim unsigned Val = fieldFromInstruction(Insn, 0, 8); 5607239462Sdim Val |= fieldFromInstruction(Insn, 12, 3) << 8; 5608239462Sdim Val |= fieldFromInstruction(Insn, 26, 1) << 11; 5609360784Sdim // If sign, then it is decreasing the address. 5610360784Sdim if (sign1) { 5611360784Sdim // Following ARMv7 Architecture Manual, when the offset 5612360784Sdim // is zero, it is decoded as a subw, not as a adr.w 5613360784Sdim if (!Val) { 5614360784Sdim Inst.setOpcode(ARM::t2SUBri12); 5615360784Sdim Inst.addOperand(MCOperand::createReg(ARM::PC)); 5616360784Sdim } else 5617360784Sdim Val = -Val; 5618360784Sdim } 5619360784Sdim Inst.addOperand(MCOperand::createImm(Val)); 5620360784Sdim return S; 5621226633Sdim} 5622226633Sdim 5623234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val, 5624226633Sdim uint64_t Address, 5625226633Sdim const void *Decoder) { 5626226633Sdim DecodeStatus S = MCDisassembler::Success; 5627226633Sdim 5628226633Sdim // Shift of "asr #32" is not allowed in Thumb2 mode. 5629288943Sdim if (Val == 0x20) S = MCDisassembler::Fail; 5630288943Sdim Inst.addOperand(MCOperand::createImm(Val)); 5631226633Sdim return S; 5632226633Sdim} 5633226633Sdim 5634234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, 5635234353Sdim uint64_t Address, const void *Decoder) { 5636239462Sdim unsigned Rt = fieldFromInstruction(Insn, 12, 4); 5637239462Sdim unsigned Rt2 = fieldFromInstruction(Insn, 0, 4); 5638239462Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 5639239462Sdim unsigned pred = fieldFromInstruction(Insn, 28, 4); 5640234353Sdim 5641234353Sdim if (pred == 0xF) 5642234353Sdim return DecodeCPSInstruction(Inst, Insn, Address, Decoder); 5643234353Sdim 5644234353Sdim DecodeStatus S = MCDisassembler::Success; 5645234982Sdim 5646234982Sdim if (Rt == Rn || Rn == Rt2) 5647234982Sdim S = MCDisassembler::SoftFail; 5648234982Sdim 5649234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 5650234353Sdim return MCDisassembler::Fail; 5651234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 5652234353Sdim return MCDisassembler::Fail; 5653234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 5654234353Sdim return MCDisassembler::Fail; 5655234353Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 5656234353Sdim return MCDisassembler::Fail; 5657234353Sdim 5658234353Sdim return S; 5659234353Sdim} 5660234353Sdim 5661234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, 5662234353Sdim uint64_t Address, const void *Decoder) { 5663296417Sdim const FeatureBitset &featureBits = 5664296417Sdim ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits(); 5665296417Sdim bool hasFullFP16 = featureBits[ARM::FeatureFullFP16]; 5666296417Sdim 5667239462Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 5668239462Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 5669239462Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 5670239462Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 5671239462Sdim unsigned imm = fieldFromInstruction(Insn, 16, 6); 5672239462Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 5673261991Sdim unsigned op = fieldFromInstruction(Insn, 5, 1); 5674234353Sdim 5675234353Sdim DecodeStatus S = MCDisassembler::Success; 5676234353Sdim 5677296417Sdim // If the top 3 bits of imm are clear, this is a VMOV (immediate) 5678296417Sdim if (!(imm & 0x38)) { 5679296417Sdim if (cmode == 0xF) { 5680296417Sdim if (op == 1) return MCDisassembler::Fail; 5681296417Sdim Inst.setOpcode(ARM::VMOVv2f32); 5682296417Sdim } 5683296417Sdim if (hasFullFP16) { 5684296417Sdim if (cmode == 0xE) { 5685296417Sdim if (op == 1) { 5686296417Sdim Inst.setOpcode(ARM::VMOVv1i64); 5687296417Sdim } else { 5688296417Sdim Inst.setOpcode(ARM::VMOVv8i8); 5689296417Sdim } 5690296417Sdim } 5691296417Sdim if (cmode == 0xD) { 5692296417Sdim if (op == 1) { 5693296417Sdim Inst.setOpcode(ARM::VMVNv2i32); 5694296417Sdim } else { 5695296417Sdim Inst.setOpcode(ARM::VMOVv2i32); 5696296417Sdim } 5697296417Sdim } 5698296417Sdim if (cmode == 0xC) { 5699296417Sdim if (op == 1) { 5700296417Sdim Inst.setOpcode(ARM::VMVNv2i32); 5701296417Sdim } else { 5702296417Sdim Inst.setOpcode(ARM::VMOVv2i32); 5703296417Sdim } 5704296417Sdim } 5705296417Sdim } 5706360784Sdim return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder); 5707234353Sdim } 5708234353Sdim 5709261991Sdim if (!(imm & 0x20)) return MCDisassembler::Fail; 5710234353Sdim 5711234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) 5712234353Sdim return MCDisassembler::Fail; 5713234353Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder))) 5714234353Sdim return MCDisassembler::Fail; 5715288943Sdim Inst.addOperand(MCOperand::createImm(64 - imm)); 5716234353Sdim 5717234353Sdim return S; 5718234353Sdim} 5719234353Sdim 5720234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, 5721234353Sdim uint64_t Address, const void *Decoder) { 5722296417Sdim const FeatureBitset &featureBits = 5723296417Sdim ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits(); 5724296417Sdim bool hasFullFP16 = featureBits[ARM::FeatureFullFP16]; 5725296417Sdim 5726239462Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 5727239462Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 5728239462Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 5729239462Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 5730239462Sdim unsigned imm = fieldFromInstruction(Insn, 16, 6); 5731239462Sdim unsigned cmode = fieldFromInstruction(Insn, 8, 4); 5732261991Sdim unsigned op = fieldFromInstruction(Insn, 5, 1); 5733234353Sdim 5734234353Sdim DecodeStatus S = MCDisassembler::Success; 5735234353Sdim 5736296417Sdim // If the top 3 bits of imm are clear, this is a VMOV (immediate) 5737296417Sdim if (!(imm & 0x38)) { 5738296417Sdim if (cmode == 0xF) { 5739296417Sdim if (op == 1) return MCDisassembler::Fail; 5740296417Sdim Inst.setOpcode(ARM::VMOVv4f32); 5741296417Sdim } 5742296417Sdim if (hasFullFP16) { 5743296417Sdim if (cmode == 0xE) { 5744296417Sdim if (op == 1) { 5745296417Sdim Inst.setOpcode(ARM::VMOVv2i64); 5746296417Sdim } else { 5747296417Sdim Inst.setOpcode(ARM::VMOVv16i8); 5748296417Sdim } 5749296417Sdim } 5750296417Sdim if (cmode == 0xD) { 5751296417Sdim if (op == 1) { 5752296417Sdim Inst.setOpcode(ARM::VMVNv4i32); 5753296417Sdim } else { 5754296417Sdim Inst.setOpcode(ARM::VMOVv4i32); 5755296417Sdim } 5756296417Sdim } 5757296417Sdim if (cmode == 0xC) { 5758296417Sdim if (op == 1) { 5759296417Sdim Inst.setOpcode(ARM::VMVNv4i32); 5760296417Sdim } else { 5761296417Sdim Inst.setOpcode(ARM::VMOVv4i32); 5762296417Sdim } 5763296417Sdim } 5764296417Sdim } 5765360784Sdim return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder); 5766234353Sdim } 5767234353Sdim 5768261991Sdim if (!(imm & 0x20)) return MCDisassembler::Fail; 5769234353Sdim 5770234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder))) 5771234353Sdim return MCDisassembler::Fail; 5772234353Sdim if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder))) 5773234353Sdim return MCDisassembler::Fail; 5774288943Sdim Inst.addOperand(MCOperand::createImm(64 - imm)); 5775234353Sdim 5776234353Sdim return S; 5777234353Sdim} 5778234353Sdim 5779327952Sdimstatic DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst, 5780327952Sdim unsigned Insn, 5781327952Sdim uint64_t Address, 5782327952Sdim const void *Decoder) { 5783327952Sdim unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); 5784327952Sdim Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); 5785327952Sdim unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0); 5786327952Sdim Vn |= (fieldFromInstruction(Insn, 7, 1) << 4); 5787327952Sdim unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); 5788327952Sdim Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); 5789327952Sdim unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0); 5790327952Sdim unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0); 5791327952Sdim 5792327952Sdim DecodeStatus S = MCDisassembler::Success; 5793327952Sdim 5794327952Sdim auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass; 5795327952Sdim 5796327952Sdim if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder))) 5797327952Sdim return MCDisassembler::Fail; 5798327952Sdim if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder))) 5799327952Sdim return MCDisassembler::Fail; 5800327952Sdim if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder))) 5801327952Sdim return MCDisassembler::Fail; 5802327952Sdim if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder))) 5803327952Sdim return MCDisassembler::Fail; 5804327952Sdim // The lane index does not have any bits in the encoding, because it can only 5805327952Sdim // be 0. 5806327952Sdim Inst.addOperand(MCOperand::createImm(0)); 5807327952Sdim Inst.addOperand(MCOperand::createImm(rotate)); 5808327952Sdim 5809327952Sdim return S; 5810327952Sdim} 5811327952Sdim 5812234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, 5813234353Sdim uint64_t Address, const void *Decoder) { 5814234353Sdim DecodeStatus S = MCDisassembler::Success; 5815234353Sdim 5816239462Sdim unsigned Rn = fieldFromInstruction(Val, 16, 4); 5817239462Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 5818239462Sdim unsigned Rm = fieldFromInstruction(Val, 0, 4); 5819239462Sdim Rm |= (fieldFromInstruction(Val, 23, 1) << 4); 5820239462Sdim unsigned Cond = fieldFromInstruction(Val, 28, 4); 5821296417Sdim 5822239462Sdim if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt) 5823234353Sdim S = MCDisassembler::SoftFail; 5824234353Sdim 5825234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 5826234353Sdim return MCDisassembler::Fail; 5827234353Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 5828234353Sdim return MCDisassembler::Fail; 5829341825Sdim if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder))) 5830234353Sdim return MCDisassembler::Fail; 5831234353Sdim if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder))) 5832234353Sdim return MCDisassembler::Fail; 5833234353Sdim if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder))) 5834234353Sdim return MCDisassembler::Fail; 5835234353Sdim 5836234353Sdim return S; 5837234353Sdim} 5838234353Sdim 5839321369Sdimstatic DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val, 5840309124Sdim uint64_t Address, const void *Decoder) { 5841234982Sdim DecodeStatus S = MCDisassembler::Success; 5842234982Sdim 5843239462Sdim unsigned CRm = fieldFromInstruction(Val, 0, 4); 5844239462Sdim unsigned opc1 = fieldFromInstruction(Val, 4, 4); 5845239462Sdim unsigned cop = fieldFromInstruction(Val, 8, 4); 5846239462Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 5847239462Sdim unsigned Rt2 = fieldFromInstruction(Val, 16, 4); 5848234982Sdim 5849234982Sdim if ((cop & ~0x1) == 0xa) 5850234982Sdim return MCDisassembler::Fail; 5851234982Sdim 5852234982Sdim if (Rt == Rt2) 5853234982Sdim S = MCDisassembler::SoftFail; 5854234982Sdim 5855309124Sdim // We have to check if the instruction is MRRC2 5856309124Sdim // or MCRR2 when constructing the operands for 5857309124Sdim // Inst. Reason is because MRRC2 stores to two 5858309124Sdim // registers so it's tablegen desc has has two 5859309124Sdim // outputs whereas MCRR doesn't store to any 5860309124Sdim // registers so all of it's operands are listed 5861309124Sdim // as inputs, therefore the operand order for 5862309124Sdim // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm] 5863309124Sdim // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm] 5864309124Sdim 5865309124Sdim if (Inst.getOpcode() == ARM::MRRC2) { 5866309124Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 5867309124Sdim return MCDisassembler::Fail; 5868309124Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 5869309124Sdim return MCDisassembler::Fail; 5870309124Sdim } 5871288943Sdim Inst.addOperand(MCOperand::createImm(cop)); 5872288943Sdim Inst.addOperand(MCOperand::createImm(opc1)); 5873309124Sdim if (Inst.getOpcode() == ARM::MCRR2) { 5874309124Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) 5875309124Sdim return MCDisassembler::Fail; 5876309124Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) 5877309124Sdim return MCDisassembler::Fail; 5878309124Sdim } 5879288943Sdim Inst.addOperand(MCOperand::createImm(CRm)); 5880234982Sdim 5881234982Sdim return S; 5882234982Sdim} 5883327952Sdim 5884327952Sdimstatic DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val, 5885327952Sdim uint64_t Address, 5886327952Sdim const void *Decoder) { 5887327952Sdim const FeatureBitset &featureBits = 5888327952Sdim ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits(); 5889327952Sdim DecodeStatus S = MCDisassembler::Success; 5890327952Sdim 5891353358Sdim // Add explicit operand for the destination sysreg, for cases where 5892353358Sdim // we have to model it for code generation purposes. 5893353358Sdim switch (Inst.getOpcode()) { 5894353358Sdim case ARM::VMSR_FPSCR_NZCVQC: 5895353358Sdim Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV)); 5896353358Sdim break; 5897353358Sdim case ARM::VMSR_P0: 5898353358Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 5899353358Sdim break; 5900353358Sdim } 5901327952Sdim 5902353358Sdim if (Inst.getOpcode() != ARM::FMSTAT) { 5903353358Sdim unsigned Rt = fieldFromInstruction(Val, 12, 4); 5904327952Sdim 5905353358Sdim if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) { 5906353358Sdim if (Rt == 13 || Rt == 15) 5907353358Sdim S = MCDisassembler::SoftFail; 5908353358Sdim Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)); 5909353358Sdim } else 5910353358Sdim Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)); 5911353358Sdim } 5912353358Sdim 5913353358Sdim // Add explicit operand for the source sysreg, similarly to above. 5914353358Sdim switch (Inst.getOpcode()) { 5915353358Sdim case ARM::VMRS_FPSCR_NZCVQC: 5916353358Sdim Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV)); 5917353358Sdim break; 5918353358Sdim case ARM::VMRS_P0: 5919353358Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 5920353358Sdim break; 5921353358Sdim } 5922353358Sdim 5923327952Sdim if (featureBits[ARM::ModeThumb]) { 5924327952Sdim Inst.addOperand(MCOperand::createImm(ARMCC::AL)); 5925327952Sdim Inst.addOperand(MCOperand::createReg(0)); 5926327952Sdim } else { 5927327952Sdim unsigned pred = fieldFromInstruction(Val, 28, 4); 5928327952Sdim if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) 5929327952Sdim return MCDisassembler::Fail; 5930327952Sdim } 5931327952Sdim 5932327952Sdim return S; 5933327952Sdim} 5934353358Sdim 5935353358Sdimtemplate <bool isSigned, bool isNeg, bool zeroPermitted, int size> 5936353358Sdimstatic DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned Val, 5937353358Sdim uint64_t Address, 5938353358Sdim const void *Decoder) { 5939353358Sdim DecodeStatus S = MCDisassembler::Success; 5940353358Sdim if (Val == 0 && !zeroPermitted) 5941353358Sdim S = MCDisassembler::Fail; 5942353358Sdim 5943353358Sdim uint64_t DecVal; 5944353358Sdim if (isSigned) 5945353358Sdim DecVal = SignExtend32<size + 1>(Val << 1); 5946353358Sdim else 5947353358Sdim DecVal = (Val << 1); 5948353358Sdim 5949353358Sdim if (!tryAddingSymbolicOperand(Address, Address + DecVal + 4, true, 4, Inst, 5950353358Sdim Decoder)) 5951353358Sdim Inst.addOperand(MCOperand::createImm(isNeg ? -DecVal : DecVal)); 5952353358Sdim return S; 5953353358Sdim} 5954353358Sdim 5955353358Sdimstatic DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned Val, 5956353358Sdim uint64_t Address, 5957353358Sdim const void *Decoder) { 5958353358Sdim 5959353358Sdim uint64_t LocImm = Inst.getOperand(0).getImm(); 5960353358Sdim Val = LocImm + (2 << Val); 5961353358Sdim if (!tryAddingSymbolicOperand(Address, Address + Val + 4, true, 4, Inst, 5962353358Sdim Decoder)) 5963353358Sdim Inst.addOperand(MCOperand::createImm(Val)); 5964353358Sdim return MCDisassembler::Success; 5965353358Sdim} 5966353358Sdim 5967353358Sdimstatic DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val, 5968353358Sdim uint64_t Address, 5969353358Sdim const void *Decoder) { 5970353358Sdim if (Val >= ARMCC::AL) // also exclude the non-condition NV 5971353358Sdim return MCDisassembler::Fail; 5972353358Sdim Inst.addOperand(MCOperand::createImm(Val)); 5973353358Sdim return MCDisassembler::Success; 5974353358Sdim} 5975353358Sdim 5976353358Sdimstatic DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address, 5977353358Sdim const void *Decoder) { 5978353358Sdim DecodeStatus S = MCDisassembler::Success; 5979353358Sdim 5980353358Sdim if (Inst.getOpcode() == ARM::MVE_LCTP) 5981353358Sdim return S; 5982353358Sdim 5983353358Sdim unsigned Imm = fieldFromInstruction(Insn, 11, 1) | 5984353358Sdim fieldFromInstruction(Insn, 1, 10) << 1; 5985353358Sdim switch (Inst.getOpcode()) { 5986353358Sdim case ARM::t2LEUpdate: 5987353358Sdim case ARM::MVE_LETP: 5988353358Sdim Inst.addOperand(MCOperand::createReg(ARM::LR)); 5989353358Sdim Inst.addOperand(MCOperand::createReg(ARM::LR)); 5990353358Sdim LLVM_FALLTHROUGH; 5991353358Sdim case ARM::t2LE: 5992353358Sdim if (!Check(S, DecodeBFLabelOperand<false, true, true, 11>( 5993353358Sdim Inst, Imm, Address, Decoder))) 5994353358Sdim return MCDisassembler::Fail; 5995353358Sdim break; 5996353358Sdim case ARM::t2WLS: 5997353358Sdim case ARM::MVE_WLSTP_8: 5998353358Sdim case ARM::MVE_WLSTP_16: 5999353358Sdim case ARM::MVE_WLSTP_32: 6000353358Sdim case ARM::MVE_WLSTP_64: 6001353358Sdim Inst.addOperand(MCOperand::createReg(ARM::LR)); 6002353358Sdim if (!Check(S, 6003353358Sdim DecoderGPRRegisterClass(Inst, fieldFromInstruction(Insn, 16, 4), 6004353358Sdim Address, Decoder)) || 6005353358Sdim !Check(S, DecodeBFLabelOperand<false, false, true, 11>( 6006353358Sdim Inst, Imm, Address, Decoder))) 6007353358Sdim return MCDisassembler::Fail; 6008353358Sdim break; 6009353358Sdim case ARM::t2DLS: 6010353358Sdim case ARM::MVE_DLSTP_8: 6011353358Sdim case ARM::MVE_DLSTP_16: 6012353358Sdim case ARM::MVE_DLSTP_32: 6013353358Sdim case ARM::MVE_DLSTP_64: 6014353358Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 6015353358Sdim if (Rn == 0xF) { 6016353358Sdim // Enforce all the rest of the instruction bits in LCTP, which 6017353358Sdim // won't have been reliably checked based on LCTP's own tablegen 6018353358Sdim // record, because we came to this decode by a roundabout route. 6019353358Sdim uint32_t CanonicalLCTP = 0xF00FE001, SBZMask = 0x00300FFE; 6020353358Sdim if ((Insn & ~SBZMask) != CanonicalLCTP) 6021353358Sdim return MCDisassembler::Fail; // a mandatory bit is wrong: hard fail 6022353358Sdim if (Insn != CanonicalLCTP) 6023353358Sdim Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail 6024353358Sdim 6025353358Sdim Inst.setOpcode(ARM::MVE_LCTP); 6026353358Sdim } else { 6027353358Sdim Inst.addOperand(MCOperand::createReg(ARM::LR)); 6028353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, 6029353358Sdim fieldFromInstruction(Insn, 16, 4), 6030353358Sdim Address, Decoder))) 6031353358Sdim return MCDisassembler::Fail; 6032353358Sdim } 6033353358Sdim break; 6034353358Sdim } 6035353358Sdim return S; 6036353358Sdim} 6037353358Sdim 6038353358Sdimstatic DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val, 6039353358Sdim uint64_t Address, 6040353358Sdim const void *Decoder) { 6041353358Sdim DecodeStatus S = MCDisassembler::Success; 6042353358Sdim 6043353358Sdim if (Val == 0) 6044353358Sdim Val = 32; 6045353358Sdim 6046353358Sdim Inst.addOperand(MCOperand::createImm(Val)); 6047353358Sdim 6048353358Sdim return S; 6049353358Sdim} 6050353358Sdim 6051353358Sdimstatic DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo, 6052353358Sdim uint64_t Address, const void *Decoder) { 6053353358Sdim if ((RegNo) + 1 > 11) 6054353358Sdim return MCDisassembler::Fail; 6055353358Sdim 6056353358Sdim unsigned Register = GPRDecoderTable[(RegNo) + 1]; 6057353358Sdim Inst.addOperand(MCOperand::createReg(Register)); 6058353358Sdim return MCDisassembler::Success; 6059353358Sdim} 6060353358Sdim 6061353358Sdimstatic DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo, 6062353358Sdim uint64_t Address, const void *Decoder) { 6063353358Sdim if ((RegNo) > 14) 6064353358Sdim return MCDisassembler::Fail; 6065353358Sdim 6066353358Sdim unsigned Register = GPRDecoderTable[(RegNo)]; 6067353358Sdim Inst.addOperand(MCOperand::createReg(Register)); 6068353358Sdim return MCDisassembler::Success; 6069353358Sdim} 6070353358Sdim 6071353358Sdimstatic DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address, 6072353358Sdim const void *Decoder) { 6073353358Sdim DecodeStatus S = MCDisassembler::Success; 6074353358Sdim 6075353358Sdim Inst.addOperand(MCOperand::createImm(ARMCC::AL)); 6076353358Sdim Inst.addOperand(MCOperand::createReg(0)); 6077353358Sdim if (Inst.getOpcode() == ARM::VSCCLRMD) { 6078353358Sdim unsigned reglist = (fieldFromInstruction(Insn, 1, 7) << 1) | 6079353358Sdim (fieldFromInstruction(Insn, 12, 4) << 8) | 6080353358Sdim (fieldFromInstruction(Insn, 22, 1) << 12); 6081353358Sdim if (!Check(S, DecodeDPRRegListOperand(Inst, reglist, Address, Decoder))) { 6082353358Sdim return MCDisassembler::Fail; 6083353358Sdim } 6084353358Sdim } else { 6085353358Sdim unsigned reglist = fieldFromInstruction(Insn, 0, 8) | 6086353358Sdim (fieldFromInstruction(Insn, 22, 1) << 8) | 6087353358Sdim (fieldFromInstruction(Insn, 12, 4) << 9); 6088353358Sdim if (!Check(S, DecodeSPRRegListOperand(Inst, reglist, Address, Decoder))) { 6089353358Sdim return MCDisassembler::Fail; 6090353358Sdim } 6091353358Sdim } 6092353358Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 6093353358Sdim 6094353358Sdim return S; 6095353358Sdim} 6096353358Sdim 6097353358Sdimstatic DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo, 6098353358Sdim uint64_t Address, 6099353358Sdim const void *Decoder) { 6100353358Sdim if (RegNo > 7) 6101353358Sdim return MCDisassembler::Fail; 6102353358Sdim 6103353358Sdim unsigned Register = QPRDecoderTable[RegNo]; 6104353358Sdim Inst.addOperand(MCOperand::createReg(Register)); 6105353358Sdim return MCDisassembler::Success; 6106353358Sdim} 6107353358Sdim 6108353358Sdimstatic const uint16_t QQPRDecoderTable[] = { 6109353358Sdim ARM::Q0_Q1, ARM::Q1_Q2, ARM::Q2_Q3, ARM::Q3_Q4, 6110353358Sdim ARM::Q4_Q5, ARM::Q5_Q6, ARM::Q6_Q7 6111353358Sdim}; 6112353358Sdim 6113353358Sdimstatic DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo, 6114353358Sdim uint64_t Address, 6115353358Sdim const void *Decoder) { 6116353358Sdim if (RegNo > 6) 6117353358Sdim return MCDisassembler::Fail; 6118353358Sdim 6119353358Sdim unsigned Register = QQPRDecoderTable[RegNo]; 6120353358Sdim Inst.addOperand(MCOperand::createReg(Register)); 6121353358Sdim return MCDisassembler::Success; 6122353358Sdim} 6123353358Sdim 6124353358Sdimstatic const uint16_t QQQQPRDecoderTable[] = { 6125353358Sdim ARM::Q0_Q1_Q2_Q3, ARM::Q1_Q2_Q3_Q4, ARM::Q2_Q3_Q4_Q5, 6126353358Sdim ARM::Q3_Q4_Q5_Q6, ARM::Q4_Q5_Q6_Q7 6127353358Sdim}; 6128353358Sdim 6129353358Sdimstatic DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo, 6130353358Sdim uint64_t Address, 6131353358Sdim const void *Decoder) { 6132353358Sdim if (RegNo > 4) 6133353358Sdim return MCDisassembler::Fail; 6134353358Sdim 6135353358Sdim unsigned Register = QQQQPRDecoderTable[RegNo]; 6136353358Sdim Inst.addOperand(MCOperand::createReg(Register)); 6137353358Sdim return MCDisassembler::Success; 6138353358Sdim} 6139353358Sdim 6140353358Sdimstatic DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val, 6141353358Sdim uint64_t Address, 6142353358Sdim const void *Decoder) { 6143353358Sdim DecodeStatus S = MCDisassembler::Success; 6144353358Sdim 6145353358Sdim // Parse VPT mask and encode it in the MCInst as an immediate with the same 6146353358Sdim // format as the it_mask. That is, from the second 'e|t' encode 'e' as 1 and 6147353358Sdim // 't' as 0 and finish with a 1. 6148353358Sdim unsigned Imm = 0; 6149353358Sdim // We always start with a 't'. 6150353358Sdim unsigned CurBit = 0; 6151353358Sdim for (int i = 3; i >= 0; --i) { 6152353358Sdim // If the bit we are looking at is not the same as last one, invert the 6153353358Sdim // CurBit, if it is the same leave it as is. 6154353358Sdim CurBit ^= (Val >> i) & 1U; 6155353358Sdim 6156353358Sdim // Encode the CurBit at the right place in the immediate. 6157353358Sdim Imm |= (CurBit << i); 6158353358Sdim 6159353358Sdim // If we are done, finish the encoding with a 1. 6160353358Sdim if ((Val & ~(~0U << i)) == 0) { 6161353358Sdim Imm |= 1U << i; 6162353358Sdim break; 6163353358Sdim } 6164353358Sdim } 6165353358Sdim 6166353358Sdim Inst.addOperand(MCOperand::createImm(Imm)); 6167353358Sdim 6168353358Sdim return S; 6169353358Sdim} 6170353358Sdim 6171353358Sdimstatic DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo, 6172353358Sdim uint64_t Address, const void *Decoder) { 6173353358Sdim // The vpred_r operand type includes an MQPR register field derived 6174353358Sdim // from the encoding. But we don't actually want to add an operand 6175353358Sdim // to the MCInst at this stage, because AddThumbPredicate will do it 6176353358Sdim // later, and will infer the register number from the TIED_TO 6177353358Sdim // constraint. So this is a deliberately empty decoder method that 6178353358Sdim // will inhibit the auto-generated disassembly code from adding an 6179353358Sdim // operand at all. 6180353358Sdim return MCDisassembler::Success; 6181353358Sdim} 6182353358Sdim 6183353358Sdimstatic DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst, 6184353358Sdim unsigned Val, 6185353358Sdim uint64_t Address, 6186353358Sdim const void *Decoder) { 6187353358Sdim Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE)); 6188353358Sdim return MCDisassembler::Success; 6189353358Sdim} 6190353358Sdim 6191353358Sdimstatic DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst, 6192353358Sdim unsigned Val, 6193353358Sdim uint64_t Address, 6194353358Sdim const void *Decoder) { 6195353358Sdim unsigned Code; 6196353358Sdim switch (Val & 0x3) { 6197353358Sdim case 0: 6198353358Sdim Code = ARMCC::GE; 6199353358Sdim break; 6200353358Sdim case 1: 6201353358Sdim Code = ARMCC::LT; 6202353358Sdim break; 6203353358Sdim case 2: 6204353358Sdim Code = ARMCC::GT; 6205353358Sdim break; 6206353358Sdim case 3: 6207353358Sdim Code = ARMCC::LE; 6208353358Sdim break; 6209353358Sdim } 6210353358Sdim Inst.addOperand(MCOperand::createImm(Code)); 6211353358Sdim return MCDisassembler::Success; 6212353358Sdim} 6213353358Sdim 6214353358Sdimstatic DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst, 6215353358Sdim unsigned Val, 6216353358Sdim uint64_t Address, 6217353358Sdim const void *Decoder) { 6218353358Sdim Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI)); 6219353358Sdim return MCDisassembler::Success; 6220353358Sdim} 6221353358Sdim 6222353358Sdimstatic DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val, 6223353358Sdim uint64_t Address, 6224353358Sdim const void *Decoder) { 6225353358Sdim unsigned Code; 6226353358Sdim switch (Val) { 6227353358Sdim default: 6228353358Sdim return MCDisassembler::Fail; 6229353358Sdim case 0: 6230353358Sdim Code = ARMCC::EQ; 6231353358Sdim break; 6232353358Sdim case 1: 6233353358Sdim Code = ARMCC::NE; 6234353358Sdim break; 6235353358Sdim case 4: 6236353358Sdim Code = ARMCC::GE; 6237353358Sdim break; 6238353358Sdim case 5: 6239353358Sdim Code = ARMCC::LT; 6240353358Sdim break; 6241353358Sdim case 6: 6242353358Sdim Code = ARMCC::GT; 6243353358Sdim break; 6244353358Sdim case 7: 6245353358Sdim Code = ARMCC::LE; 6246353358Sdim break; 6247353358Sdim } 6248353358Sdim 6249353358Sdim Inst.addOperand(MCOperand::createImm(Code)); 6250353358Sdim return MCDisassembler::Success; 6251353358Sdim} 6252353358Sdim 6253353358Sdimstatic DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Val, 6254353358Sdim uint64_t Address, const void *Decoder) { 6255353358Sdim DecodeStatus S = MCDisassembler::Success; 6256353358Sdim 6257353358Sdim unsigned DecodedVal = 64 - Val; 6258353358Sdim 6259353358Sdim switch (Inst.getOpcode()) { 6260353358Sdim case ARM::MVE_VCVTf16s16_fix: 6261353358Sdim case ARM::MVE_VCVTs16f16_fix: 6262353358Sdim case ARM::MVE_VCVTf16u16_fix: 6263353358Sdim case ARM::MVE_VCVTu16f16_fix: 6264353358Sdim if (DecodedVal > 16) 6265353358Sdim return MCDisassembler::Fail; 6266353358Sdim break; 6267353358Sdim case ARM::MVE_VCVTf32s32_fix: 6268353358Sdim case ARM::MVE_VCVTs32f32_fix: 6269353358Sdim case ARM::MVE_VCVTf32u32_fix: 6270353358Sdim case ARM::MVE_VCVTu32f32_fix: 6271353358Sdim if (DecodedVal > 32) 6272353358Sdim return MCDisassembler::Fail; 6273353358Sdim break; 6274353358Sdim } 6275353358Sdim 6276353358Sdim Inst.addOperand(MCOperand::createImm(64 - Val)); 6277353358Sdim 6278353358Sdim return S; 6279353358Sdim} 6280353358Sdim 6281353358Sdimstatic unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) { 6282353358Sdim switch (Opcode) { 6283353358Sdim case ARM::VSTR_P0_off: 6284353358Sdim case ARM::VSTR_P0_pre: 6285353358Sdim case ARM::VSTR_P0_post: 6286353358Sdim case ARM::VLDR_P0_off: 6287353358Sdim case ARM::VLDR_P0_pre: 6288353358Sdim case ARM::VLDR_P0_post: 6289353358Sdim return ARM::P0; 6290353358Sdim default: 6291353358Sdim return 0; 6292353358Sdim } 6293353358Sdim} 6294353358Sdim 6295353358Sdimtemplate<bool Writeback> 6296353358Sdimstatic DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val, 6297353358Sdim uint64_t Address, 6298353358Sdim const void *Decoder) { 6299353358Sdim switch (Inst.getOpcode()) { 6300353358Sdim case ARM::VSTR_FPSCR_pre: 6301353358Sdim case ARM::VSTR_FPSCR_NZCVQC_pre: 6302353358Sdim case ARM::VLDR_FPSCR_pre: 6303353358Sdim case ARM::VLDR_FPSCR_NZCVQC_pre: 6304353358Sdim case ARM::VSTR_FPSCR_off: 6305353358Sdim case ARM::VSTR_FPSCR_NZCVQC_off: 6306353358Sdim case ARM::VLDR_FPSCR_off: 6307353358Sdim case ARM::VLDR_FPSCR_NZCVQC_off: 6308353358Sdim case ARM::VSTR_FPSCR_post: 6309353358Sdim case ARM::VSTR_FPSCR_NZCVQC_post: 6310353358Sdim case ARM::VLDR_FPSCR_post: 6311353358Sdim case ARM::VLDR_FPSCR_NZCVQC_post: 6312353358Sdim const FeatureBitset &featureBits = 6313353358Sdim ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits(); 6314353358Sdim 6315353358Sdim if (!featureBits[ARM::HasMVEIntegerOps] && !featureBits[ARM::FeatureVFP2]) 6316353358Sdim return MCDisassembler::Fail; 6317353358Sdim } 6318353358Sdim 6319353358Sdim DecodeStatus S = MCDisassembler::Success; 6320353358Sdim if (unsigned Sysreg = FixedRegForVSTRVLDR_SYSREG(Inst.getOpcode())) 6321353358Sdim Inst.addOperand(MCOperand::createReg(Sysreg)); 6322353358Sdim unsigned Rn = fieldFromInstruction(Val, 16, 4); 6323353358Sdim unsigned addr = fieldFromInstruction(Val, 0, 7) | 6324353358Sdim (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8); 6325353358Sdim 6326353358Sdim if (Writeback) { 6327353358Sdim if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) 6328353358Sdim return MCDisassembler::Fail; 6329353358Sdim } 6330353358Sdim if (!Check(S, DecodeT2AddrModeImm7s4(Inst, addr, Address, Decoder))) 6331353358Sdim return MCDisassembler::Fail; 6332353358Sdim 6333353358Sdim Inst.addOperand(MCOperand::createImm(ARMCC::AL)); 6334353358Sdim Inst.addOperand(MCOperand::createReg(0)); 6335353358Sdim 6336353358Sdim return S; 6337353358Sdim} 6338353358Sdim 6339353358Sdimstatic inline DecodeStatus DecodeMVE_MEM_pre( 6340353358Sdim MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder, 6341353358Sdim unsigned Rn, OperandDecoder RnDecoder, OperandDecoder AddrDecoder) { 6342353358Sdim DecodeStatus S = MCDisassembler::Success; 6343353358Sdim 6344353358Sdim unsigned Qd = fieldFromInstruction(Val, 13, 3); 6345353358Sdim unsigned addr = fieldFromInstruction(Val, 0, 7) | 6346353358Sdim (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8); 6347353358Sdim 6348353358Sdim if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder))) 6349353358Sdim return MCDisassembler::Fail; 6350353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 6351353358Sdim return MCDisassembler::Fail; 6352353358Sdim if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder))) 6353353358Sdim return MCDisassembler::Fail; 6354353358Sdim 6355353358Sdim return S; 6356353358Sdim} 6357353358Sdim 6358353358Sdimtemplate <int shift> 6359353358Sdimstatic DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val, 6360353358Sdim uint64_t Address, const void *Decoder) { 6361353358Sdim return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder, 6362353358Sdim fieldFromInstruction(Val, 16, 3), 6363353358Sdim DecodetGPRRegisterClass, 6364353358Sdim DecodeTAddrModeImm7<shift>); 6365353358Sdim} 6366353358Sdim 6367353358Sdimtemplate <int shift> 6368353358Sdimstatic DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val, 6369353358Sdim uint64_t Address, const void *Decoder) { 6370353358Sdim return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder, 6371353358Sdim fieldFromInstruction(Val, 16, 4), 6372353358Sdim DecoderGPRRegisterClass, 6373353358Sdim DecodeT2AddrModeImm7<shift,1>); 6374353358Sdim} 6375353358Sdim 6376353358Sdimtemplate <int shift> 6377353358Sdimstatic DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val, 6378353358Sdim uint64_t Address, const void *Decoder) { 6379353358Sdim return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder, 6380353358Sdim fieldFromInstruction(Val, 17, 3), 6381353358Sdim DecodeMQPRRegisterClass, 6382353358Sdim DecodeMveAddrModeQ<shift>); 6383353358Sdim} 6384353358Sdim 6385353358Sdimtemplate<unsigned MinLog, unsigned MaxLog> 6386353358Sdimstatic DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val, 6387353358Sdim uint64_t Address, 6388353358Sdim const void *Decoder) { 6389353358Sdim DecodeStatus S = MCDisassembler::Success; 6390353358Sdim 6391353358Sdim if (Val < MinLog || Val > MaxLog) 6392353358Sdim return MCDisassembler::Fail; 6393353358Sdim 6394353358Sdim Inst.addOperand(MCOperand::createImm(1LL << Val)); 6395353358Sdim return S; 6396353358Sdim} 6397353358Sdim 6398353358Sdimtemplate <int shift> 6399353358Sdimstatic DecodeStatus DecodeExpandedImmOperand(MCInst &Inst, unsigned Val, 6400353358Sdim uint64_t Address, 6401353358Sdim const void *Decoder) { 6402353358Sdim Val <<= shift; 6403353358Sdim 6404353358Sdim Inst.addOperand(MCOperand::createImm(Val)); 6405353358Sdim return MCDisassembler::Success; 6406353358Sdim} 6407353358Sdim 6408353358Sdimtemplate<unsigned start> 6409353358Sdimstatic DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, 6410353358Sdim uint64_t Address, 6411353358Sdim const void *Decoder) { 6412353358Sdim DecodeStatus S = MCDisassembler::Success; 6413353358Sdim 6414353358Sdim Inst.addOperand(MCOperand::createImm(start + Val)); 6415353358Sdim 6416353358Sdim return S; 6417353358Sdim} 6418353358Sdim 6419353358Sdimstatic DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn, 6420353358Sdim uint64_t Address, const void *Decoder) { 6421353358Sdim DecodeStatus S = MCDisassembler::Success; 6422353358Sdim unsigned Rt = fieldFromInstruction(Insn, 0, 4); 6423353358Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 6424353358Sdim unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) | 6425353358Sdim fieldFromInstruction(Insn, 13, 3)); 6426353358Sdim unsigned index = fieldFromInstruction(Insn, 4, 1); 6427353358Sdim 6428353358Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 6429353358Sdim return MCDisassembler::Fail; 6430353358Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder))) 6431353358Sdim return MCDisassembler::Fail; 6432353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 6433353358Sdim return MCDisassembler::Fail; 6434353358Sdim if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder))) 6435353358Sdim return MCDisassembler::Fail; 6436353358Sdim if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder))) 6437353358Sdim return MCDisassembler::Fail; 6438353358Sdim 6439353358Sdim return S; 6440353358Sdim} 6441353358Sdim 6442353358Sdimstatic DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn, 6443353358Sdim uint64_t Address, const void *Decoder) { 6444353358Sdim DecodeStatus S = MCDisassembler::Success; 6445353358Sdim unsigned Rt = fieldFromInstruction(Insn, 0, 4); 6446353358Sdim unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); 6447353358Sdim unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) | 6448353358Sdim fieldFromInstruction(Insn, 13, 3)); 6449353358Sdim unsigned index = fieldFromInstruction(Insn, 4, 1); 6450353358Sdim 6451353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 6452353358Sdim return MCDisassembler::Fail; 6453353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 6454353358Sdim return MCDisassembler::Fail; 6455353358Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) 6456353358Sdim return MCDisassembler::Fail; 6457353358Sdim if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder))) 6458353358Sdim return MCDisassembler::Fail; 6459353358Sdim if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder))) 6460353358Sdim return MCDisassembler::Fail; 6461353358Sdim if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder))) 6462353358Sdim return MCDisassembler::Fail; 6463353358Sdim 6464353358Sdim return S; 6465353358Sdim} 6466353358Sdim 6467353358Sdimstatic DecodeStatus DecodeMVEOverlappingLongShift( 6468353358Sdim MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { 6469353358Sdim DecodeStatus S = MCDisassembler::Success; 6470353358Sdim 6471353358Sdim unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1; 6472353358Sdim unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1; 6473353358Sdim unsigned Rm = fieldFromInstruction(Insn, 12, 4); 6474353358Sdim 6475353358Sdim if (RdaHi == 14) { 6476353358Sdim // This value of RdaHi (really indicating pc, because RdaHi has to 6477353358Sdim // be an odd-numbered register, so the low bit will be set by the 6478353358Sdim // decode function below) indicates that we must decode as SQRSHR 6479353358Sdim // or UQRSHL, which both have a single Rda register field with all 6480353358Sdim // four bits. 6481353358Sdim unsigned Rda = fieldFromInstruction(Insn, 16, 4); 6482353358Sdim 6483353358Sdim switch (Inst.getOpcode()) { 6484353358Sdim case ARM::MVE_ASRLr: 6485353358Sdim case ARM::MVE_SQRSHRL: 6486353358Sdim Inst.setOpcode(ARM::MVE_SQRSHR); 6487353358Sdim break; 6488353358Sdim case ARM::MVE_LSLLr: 6489353358Sdim case ARM::MVE_UQRSHLL: 6490353358Sdim Inst.setOpcode(ARM::MVE_UQRSHL); 6491353358Sdim break; 6492353358Sdim default: 6493353358Sdim llvm_unreachable("Unexpected starting opcode!"); 6494353358Sdim } 6495353358Sdim 6496353358Sdim // Rda as output parameter 6497353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder))) 6498353358Sdim return MCDisassembler::Fail; 6499353358Sdim 6500353358Sdim // Rda again as input parameter 6501353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder))) 6502353358Sdim return MCDisassembler::Fail; 6503353358Sdim 6504353358Sdim // Rm, the amount to shift by 6505353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 6506353358Sdim return MCDisassembler::Fail; 6507353358Sdim 6508360784Sdim if (fieldFromInstruction (Insn, 6, 3) != 4) 6509360784Sdim return MCDisassembler::SoftFail; 6510360784Sdim 6511360784Sdim if (Rda == Rm) 6512360784Sdim return MCDisassembler::SoftFail; 6513360784Sdim 6514353358Sdim return S; 6515353358Sdim } 6516353358Sdim 6517353358Sdim // Otherwise, we decode as whichever opcode our caller has already 6518353358Sdim // put into Inst. Those all look the same: 6519353358Sdim 6520353358Sdim // RdaLo,RdaHi as output parameters 6521353358Sdim if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder))) 6522353358Sdim return MCDisassembler::Fail; 6523353358Sdim if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder))) 6524353358Sdim return MCDisassembler::Fail; 6525353358Sdim 6526353358Sdim // RdaLo,RdaHi again as input parameters 6527353358Sdim if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder))) 6528353358Sdim return MCDisassembler::Fail; 6529353358Sdim if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder))) 6530353358Sdim return MCDisassembler::Fail; 6531353358Sdim 6532353358Sdim // Rm, the amount to shift by 6533353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) 6534353358Sdim return MCDisassembler::Fail; 6535353358Sdim 6536360784Sdim if (Inst.getOpcode() == ARM::MVE_SQRSHRL || 6537360784Sdim Inst.getOpcode() == ARM::MVE_UQRSHLL) { 6538360784Sdim unsigned Saturate = fieldFromInstruction(Insn, 7, 1); 6539360784Sdim // Saturate, the bit position for saturation 6540360784Sdim Inst.addOperand(MCOperand::createImm(Saturate)); 6541360784Sdim } 6542360784Sdim 6543353358Sdim return S; 6544353358Sdim} 6545353358Sdim 6546353358Sdimstatic DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn, uint64_t Address, 6547353358Sdim const void *Decoder) { 6548353358Sdim DecodeStatus S = MCDisassembler::Success; 6549353358Sdim unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) | 6550353358Sdim fieldFromInstruction(Insn, 13, 3)); 6551353358Sdim unsigned Qm = ((fieldFromInstruction(Insn, 5, 1) << 3) | 6552353358Sdim fieldFromInstruction(Insn, 1, 3)); 6553353358Sdim unsigned imm6 = fieldFromInstruction(Insn, 16, 6); 6554353358Sdim 6555353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) 6556353358Sdim return MCDisassembler::Fail; 6557353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) 6558353358Sdim return MCDisassembler::Fail; 6559353358Sdim if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder))) 6560353358Sdim return MCDisassembler::Fail; 6561353358Sdim 6562353358Sdim return S; 6563353358Sdim} 6564353358Sdim 6565353358Sdimtemplate<bool scalar, OperandDecoder predicate_decoder> 6566353358Sdimstatic DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address, 6567353358Sdim const void *Decoder) { 6568353358Sdim DecodeStatus S = MCDisassembler::Success; 6569353358Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 6570353358Sdim unsigned Qn = fieldFromInstruction(Insn, 17, 3); 6571353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder))) 6572353358Sdim return MCDisassembler::Fail; 6573353358Sdim 6574353358Sdim unsigned fc; 6575353358Sdim 6576353358Sdim if (scalar) { 6577353358Sdim fc = fieldFromInstruction(Insn, 12, 1) << 2 | 6578353358Sdim fieldFromInstruction(Insn, 7, 1) | 6579353358Sdim fieldFromInstruction(Insn, 5, 1) << 1; 6580353358Sdim unsigned Rm = fieldFromInstruction(Insn, 0, 4); 6581353358Sdim if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder))) 6582353358Sdim return MCDisassembler::Fail; 6583353358Sdim } else { 6584353358Sdim fc = fieldFromInstruction(Insn, 12, 1) << 2 | 6585353358Sdim fieldFromInstruction(Insn, 7, 1) | 6586353358Sdim fieldFromInstruction(Insn, 0, 1) << 1; 6587353358Sdim unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 | 6588353358Sdim fieldFromInstruction(Insn, 1, 3); 6589353358Sdim if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) 6590353358Sdim return MCDisassembler::Fail; 6591353358Sdim } 6592353358Sdim 6593353358Sdim if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder))) 6594353358Sdim return MCDisassembler::Fail; 6595353358Sdim 6596353358Sdim Inst.addOperand(MCOperand::createImm(ARMVCC::None)); 6597353358Sdim Inst.addOperand(MCOperand::createReg(0)); 6598353358Sdim Inst.addOperand(MCOperand::createImm(0)); 6599353358Sdim 6600353358Sdim return S; 6601353358Sdim} 6602353358Sdim 6603353358Sdimstatic DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address, 6604353358Sdim const void *Decoder) { 6605353358Sdim DecodeStatus S = MCDisassembler::Success; 6606353358Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 6607353358Sdim unsigned Rn = fieldFromInstruction(Insn, 16, 4); 6608353358Sdim if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) 6609353358Sdim return MCDisassembler::Fail; 6610353358Sdim return S; 6611353358Sdim} 6612360784Sdim 6613360784Sdimstatic DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn, uint64_t Address, 6614360784Sdim const void *Decoder) { 6615360784Sdim DecodeStatus S = MCDisassembler::Success; 6616360784Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 6617360784Sdim Inst.addOperand(MCOperand::createReg(ARM::VPR)); 6618360784Sdim return S; 6619360784Sdim} 6620360784Sdim 6621360784Sdimstatic DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn, 6622360784Sdim uint64_t Address, const void *Decoder) { 6623360784Sdim const unsigned Rd = fieldFromInstruction(Insn, 8, 4); 6624360784Sdim const unsigned Rn = fieldFromInstruction(Insn, 16, 4); 6625360784Sdim const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 | 6626360784Sdim fieldFromInstruction(Insn, 12, 3) << 8 | 6627360784Sdim fieldFromInstruction(Insn, 0, 8); 6628360784Sdim const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1); 6629360784Sdim unsigned sign1 = fieldFromInstruction(Insn, 21, 1); 6630360784Sdim unsigned sign2 = fieldFromInstruction(Insn, 23, 1); 6631360784Sdim unsigned S = fieldFromInstruction(Insn, 20, 1); 6632360784Sdim if (sign1 != sign2) 6633360784Sdim return MCDisassembler::Fail; 6634360784Sdim 6635360784Sdim // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm) 6636360784Sdim DecodeStatus DS = MCDisassembler::Success; 6637360784Sdim if ((!Check(DS, 6638360784Sdim DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst 6639360784Sdim (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder)))) 6640360784Sdim return MCDisassembler::Fail; 6641360784Sdim if (TypeT3) { 6642360784Sdim Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12); 6643360784Sdim S = 0; 6644360784Sdim Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12 6645360784Sdim } else { 6646360784Sdim Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm); 6647360784Sdim if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12 6648360784Sdim return MCDisassembler::Fail; 6649360784Sdim } 6650360784Sdim if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out 6651360784Sdim return MCDisassembler::Fail; 6652360784Sdim 6653360784Sdim Inst.addOperand(MCOperand::createReg(0)); // pred 6654360784Sdim 6655360784Sdim return DS; 6656360784Sdim} 6657