diff options
Diffstat (limited to 'contrib/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp | 2553 | 
1 files changed, 1270 insertions, 1283 deletions
diff --git a/contrib/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/contrib/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index be4d7f22b2b1..6de27d6d51a5 100644 --- a/contrib/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/contrib/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1,4 +1,4 @@ -//===- AArch64Disassembler.cpp - Disassembler for AArch64 ISA -------------===// +//===- AArch64Disassembler.cpp - Disassembler for AArch64 -------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -7,245 +7,169 @@  //  //===----------------------------------------------------------------------===//  // -// This file contains the functions necessary to decode AArch64 instruction -// bitpatterns into MCInsts (with the help of TableGenerated information from -// the instruction definitions).  //  //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "arm-disassembler" - -#include "AArch64.h" -#include "AArch64RegisterInfo.h" +#include "AArch64Disassembler.h" +#include "AArch64ExternalSymbolizer.h"  #include "AArch64Subtarget.h" +#include "MCTargetDesc/AArch64AddressingModes.h"  #include "Utils/AArch64BaseInfo.h"  #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDisassembler.h"  #include "llvm/MC/MCFixedLenDisassembler.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/MemoryObject.h" -#include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ErrorHandling.h"  using namespace llvm; -typedef MCDisassembler::DecodeStatus DecodeStatus; - -namespace { -/// AArch64 disassembler for all AArch64 platforms. -class AArch64Disassembler : public MCDisassembler { -  OwningPtr<const MCRegisterInfo> RegInfo; -public: -  /// Initializes the disassembler. -  /// -  AArch64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) -    : MCDisassembler(STI), RegInfo(Info) { -  } - -  ~AArch64Disassembler() {} - -  /// See MCDisassembler. -  DecodeStatus getInstruction(MCInst &instr, -                              uint64_t &size, -                              const MemoryObject ®ion, -                              uint64_t address, -                              raw_ostream &vStream, -                              raw_ostream &cStream) const; - -  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } -}; +#define DEBUG_TYPE "aarch64-disassembler" -} - -// Forward-declarations used in the auto-generated files. -static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus -DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder); - -static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus -DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder); +// Pull DecodeStatus and its enum values into the global namespace. +typedef llvm::MCDisassembler::DecodeStatus DecodeStatus; -static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus DecodeFPR64LoRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                         uint64_t Address, const void *Decoder); +// Forward declare these because the autogenerated code will reference them. +// Definitions are further down.  static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,                                                unsigned RegNo, uint64_t Address,                                                const void *Decoder); -static DecodeStatus DecodeFPR128LoRegisterClass(llvm::MCInst &Inst, -                                                unsigned RegNo, uint64_t Address, -                                                const void *Decoder); - -static DecodeStatus DecodeGPR64noxzrRegisterClass(llvm::MCInst &Inst, -                                                  unsigned RegNo, -                                                  uint64_t Address, -                                                  const void *Decoder); - -static DecodeStatus DecodeDPairRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeFPR128_loRegisterClass(llvm::MCInst &Inst, +                                                 unsigned RegNo, +                                                 uint64_t Address, +                                                 const void *Decoder); +static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                               uint64_t Address,                                               const void *Decoder); -static DecodeStatus DecodeQPairRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                               uint64_t Address,                                               const void *Decoder); -static DecodeStatus DecodeDTripleRegisterClass(llvm::MCInst &Inst, -                                               unsigned RegNo, uint64_t Address, -                                               const void *Decoder); -static DecodeStatus DecodeQTripleRegisterClass(llvm::MCInst &Inst, -                                               unsigned RegNo, uint64_t Address, -                                               const void *Decoder); -static DecodeStatus DecodeDQuadRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                               uint64_t Address,                                               const void *Decoder); -static DecodeStatus DecodeQQuadRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, +                                            uint64_t Address, +                                            const void *Decoder); +static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                               uint64_t Address,                                               const void *Decoder); - -static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst, -                                               unsigned OptionHiS, -                                               uint64_t Address, -                                               const void *Decoder); - - -static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst, -                                               unsigned Imm6Bits, -                                               uint64_t Address, +static DecodeStatus DecodeGPR64spRegisterClass(llvm::MCInst &Inst, +                                               unsigned RegNo, uint64_t Address,                                                 const void *Decoder); - -static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst, -                                               unsigned Imm6Bits, -                                               uint64_t Address, +static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo, +                                             uint64_t Address, +                                             const void *Decoder); +static DecodeStatus DecodeGPR32spRegisterClass(llvm::MCInst &Inst, +                                               unsigned RegNo, uint64_t Address,                                                 const void *Decoder); - -static DecodeStatus DecodeFPZeroOperand(llvm::MCInst &Inst, -                                        unsigned RmBits, -                                        uint64_t Address, -                                        const void *Decoder); - -static DecodeStatus DecodeShiftRightImm8(MCInst &Inst, unsigned Val, -                                         uint64_t Address, const void *Decoder); -static DecodeStatus DecodeShiftRightImm16(MCInst &Inst, unsigned Val, +static DecodeStatus DecodeQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                            uint64_t Address,                                            const void *Decoder); -static DecodeStatus DecodeShiftRightImm32(MCInst &Inst, unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder); -static DecodeStatus DecodeShiftRightImm64(MCInst &Inst, unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder); - -static DecodeStatus DecodeShiftLeftImm8(MCInst &Inst, unsigned Val, -                                        uint64_t Address, const void *Decoder); -static DecodeStatus DecodeShiftLeftImm16(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder); -static DecodeStatus DecodeShiftLeftImm32(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder); -static DecodeStatus DecodeShiftLeftImm64(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder); - -template<int RegWidth> -static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst, -                                             unsigned FullImm, -                                             uint64_t Address, -                                             const void *Decoder); - -template<int RegWidth> -static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst, -                                            unsigned Bits, +static DecodeStatus DecodeQQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +                                           uint64_t Address, +                                           const void *Decoder); +static DecodeStatus DecodeQQQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                              uint64_t Address,                                              const void *Decoder); - -static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst, -                                           unsigned ShiftAmount, +static DecodeStatus DecodeDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo, +                                          uint64_t Address, +                                          const void *Decoder); +static DecodeStatus DecodeDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                             uint64_t Address,                                             const void *Decoder); -template <A64SE::ShiftExtSpecifiers Ext, bool IsHalf> -static DecodeStatus -DecodeNeonMovImmShiftOperand(llvm::MCInst &Inst, unsigned ShiftAmount, -                             uint64_t Address, const void *Decoder); - -static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst, -                                            unsigned ShiftAmount, +static DecodeStatus DecodeDDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,                                              uint64_t Address,                                              const void *Decoder); -static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn, + +static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Address, +                                               const void *Decoder); +static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Address, +                                               const void *Decoder); +static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm, +                                       uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemExtend(llvm::MCInst &Inst, unsigned Imm, +                                    uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm, +                                            uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm, +                                            uint64_t Address, const void *Decoder); +static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst, +                                                   uint32_t insn, +                                                   uint64_t Address, +                                                   const void *Decoder); +static DecodeStatus DecodeMoveImmInstruction(llvm::MCInst &Inst, uint32_t insn, +                                             uint64_t Address, +                                             const void *Decoder); +static DecodeStatus DecodeUnsignedLdStInstruction(llvm::MCInst &Inst, +                                                  uint32_t insn, +                                                  uint64_t Address, +                                                  const void *Decoder); +static DecodeStatus DecodeSignedLdStInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Address, +                                                const void *Decoder); +static DecodeStatus DecodeExclusiveLdStInstruction(llvm::MCInst &Inst, +                                                   uint32_t insn, +                                                   uint64_t Address, +                                                   const void *Decoder); +static DecodeStatus DecodePairLdStInstruction(llvm::MCInst &Inst, uint32_t insn,                                                uint64_t Address,                                                const void *Decoder); - -static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeAddSubERegInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Address, +                                                const void *Decoder); +static DecodeStatus DecodeLogicalImmInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Address, +                                                const void *Decoder); +static DecodeStatus DecodeModImmInstruction(llvm::MCInst &Inst, uint32_t insn, +                                            uint64_t Address, +                                            const void *Decoder); +static DecodeStatus DecodeModImmTiedInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Address, +                                                const void *Decoder); +static DecodeStatus DecodeAdrInstruction(llvm::MCInst &Inst, uint32_t insn, +                                         uint64_t Address, const void *Decoder); +static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn, +                                        uint64_t Address, const void *Decoder); +static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn,                                                uint64_t Address,                                                const void *Decoder); +static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst, +                                                  uint32_t insn, +                                                  uint64_t Address, +                                                  const void *Decoder); +static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn, +                                        uint64_t Address, const void *Decoder); -static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst, -                                              unsigned Insn, +static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,                                                uint64_t Address,                                                const void *Decoder); - -static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst, -                                                       unsigned Val, -                                                       uint64_t Address, -                                                       const void *Decoder); - -template<typename SomeNamedImmMapper> -static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst, -                                          unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder); - -static DecodeStatus -DecodeSysRegOperand(const A64SysReg::SysRegMapper &InstMapper, -                    llvm::MCInst &Inst, unsigned Val, -                    uint64_t Address, const void *Decoder); - -static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst, -                                     unsigned Val, -                                     uint64_t Address, -                                     const void *Decoder); - -static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst, -                                     unsigned Val, -                                     uint64_t Address, -                                     const void *Decoder); - - -static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst, -                                                   unsigned Val, -                                                   uint64_t Address, -                                                   const void *Decoder); - -static DecodeStatus DecodeVLDSTPostInstruction(MCInst &Inst, unsigned Val, -                                               uint64_t Address, +static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr,                                                 const void *Decoder); - -static DecodeStatus DecodeVLDSTLanePostInstruction(MCInst &Inst, unsigned Insn, -                                                   uint64_t Address, -                                                   const void *Decoder); - -static DecodeStatus DecodeSHLLInstruction(MCInst &Inst, unsigned Insn, -                                          uint64_t Address, -                                          const void *Decoder); - -static bool Check(DecodeStatus &Out, DecodeStatus In); - -#include "AArch64GenDisassemblerTables.inc" -#include "AArch64GenInstrInfo.inc" +static DecodeStatus DecodeVecShiftR32Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftR32ImmNarrow(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder); +static DecodeStatus DecodeVecShiftR16Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftR16ImmNarrow(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder); +static DecodeStatus DecodeVecShiftR8Imm(llvm::MCInst &Inst, unsigned Imm, +                                        uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftL64Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftL32Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftL16Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeVecShiftL8Imm(llvm::MCInst &Inst, unsigned Imm, +                                        uint64_t Addr, const void *Decoder);  static bool Check(DecodeStatus &Out, DecodeStatus In) {    switch (In) { @@ -262,486 +186,479 @@ static bool Check(DecodeStatus &Out, DecodeStatus In) {    llvm_unreachable("Invalid DecodeStatus!");  } +#include "AArch64GenDisassemblerTables.inc" +#include "AArch64GenInstrInfo.inc" + +#define Success llvm::MCDisassembler::Success +#define Fail llvm::MCDisassembler::Fail +#define SoftFail llvm::MCDisassembler::SoftFail + +static MCDisassembler *createAArch64Disassembler(const Target &T, +                                               const MCSubtargetInfo &STI, +                                               MCContext &Ctx) { +  return new AArch64Disassembler(STI, Ctx); +} +  DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size, -                                                 const MemoryObject &Region, -                                                 uint64_t Address, -                                                 raw_ostream &os, -                                                 raw_ostream &cs) const { +                                               const MemoryObject &Region, +                                               uint64_t Address, +                                               raw_ostream &os, +                                               raw_ostream &cs) const {    CommentStream = &cs;    uint8_t bytes[4]; +  Size = 0;    // We want to read exactly 4 bytes of data. -  if (Region.readBytes(Address, 4, bytes) == -1) { -    Size = 0; -    return MCDisassembler::Fail; -  } +  if (Region.readBytes(Address, 4, (uint8_t *)bytes) == -1) +    return Fail; +  Size = 4;    // Encoded as a small-endian 32-bit word in the stream. -  uint32_t insn = (bytes[3] << 24) | -    (bytes[2] << 16) | -    (bytes[1] <<  8) | -    (bytes[0] <<  0); +  uint32_t insn = +      (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0] << 0);    // Calling the auto-generated decoder function. -  DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address, -                                          this, STI); -  if (result != MCDisassembler::Fail) { -    Size = 4; -    return result; -  } - -  MI.clear(); -  Size = 0; -  return MCDisassembler::Fail; +  return decodeInstruction(DecoderTable32, MI, insn, Address, this, STI);  } -static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { -  const AArch64Disassembler *Dis = static_cast<const AArch64Disassembler*>(D); -  return Dis->getRegInfo()->getRegClass(RC).getRegister(RegNo); +static MCSymbolizer * +createAArch64ExternalSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, +                              LLVMSymbolLookupCallback SymbolLookUp, +                              void *DisInfo, MCContext *Ctx, +                              MCRelocationInfo *RelInfo) { +  return new llvm::AArch64ExternalSymbolizer( +                                     *Ctx, +                                     std::unique_ptr<MCRelocationInfo>(RelInfo), +                                     GetOpInfo, SymbolLookUp, DisInfo);  } -static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                        uint64_t Address, const void *Decoder) { -  if (RegNo > 31) -    return MCDisassembler::Fail; +extern "C" void LLVMInitializeAArch64Disassembler() { +  TargetRegistry::RegisterMCDisassembler(TheAArch64leTarget, +                                         createAArch64Disassembler); +  TargetRegistry::RegisterMCDisassembler(TheAArch64beTarget, +                                         createAArch64Disassembler); +  TargetRegistry::RegisterMCSymbolizer(TheAArch64leTarget, +                                       createAArch64ExternalSymbolizer); +  TargetRegistry::RegisterMCSymbolizer(TheAArch64beTarget, +                                       createAArch64ExternalSymbolizer); -  uint16_t Register = getReg(Decoder, AArch64::GPR64RegClassID, RegNo); -  Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  TargetRegistry::RegisterMCDisassembler(TheARM64leTarget, +                                         createAArch64Disassembler); +  TargetRegistry::RegisterMCDisassembler(TheARM64beTarget, +                                         createAArch64Disassembler); +  TargetRegistry::RegisterMCSymbolizer(TheARM64leTarget, +                                       createAArch64ExternalSymbolizer); +  TargetRegistry::RegisterMCSymbolizer(TheARM64beTarget, +                                       createAArch64ExternalSymbolizer);  } -static DecodeStatus -DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { -  if (RegNo > 31) -    return MCDisassembler::Fail; - -  uint16_t Register = getReg(Decoder, AArch64::GPR64xspRegClassID, RegNo); -  Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; -} +static const unsigned FPR128DecoderTable[] = { +    AArch64::Q0,  AArch64::Q1,  AArch64::Q2,  AArch64::Q3,  AArch64::Q4, +    AArch64::Q5,  AArch64::Q6,  AArch64::Q7,  AArch64::Q8,  AArch64::Q9, +    AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14, +    AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19, +    AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24, +    AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29, +    AArch64::Q30, AArch64::Q31 +}; -static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                             uint64_t Address, -                                             const void *Decoder) { +static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo, +                                              uint64_t Addr, +                                              const void *Decoder) {    if (RegNo > 31) -    return MCDisassembler::Fail; +    return Fail; -  uint16_t Register = getReg(Decoder, AArch64::GPR32RegClassID, RegNo); +  unsigned Register = FPR128DecoderTable[RegNo];    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } -static DecodeStatus -DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { -  if (RegNo > 31) -    return MCDisassembler::Fail; - -  uint16_t Register = getReg(Decoder, AArch64::GPR32wspRegClassID, RegNo); -  Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, +                                                 uint64_t Addr, +                                                 const void *Decoder) { +  if (RegNo > 15) +    return Fail; +  return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);  } -static DecodeStatus -DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { -  if (RegNo > 31) -    return MCDisassembler::Fail; - -  uint16_t Register = getReg(Decoder, AArch64::FPR8RegClassID, RegNo); -  Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; -} +static const unsigned FPR64DecoderTable[] = { +    AArch64::D0,  AArch64::D1,  AArch64::D2,  AArch64::D3,  AArch64::D4, +    AArch64::D5,  AArch64::D6,  AArch64::D7,  AArch64::D8,  AArch64::D9, +    AArch64::D10, AArch64::D11, AArch64::D12, AArch64::D13, AArch64::D14, +    AArch64::D15, AArch64::D16, AArch64::D17, AArch64::D18, AArch64::D19, +    AArch64::D20, AArch64::D21, AArch64::D22, AArch64::D23, AArch64::D24, +    AArch64::D25, AArch64::D26, AArch64::D27, AArch64::D28, AArch64::D29, +    AArch64::D30, AArch64::D31 +}; -static DecodeStatus -DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { +static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo, +                                             uint64_t Addr, +                                             const void *Decoder) {    if (RegNo > 31) -    return MCDisassembler::Fail; +    return Fail; -  uint16_t Register = getReg(Decoder, AArch64::FPR16RegClassID, RegNo); +  unsigned Register = FPR64DecoderTable[RegNo];    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } +static const unsigned FPR32DecoderTable[] = { +    AArch64::S0,  AArch64::S1,  AArch64::S2,  AArch64::S3,  AArch64::S4, +    AArch64::S5,  AArch64::S6,  AArch64::S7,  AArch64::S8,  AArch64::S9, +    AArch64::S10, AArch64::S11, AArch64::S12, AArch64::S13, AArch64::S14, +    AArch64::S15, AArch64::S16, AArch64::S17, AArch64::S18, AArch64::S19, +    AArch64::S20, AArch64::S21, AArch64::S22, AArch64::S23, AArch64::S24, +    AArch64::S25, AArch64::S26, AArch64::S27, AArch64::S28, AArch64::S29, +    AArch64::S30, AArch64::S31 +}; -static DecodeStatus -DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { +static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo, +                                             uint64_t Addr, +                                             const void *Decoder) {    if (RegNo > 31) -    return MCDisassembler::Fail; +    return Fail; -  uint16_t Register = getReg(Decoder, AArch64::FPR32RegClassID, RegNo); +  unsigned Register = FPR32DecoderTable[RegNo];    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } -static DecodeStatus -DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { +static const unsigned FPR16DecoderTable[] = { +    AArch64::H0,  AArch64::H1,  AArch64::H2,  AArch64::H3,  AArch64::H4, +    AArch64::H5,  AArch64::H6,  AArch64::H7,  AArch64::H8,  AArch64::H9, +    AArch64::H10, AArch64::H11, AArch64::H12, AArch64::H13, AArch64::H14, +    AArch64::H15, AArch64::H16, AArch64::H17, AArch64::H18, AArch64::H19, +    AArch64::H20, AArch64::H21, AArch64::H22, AArch64::H23, AArch64::H24, +    AArch64::H25, AArch64::H26, AArch64::H27, AArch64::H28, AArch64::H29, +    AArch64::H30, AArch64::H31 +}; + +static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo, +                                             uint64_t Addr, +                                             const void *Decoder) {    if (RegNo > 31) -    return MCDisassembler::Fail; +    return Fail; -  uint16_t Register = getReg(Decoder, AArch64::FPR64RegClassID, RegNo); +  unsigned Register = FPR16DecoderTable[RegNo];    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } -static DecodeStatus -DecodeFPR64LoRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { -  if (RegNo > 15) -    return MCDisassembler::Fail; - -  return DecodeFPR64RegisterClass(Inst, RegNo, Address, Decoder); -} +static const unsigned FPR8DecoderTable[] = { +    AArch64::B0,  AArch64::B1,  AArch64::B2,  AArch64::B3,  AArch64::B4, +    AArch64::B5,  AArch64::B6,  AArch64::B7,  AArch64::B8,  AArch64::B9, +    AArch64::B10, AArch64::B11, AArch64::B12, AArch64::B13, AArch64::B14, +    AArch64::B15, AArch64::B16, AArch64::B17, AArch64::B18, AArch64::B19, +    AArch64::B20, AArch64::B21, AArch64::B22, AArch64::B23, AArch64::B24, +    AArch64::B25, AArch64::B26, AArch64::B27, AArch64::B28, AArch64::B29, +    AArch64::B30, AArch64::B31 +}; -static DecodeStatus -DecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { +static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo, +                                            uint64_t Addr, +                                            const void *Decoder) {    if (RegNo > 31) -    return MCDisassembler::Fail; +    return Fail; -  uint16_t Register = getReg(Decoder, AArch64::FPR128RegClassID, RegNo); +  unsigned Register = FPR8DecoderTable[RegNo];    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } -static DecodeStatus -DecodeFPR128LoRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                            uint64_t Address, const void *Decoder) { -  if (RegNo > 15) -    return MCDisassembler::Fail; - -  return DecodeFPR128RegisterClass(Inst, RegNo, Address, Decoder); -} +static const unsigned GPR64DecoderTable[] = { +    AArch64::X0,  AArch64::X1,  AArch64::X2,  AArch64::X3,  AArch64::X4, +    AArch64::X5,  AArch64::X6,  AArch64::X7,  AArch64::X8,  AArch64::X9, +    AArch64::X10, AArch64::X11, AArch64::X12, AArch64::X13, AArch64::X14, +    AArch64::X15, AArch64::X16, AArch64::X17, AArch64::X18, AArch64::X19, +    AArch64::X20, AArch64::X21, AArch64::X22, AArch64::X23, AArch64::X24, +    AArch64::X25, AArch64::X26, AArch64::X27, AArch64::X28, AArch64::FP, +    AArch64::LR,  AArch64::XZR +}; -static DecodeStatus DecodeGPR64noxzrRegisterClass(llvm::MCInst &Inst, -                                                  unsigned RegNo, -                                                  uint64_t Address, -                                                  const void *Decoder) { -  if (RegNo > 30) -    return MCDisassembler::Fail; +static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo, +                                             uint64_t Addr, +                                             const void *Decoder) { +  if (RegNo > 31) +    return Fail; -  uint16_t Register = getReg(Decoder, AArch64::GPR64noxzrRegClassID, RegNo); +  unsigned Register = GPR64DecoderTable[RegNo];    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } -static DecodeStatus DecodeRegisterClassByID(llvm::MCInst &Inst, unsigned RegNo, -                                            unsigned RegID, -                                            const void *Decoder) { +static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo, +                                               uint64_t Addr, +                                               const void *Decoder) {    if (RegNo > 31) -    return MCDisassembler::Fail; - -  uint16_t Register = getReg(Decoder, RegID, RegNo); +    return Fail; +  unsigned Register = GPR64DecoderTable[RegNo]; +  if (Register == AArch64::XZR) +    Register = AArch64::SP;    Inst.addOperand(MCOperand::CreateReg(Register)); -  return MCDisassembler::Success; +  return Success;  } -static DecodeStatus DecodeDPairRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                             uint64_t Address, -                                             const void *Decoder) { -  return DecodeRegisterClassByID(Inst, RegNo, AArch64::DPairRegClassID, -                                 Decoder); -} +static const unsigned GPR32DecoderTable[] = { +    AArch64::W0,  AArch64::W1,  AArch64::W2,  AArch64::W3,  AArch64::W4, +    AArch64::W5,  AArch64::W6,  AArch64::W7,  AArch64::W8,  AArch64::W9, +    AArch64::W10, AArch64::W11, AArch64::W12, AArch64::W13, AArch64::W14, +    AArch64::W15, AArch64::W16, AArch64::W17, AArch64::W18, AArch64::W19, +    AArch64::W20, AArch64::W21, AArch64::W22, AArch64::W23, AArch64::W24, +    AArch64::W25, AArch64::W26, AArch64::W27, AArch64::W28, AArch64::W29, +    AArch64::W30, AArch64::WZR +}; -static DecodeStatus DecodeQPairRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                             uint64_t Address, +static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, +                                             uint64_t Addr,                                               const void *Decoder) { -  return DecodeRegisterClassByID(Inst, RegNo, AArch64::QPairRegClassID, -                                 Decoder); -} +  if (RegNo > 31) +    return Fail; -static DecodeStatus DecodeDTripleRegisterClass(llvm::MCInst &Inst, -                                               unsigned RegNo, uint64_t Address, -                                               const void *Decoder) { -  return DecodeRegisterClassByID(Inst, RegNo, AArch64::DTripleRegClassID, -                                 Decoder); +  unsigned Register = GPR32DecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeQTripleRegisterClass(llvm::MCInst &Inst, -                                               unsigned RegNo, uint64_t Address, +static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo, +                                               uint64_t Addr,                                                 const void *Decoder) { -  return DecodeRegisterClassByID(Inst, RegNo, AArch64::QTripleRegClassID, -                                 Decoder); -} +  if (RegNo > 31) +    return Fail; -static DecodeStatus DecodeDQuadRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                             uint64_t Address, -                                             const void *Decoder) { -  return DecodeRegisterClassByID(Inst, RegNo, AArch64::DQuadRegClassID, -                                 Decoder); +  unsigned Register = GPR32DecoderTable[RegNo]; +  if (Register == AArch64::WZR) +    Register = AArch64::WSP; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeQQuadRegisterClass(llvm::MCInst &Inst, unsigned RegNo, -                                             uint64_t Address, -                                             const void *Decoder) { -  return DecodeRegisterClassByID(Inst, RegNo, AArch64::QQuadRegClassID, -                                 Decoder); -} +static const unsigned VectorDecoderTable[] = { +    AArch64::Q0,  AArch64::Q1,  AArch64::Q2,  AArch64::Q3,  AArch64::Q4, +    AArch64::Q5,  AArch64::Q6,  AArch64::Q7,  AArch64::Q8,  AArch64::Q9, +    AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14, +    AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19, +    AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24, +    AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29, +    AArch64::Q30, AArch64::Q31 +}; -static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst, -                                               unsigned OptionHiS, -                                               uint64_t Address, -                                               const void *Decoder) { -  // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1}, -  // S}. Hence we want to check bit 1. -  if (!(OptionHiS & 2)) -    return MCDisassembler::Fail; +static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, unsigned RegNo, +                                              uint64_t Addr, +                                              const void *Decoder) { +  if (RegNo > 31) +    return Fail; -  Inst.addOperand(MCOperand::CreateImm(OptionHiS)); -  return MCDisassembler::Success; +  unsigned Register = VectorDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst, -                                               unsigned Imm6Bits, -                                               uint64_t Address, -                                               const void *Decoder) { -  // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be -  // between 0 and 31. -  if (Imm6Bits > 31) -    return MCDisassembler::Fail; +static const unsigned QQDecoderTable[] = { +  AArch64::Q0_Q1,   AArch64::Q1_Q2,   AArch64::Q2_Q3,   AArch64::Q3_Q4, +  AArch64::Q4_Q5,   AArch64::Q5_Q6,   AArch64::Q6_Q7,   AArch64::Q7_Q8, +  AArch64::Q8_Q9,   AArch64::Q9_Q10,  AArch64::Q10_Q11, AArch64::Q11_Q12, +  AArch64::Q12_Q13, AArch64::Q13_Q14, AArch64::Q14_Q15, AArch64::Q15_Q16, +  AArch64::Q16_Q17, AArch64::Q17_Q18, AArch64::Q18_Q19, AArch64::Q19_Q20, +  AArch64::Q20_Q21, AArch64::Q21_Q22, AArch64::Q22_Q23, AArch64::Q23_Q24, +  AArch64::Q24_Q25, AArch64::Q25_Q26, AArch64::Q26_Q27, AArch64::Q27_Q28, +  AArch64::Q28_Q29, AArch64::Q29_Q30, AArch64::Q30_Q31, AArch64::Q31_Q0 +}; -  Inst.addOperand(MCOperand::CreateImm(Imm6Bits)); -  return MCDisassembler::Success; +static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo, +                                          uint64_t Addr, const void *Decoder) { +  if (RegNo > 31) +    return Fail; +  unsigned Register = QQDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst, -                                               unsigned Imm6Bits, -                                               uint64_t Address, -                                               const void *Decoder) { -  // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32. -  if (Imm6Bits < 32) -    return MCDisassembler::Fail; - -  Inst.addOperand(MCOperand::CreateImm(Imm6Bits)); -  return MCDisassembler::Success; -} +static const unsigned QQQDecoderTable[] = { +  AArch64::Q0_Q1_Q2,    AArch64::Q1_Q2_Q3,    AArch64::Q2_Q3_Q4, +  AArch64::Q3_Q4_Q5,    AArch64::Q4_Q5_Q6,    AArch64::Q5_Q6_Q7, +  AArch64::Q6_Q7_Q8,    AArch64::Q7_Q8_Q9,    AArch64::Q8_Q9_Q10, +  AArch64::Q9_Q10_Q11,  AArch64::Q10_Q11_Q12, AArch64::Q11_Q12_Q13, +  AArch64::Q12_Q13_Q14, AArch64::Q13_Q14_Q15, AArch64::Q14_Q15_Q16, +  AArch64::Q15_Q16_Q17, AArch64::Q16_Q17_Q18, AArch64::Q17_Q18_Q19, +  AArch64::Q18_Q19_Q20, AArch64::Q19_Q20_Q21, AArch64::Q20_Q21_Q22, +  AArch64::Q21_Q22_Q23, AArch64::Q22_Q23_Q24, AArch64::Q23_Q24_Q25, +  AArch64::Q24_Q25_Q26, AArch64::Q25_Q26_Q27, AArch64::Q26_Q27_Q28, +  AArch64::Q27_Q28_Q29, AArch64::Q28_Q29_Q30, AArch64::Q29_Q30_Q31, +  AArch64::Q30_Q31_Q0,  AArch64::Q31_Q0_Q1 +}; -static DecodeStatus DecodeFPZeroOperand(llvm::MCInst &Inst, -                                        unsigned RmBits, -                                        uint64_t Address, -                                        const void *Decoder) { -  // Any bits are valid in the instruction (they're architecturally ignored), -  // but a code generator should insert 0. -  Inst.addOperand(MCOperand::CreateImm(0)); -  return MCDisassembler::Success; +static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo, +                                           uint64_t Addr, const void *Decoder) { +  if (RegNo > 31) +    return Fail; +  unsigned Register = QQQDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeShiftRightImm8(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder) { -  Inst.addOperand(MCOperand::CreateImm(8 - Val)); -  return MCDisassembler::Success; -} +static const unsigned QQQQDecoderTable[] = { +  AArch64::Q0_Q1_Q2_Q3,     AArch64::Q1_Q2_Q3_Q4,     AArch64::Q2_Q3_Q4_Q5, +  AArch64::Q3_Q4_Q5_Q6,     AArch64::Q4_Q5_Q6_Q7,     AArch64::Q5_Q6_Q7_Q8, +  AArch64::Q6_Q7_Q8_Q9,     AArch64::Q7_Q8_Q9_Q10,    AArch64::Q8_Q9_Q10_Q11, +  AArch64::Q9_Q10_Q11_Q12,  AArch64::Q10_Q11_Q12_Q13, AArch64::Q11_Q12_Q13_Q14, +  AArch64::Q12_Q13_Q14_Q15, AArch64::Q13_Q14_Q15_Q16, AArch64::Q14_Q15_Q16_Q17, +  AArch64::Q15_Q16_Q17_Q18, AArch64::Q16_Q17_Q18_Q19, AArch64::Q17_Q18_Q19_Q20, +  AArch64::Q18_Q19_Q20_Q21, AArch64::Q19_Q20_Q21_Q22, AArch64::Q20_Q21_Q22_Q23, +  AArch64::Q21_Q22_Q23_Q24, AArch64::Q22_Q23_Q24_Q25, AArch64::Q23_Q24_Q25_Q26, +  AArch64::Q24_Q25_Q26_Q27, AArch64::Q25_Q26_Q27_Q28, AArch64::Q26_Q27_Q28_Q29, +  AArch64::Q27_Q28_Q29_Q30, AArch64::Q28_Q29_Q30_Q31, AArch64::Q29_Q30_Q31_Q0, +  AArch64::Q30_Q31_Q0_Q1,   AArch64::Q31_Q0_Q1_Q2 +}; -static DecodeStatus DecodeShiftRightImm16(MCInst &Inst, unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder) { -  Inst.addOperand(MCOperand::CreateImm(16 - Val)); -  return MCDisassembler::Success; +static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo, +                                            uint64_t Addr, +                                            const void *Decoder) { +  if (RegNo > 31) +    return Fail; +  unsigned Register = QQQQDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeShiftRightImm32(MCInst &Inst, unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder) { -  Inst.addOperand(MCOperand::CreateImm(32 - Val)); -  return MCDisassembler::Success; -} +static const unsigned DDDecoderTable[] = { +  AArch64::D0_D1,   AArch64::D1_D2,   AArch64::D2_D3,   AArch64::D3_D4, +  AArch64::D4_D5,   AArch64::D5_D6,   AArch64::D6_D7,   AArch64::D7_D8, +  AArch64::D8_D9,   AArch64::D9_D10,  AArch64::D10_D11, AArch64::D11_D12, +  AArch64::D12_D13, AArch64::D13_D14, AArch64::D14_D15, AArch64::D15_D16, +  AArch64::D16_D17, AArch64::D17_D18, AArch64::D18_D19, AArch64::D19_D20, +  AArch64::D20_D21, AArch64::D21_D22, AArch64::D22_D23, AArch64::D23_D24, +  AArch64::D24_D25, AArch64::D25_D26, AArch64::D26_D27, AArch64::D27_D28, +  AArch64::D28_D29, AArch64::D29_D30, AArch64::D30_D31, AArch64::D31_D0 +}; -static DecodeStatus DecodeShiftRightImm64(MCInst &Inst, unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder) { -  Inst.addOperand(MCOperand::CreateImm(64 - Val)); -  return MCDisassembler::Success; +static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo, +                                          uint64_t Addr, const void *Decoder) { +  if (RegNo > 31) +    return Fail; +  unsigned Register = DDDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeShiftLeftImm8(MCInst &Inst, unsigned Val, -                                        uint64_t Address, -                                        const void *Decoder) { -  if (Val > 7) -    return MCDisassembler::Fail; +static const unsigned DDDDecoderTable[] = { +  AArch64::D0_D1_D2,    AArch64::D1_D2_D3,    AArch64::D2_D3_D4, +  AArch64::D3_D4_D5,    AArch64::D4_D5_D6,    AArch64::D5_D6_D7, +  AArch64::D6_D7_D8,    AArch64::D7_D8_D9,    AArch64::D8_D9_D10, +  AArch64::D9_D10_D11,  AArch64::D10_D11_D12, AArch64::D11_D12_D13, +  AArch64::D12_D13_D14, AArch64::D13_D14_D15, AArch64::D14_D15_D16, +  AArch64::D15_D16_D17, AArch64::D16_D17_D18, AArch64::D17_D18_D19, +  AArch64::D18_D19_D20, AArch64::D19_D20_D21, AArch64::D20_D21_D22, +  AArch64::D21_D22_D23, AArch64::D22_D23_D24, AArch64::D23_D24_D25, +  AArch64::D24_D25_D26, AArch64::D25_D26_D27, AArch64::D26_D27_D28, +  AArch64::D27_D28_D29, AArch64::D28_D29_D30, AArch64::D29_D30_D31, +  AArch64::D30_D31_D0,  AArch64::D31_D0_D1 +}; -  Inst.addOperand(MCOperand::CreateImm(Val)); -  return MCDisassembler::Success; +static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo, +                                           uint64_t Addr, const void *Decoder) { +  if (RegNo > 31) +    return Fail; +  unsigned Register = DDDDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeShiftLeftImm16(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder) { -  if (Val > 15) -    return MCDisassembler::Fail; +static const unsigned DDDDDecoderTable[] = { +  AArch64::D0_D1_D2_D3,     AArch64::D1_D2_D3_D4,     AArch64::D2_D3_D4_D5, +  AArch64::D3_D4_D5_D6,     AArch64::D4_D5_D6_D7,     AArch64::D5_D6_D7_D8, +  AArch64::D6_D7_D8_D9,     AArch64::D7_D8_D9_D10,    AArch64::D8_D9_D10_D11, +  AArch64::D9_D10_D11_D12,  AArch64::D10_D11_D12_D13, AArch64::D11_D12_D13_D14, +  AArch64::D12_D13_D14_D15, AArch64::D13_D14_D15_D16, AArch64::D14_D15_D16_D17, +  AArch64::D15_D16_D17_D18, AArch64::D16_D17_D18_D19, AArch64::D17_D18_D19_D20, +  AArch64::D18_D19_D20_D21, AArch64::D19_D20_D21_D22, AArch64::D20_D21_D22_D23, +  AArch64::D21_D22_D23_D24, AArch64::D22_D23_D24_D25, AArch64::D23_D24_D25_D26, +  AArch64::D24_D25_D26_D27, AArch64::D25_D26_D27_D28, AArch64::D26_D27_D28_D29, +  AArch64::D27_D28_D29_D30, AArch64::D28_D29_D30_D31, AArch64::D29_D30_D31_D0, +  AArch64::D30_D31_D0_D1,   AArch64::D31_D0_D1_D2 +}; -  Inst.addOperand(MCOperand::CreateImm(Val)); -  return MCDisassembler::Success; +static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo, +                                            uint64_t Addr, +                                            const void *Decoder) { +  if (RegNo > 31) +    return Fail; +  unsigned Register = DDDDDecoderTable[RegNo]; +  Inst.addOperand(MCOperand::CreateReg(Register)); +  return Success;  } -static DecodeStatus DecodeShiftLeftImm32(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder) { -  if (Val > 31) -    return MCDisassembler::Fail; - -  Inst.addOperand(MCOperand::CreateImm(Val)); -  return MCDisassembler::Success; +static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder) { +  // scale{5} is asserted as 1 in tblgen. +  Imm |= 0x20;   +  Inst.addOperand(MCOperand::CreateImm(64 - Imm)); +  return Success;  } -static DecodeStatus DecodeShiftLeftImm64(MCInst &Inst, unsigned Val, -                                         uint64_t Address, -                                         const void *Decoder) { -  if (Val > 63) -    return MCDisassembler::Fail; - -  Inst.addOperand(MCOperand::CreateImm(Val)); -  return MCDisassembler::Success; +static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder) { +  Inst.addOperand(MCOperand::CreateImm(64 - Imm)); +  return Success;  } -template<int RegWidth> -static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst, -                                             unsigned FullImm, -                                             uint64_t Address, -                                             const void *Decoder) { -  unsigned Imm16 = FullImm & 0xffff; -  unsigned Shift = FullImm >> 16; +static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm, +                                       uint64_t Addr, const void *Decoder) { +  int64_t ImmVal = Imm; +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); + +  // Sign-extend 19-bit immediate. +  if (ImmVal & (1 << (19 - 1))) +    ImmVal |= ~((1LL << 19) - 1); -  if (RegWidth == 32 && Shift > 1) return MCDisassembler::Fail; +  if (!Dis->tryAddingSymbolicOperand(Inst, ImmVal << 2, Addr, +                                     Inst.getOpcode() != AArch64::LDRXl, 0, 4)) +    Inst.addOperand(MCOperand::CreateImm(ImmVal)); +  return Success; +} -  Inst.addOperand(MCOperand::CreateImm(Imm16)); -  Inst.addOperand(MCOperand::CreateImm(Shift)); -  return MCDisassembler::Success; +static DecodeStatus DecodeMemExtend(llvm::MCInst &Inst, unsigned Imm, +                                    uint64_t Address, const void *Decoder) { +  Inst.addOperand(MCOperand::CreateImm((Imm  >> 1) & 1)); +  Inst.addOperand(MCOperand::CreateImm(Imm & 1)); +  return Success;  } -template<int RegWidth> -static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst, -                                            unsigned Bits, +static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,                                              uint64_t Address,                                              const void *Decoder) { -  uint64_t Imm; -  if (!A64Imms::isLogicalImmBits(RegWidth, Bits, Imm)) -    return MCDisassembler::Fail; - -  Inst.addOperand(MCOperand::CreateImm(Bits)); -  return MCDisassembler::Success; -} +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); +  const MCSubtargetInfo &STI = Dis->getSubtargetInfo(); +  Imm |= 0x8000; +  Inst.addOperand(MCOperand::CreateImm(Imm)); -static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst, -                                           unsigned ShiftAmount, -                                           uint64_t Address, -                                           const void *Decoder) { -  // Only values 0-4 are valid for this 3-bit field -  if (ShiftAmount > 4) -    return MCDisassembler::Fail; +  bool ValidNamed; +  (void)AArch64SysReg::MRSMapper(STI.getFeatureBits()) +      .toString(Imm, ValidNamed); -  Inst.addOperand(MCOperand::CreateImm(ShiftAmount)); -  return MCDisassembler::Success; +  return ValidNamed ? Success : Fail;  } -static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst, -                                            unsigned ShiftAmount, +static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,                                              uint64_t Address,                                              const void *Decoder) { -  // Only values below 32 are valid for a 32-bit register -  if (ShiftAmount > 31) -    return MCDisassembler::Fail; +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); +  const MCSubtargetInfo &STI = Dis->getSubtargetInfo(); -  Inst.addOperand(MCOperand::CreateImm(ShiftAmount)); -  return MCDisassembler::Success; -} +  Imm |= 0x8000; +  Inst.addOperand(MCOperand::CreateImm(Imm)); -static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn, -                                              uint64_t Address, -                                              const void *Decoder) { -  unsigned Rd = fieldFromInstruction(Insn, 0, 5); -  unsigned Rn = fieldFromInstruction(Insn, 5, 5); -  unsigned ImmS = fieldFromInstruction(Insn, 10, 6); -  unsigned ImmR = fieldFromInstruction(Insn, 16, 6); -  unsigned SF = fieldFromInstruction(Insn, 31, 1); - -  // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise -  // out assertions that it thinks should never be hit. -  enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc; -  Opc = (OpcTypes)fieldFromInstruction(Insn, 29, 2); - -  if (!SF) { -    // ImmR and ImmS must be between 0 and 31 for 32-bit instructions. -    if (ImmR > 31 || ImmS > 31) -      return MCDisassembler::Fail; -  } - -  if (SF) { -    DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder); -    // BFM MCInsts use Rd as a source too. -    if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder); -    DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder); -  } else { -    DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder); -    // BFM MCInsts use Rd as a source too. -    if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder); -    DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder); -  } - -  // ASR and LSR have more specific patterns so they won't get here: -  assert(!(ImmS == 31 && !SF && Opc != BFM) -         && "shift should have used auto decode"); -  assert(!(ImmS == 63 && SF && Opc != BFM) -         && "shift should have used auto decode"); - -  // Extension instructions similarly: -  if (Opc == SBFM && ImmR == 0) { -    assert((ImmS != 7 && ImmS != 15) && "extension got here"); -    assert((ImmS != 31 || SF == 0) && "extension got here"); -  } else if (Opc == UBFM && ImmR == 0) { -    assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here"); -  } - -  if (Opc == UBFM) { -    // It might be a LSL instruction, which actually takes the shift amount -    // itself as an MCInst operand. -    if (SF && (ImmS + 1) % 64 == ImmR) { -      Inst.setOpcode(AArch64::LSLxxi); -      Inst.addOperand(MCOperand::CreateImm(63 - ImmS)); -      return MCDisassembler::Success; -    } else if (!SF && (ImmS + 1) % 32 == ImmR) { -      Inst.setOpcode(AArch64::LSLwwi); -      Inst.addOperand(MCOperand::CreateImm(31 - ImmS)); -      return MCDisassembler::Success; -    } -  } - -  // Otherwise it's definitely either an extract or an insert depending on which -  // of ImmR or ImmS is larger. -  unsigned ExtractOp, InsertOp; -  switch (Opc) { -  default: llvm_unreachable("unexpected instruction trying to decode bitfield"); -  case SBFM: -    ExtractOp = SF ? AArch64::SBFXxxii : AArch64::SBFXwwii; -    InsertOp = SF ? AArch64::SBFIZxxii : AArch64::SBFIZwwii; -    break; -  case BFM: -    ExtractOp = SF ? AArch64::BFXILxxii : AArch64::BFXILwwii; -    InsertOp = SF ? AArch64::BFIxxii : AArch64::BFIwwii; -    break; -  case UBFM: -    ExtractOp = SF ? AArch64::UBFXxxii : AArch64::UBFXwwii; -    InsertOp = SF ? AArch64::UBFIZxxii : AArch64::UBFIZwwii; -    break; -  } - -  // Otherwise it's a boring insert or extract -  Inst.addOperand(MCOperand::CreateImm(ImmR)); -  Inst.addOperand(MCOperand::CreateImm(ImmS)); - - -  if (ImmS < ImmR) -    Inst.setOpcode(InsertOp); -  else -    Inst.setOpcode(ExtractOp); +  bool ValidNamed; +  (void)AArch64SysReg::MSRMapper(STI.getFeatureBits()) +      .toString(Imm, ValidNamed); -  return MCDisassembler::Success; +  return ValidNamed ? Success : Fail;  }  static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn, @@ -764,809 +681,879 @@ static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,    // Add the lane    Inst.addOperand(MCOperand::CreateImm(1)); -  return MCDisassembler::Success; +  return Success;  } +static DecodeStatus DecodeVecShiftRImm(llvm::MCInst &Inst, unsigned Imm, +                                       unsigned Add) { +  Inst.addOperand(MCOperand::CreateImm(Add - Imm)); +  return Success; +} -static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst, -                                              unsigned Insn, -                                              uint64_t Address, -                                              const void *Decoder) { -  DecodeStatus Result = MCDisassembler::Success; -  unsigned Rt = fieldFromInstruction(Insn, 0, 5); -  unsigned Rn = fieldFromInstruction(Insn, 5, 5); -  unsigned Rt2 = fieldFromInstruction(Insn, 10, 5); -  unsigned SImm7 = fieldFromInstruction(Insn, 15, 7); -  unsigned L = fieldFromInstruction(Insn, 22, 1); -  unsigned V = fieldFromInstruction(Insn, 26, 1); -  unsigned Opc = fieldFromInstruction(Insn, 30, 2); - -  // Not an official name, but it turns out that bit 23 distinguishes indexed -  // from non-indexed operations. -  unsigned Indexed = fieldFromInstruction(Insn, 23, 1); - -  if (Indexed && L == 0) { -    // The MCInst for an indexed store has an out operand and 4 ins: -    //    Rn_wb, Rt, Rt2, Rn, Imm -    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -  } - -  // You shouldn't load to the same register twice in an instruction... -  if (L && Rt == Rt2) -    Result = MCDisassembler::SoftFail; - -  // ... or do any operation that writes-back to a transfer register. But note -  // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different. -  if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn)) -    Result = MCDisassembler::SoftFail; - -  // Exactly how we decode the MCInst's registers depends on the Opc and V -  // fields of the instruction. These also obviously determine the size of the -  // operation so we can fill in that information while we're at it. -  if (V) { -    // The instruction operates on the FP/SIMD registers -    switch (Opc) { -    default: return MCDisassembler::Fail; -    case 0: -      DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder); -      DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder); -      break; -    case 1: -      DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder); -      DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder); -      break; -    case 2: -      DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder); -      DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder); -      break; -    } -  } else { -    switch (Opc) { -    default: return MCDisassembler::Fail; -    case 0: -      DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder); -      DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder); -      break; -    case 1: -      assert(L && "unexpected \"store signed\" attempt"); -      DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder); -      DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder); -      break; -    case 2: -      DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder); -      DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder); -      break; -    } -  } - -  if (Indexed && L == 1) { -    // The MCInst for an indexed load has 3 out operands and an 3 ins: -    //    Rt, Rt2, Rn_wb, Rt2, Rn, Imm -    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -  } - - -  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -  Inst.addOperand(MCOperand::CreateImm(SImm7)); +static DecodeStatus DecodeVecShiftLImm(llvm::MCInst &Inst, unsigned Imm, +                                       unsigned Add) { +  Inst.addOperand(MCOperand::CreateImm((Imm + Add) & (Add - 1))); +  return Success; +} -  return Result; +static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm, 64);  } -static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst, -                                                       uint32_t Val, -                                                       uint64_t Address, -                                                       const void *Decoder) { -  unsigned Rt = fieldFromInstruction(Val, 0, 5); -  unsigned Rn = fieldFromInstruction(Val, 5, 5); -  unsigned Rt2 = fieldFromInstruction(Val, 10, 5); -  unsigned MemSize = fieldFromInstruction(Val, 30, 2); - -  DecodeStatus S = MCDisassembler::Success; -  if (Rt == Rt2) S = MCDisassembler::SoftFail; - -  switch (MemSize) { -    case 2: -      if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder))) -        return MCDisassembler::Fail; -      if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder))) -        return MCDisassembler::Fail; -      break; -    case 3: -      if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder))) -        return MCDisassembler::Fail; -      if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder))) -        return MCDisassembler::Fail; -      break; -    default: -      llvm_unreachable("Invalid MemSize in DecodeLoadPairExclusiveInstruction"); -  } +static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm | 0x20, 64); +} -  if (!Check(S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder))) -    return MCDisassembler::Fail; +static DecodeStatus DecodeVecShiftR32Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm, 32); +} -  return S; +static DecodeStatus DecodeVecShiftR32ImmNarrow(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);  } -template<typename SomeNamedImmMapper> -static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst, -                                          unsigned Val, -                                          uint64_t Address, -                                          const void *Decoder) { -  SomeNamedImmMapper Mapper; -  bool ValidNamed; -  Mapper.toString(Val, ValidNamed); -  if (ValidNamed || Mapper.validImm(Val)) { -    Inst.addOperand(MCOperand::CreateImm(Val)); -    return MCDisassembler::Success; -  } +static DecodeStatus DecodeVecShiftR16Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm, 16); +} -  return MCDisassembler::Fail; +static DecodeStatus DecodeVecShiftR16ImmNarrow(llvm::MCInst &Inst, unsigned Imm, +                                               uint64_t Addr, +                                               const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);  } -static DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &Mapper, -                                        llvm::MCInst &Inst, -                                        unsigned Val, -                                        uint64_t Address, -                                        const void *Decoder) { -  bool ValidNamed; -  Mapper.toString(Val, ValidNamed); +static DecodeStatus DecodeVecShiftR8Imm(llvm::MCInst &Inst, unsigned Imm, +                                        uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftRImm(Inst, Imm, 8); +} -  Inst.addOperand(MCOperand::CreateImm(Val)); +static DecodeStatus DecodeVecShiftL64Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftLImm(Inst, Imm, 64); +} -  return ValidNamed ? MCDisassembler::Success : MCDisassembler::Fail; +static DecodeStatus DecodeVecShiftL32Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftLImm(Inst, Imm, 32);  } -static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst, -                                     unsigned Val, -                                     uint64_t Address, -                                     const void *Decoder) { -  return DecodeSysRegOperand(A64SysReg::MRSMapper(), Inst, Val, Address, -                             Decoder); +static DecodeStatus DecodeVecShiftL16Imm(llvm::MCInst &Inst, unsigned Imm, +                                         uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftLImm(Inst, Imm, 16);  } -static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst, -                                     unsigned Val, -                                     uint64_t Address, -                                     const void *Decoder) { -  return DecodeSysRegOperand(A64SysReg::MSRMapper(), Inst, Val, Address, -                             Decoder); +static DecodeStatus DecodeVecShiftL8Imm(llvm::MCInst &Inst, unsigned Imm, +                                        uint64_t Addr, const void *Decoder) { +  return DecodeVecShiftLImm(Inst, Imm, 8);  } -static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst, -                                                   unsigned Insn, -                                                   uint64_t Address, +static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst, +                                                   uint32_t insn, uint64_t Addr,                                                     const void *Decoder) { -  unsigned Rt = fieldFromInstruction(Insn, 0, 5); -  unsigned Rn = fieldFromInstruction(Insn, 5, 5); -  unsigned Imm9 = fieldFromInstruction(Insn, 12, 9); - -  unsigned Opc = fieldFromInstruction(Insn, 22, 2); -  unsigned V = fieldFromInstruction(Insn, 26, 1); -  unsigned Size = fieldFromInstruction(Insn, 30, 2); - -  if (Opc == 0 || (V == 1 && Opc == 2)) { -    // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm -    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned Rm = fieldFromInstruction(insn, 16, 5); +  unsigned shiftHi = fieldFromInstruction(insn, 22, 2); +  unsigned shiftLo = fieldFromInstruction(insn, 10, 6); +  unsigned shift = (shiftHi << 6) | shiftLo; +  switch (Inst.getOpcode()) { +  default: +    return Fail; +  case AArch64::ADDWrs: +  case AArch64::ADDSWrs: +  case AArch64::SUBWrs: +  case AArch64::SUBSWrs: +    // if shift == '11' then ReservedValue() +    if (shiftHi == 0x3) +      return Fail; +    // Deliberate fallthrough +  case AArch64::ANDWrs: +  case AArch64::ANDSWrs: +  case AArch64::BICWrs: +  case AArch64::BICSWrs: +  case AArch64::ORRWrs: +  case AArch64::ORNWrs: +  case AArch64::EORWrs: +  case AArch64::EONWrs: { +    // if sf == '0' and imm6<5> == '1' then ReservedValue() +    if (shiftLo >> 5 == 1) +      return Fail; +    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); +    break;    } - -  if (V == 0 && (Opc == 2 || Size == 3)) { -    DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder); -  } else if (V == 0) { -    DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder); -  } else if (V == 1 && (Opc & 2)) { -    DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder); -  } else { -    switch (Size) { -    case 0: -      DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 1: -      DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 2: -      DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 3: -      DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder); -      break; -    } +  case AArch64::ADDXrs: +  case AArch64::ADDSXrs: +  case AArch64::SUBXrs: +  case AArch64::SUBSXrs: +    // if shift == '11' then ReservedValue() +    if (shiftHi == 0x3) +      return Fail; +    // Deliberate fallthrough +  case AArch64::ANDXrs: +  case AArch64::ANDSXrs: +  case AArch64::BICXrs: +  case AArch64::BICSXrs: +  case AArch64::ORRXrs: +  case AArch64::ORNXrs: +  case AArch64::EORXrs: +  case AArch64::EONXrs: +    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); +    break;    } -  if (Opc != 0 && (V != 1 || Opc != 2)) { -    // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm -    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -  } +  Inst.addOperand(MCOperand::CreateImm(shift)); +  return Success; +} -  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); +static DecodeStatus DecodeMoveImmInstruction(llvm::MCInst &Inst, uint32_t insn, +                                             uint64_t Addr, +                                             const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned imm = fieldFromInstruction(insn, 5, 16); +  unsigned shift = fieldFromInstruction(insn, 21, 2); +  shift <<= 4; +  switch (Inst.getOpcode()) { +  default: +    return Fail; +  case AArch64::MOVZWi: +  case AArch64::MOVNWi: +  case AArch64::MOVKWi: +    if (shift & (1U << 5)) +      return Fail; +    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); +    break; +  case AArch64::MOVZXi: +  case AArch64::MOVNXi: +  case AArch64::MOVKXi: +    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +    break; +  } -  Inst.addOperand(MCOperand::CreateImm(Imm9)); +  if (Inst.getOpcode() == AArch64::MOVKWi || +      Inst.getOpcode() == AArch64::MOVKXi) +    Inst.addOperand(Inst.getOperand(0)); -  // N.b. The official documentation says undpredictable if Rt == Rn, but this -  // takes place at the architectural rather than encoding level: -  // -  // "STR xzr, [sp], #4" is perfectly valid. -  if (V == 0 && Rt == Rn && Rn != 31) -    return MCDisassembler::SoftFail; -  else -    return MCDisassembler::Success; +  Inst.addOperand(MCOperand::CreateImm(imm)); +  Inst.addOperand(MCOperand::CreateImm(shift)); +  return Success;  } -static MCDisassembler *createAArch64Disassembler(const Target &T, -                                                 const MCSubtargetInfo &STI) { -  return new AArch64Disassembler(STI, T.createMCRegInfo("")); -} +static DecodeStatus DecodeUnsignedLdStInstruction(llvm::MCInst &Inst, +                                                  uint32_t insn, uint64_t Addr, +                                                  const void *Decoder) { +  unsigned Rt = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned offset = fieldFromInstruction(insn, 10, 12); +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); -extern "C" void LLVMInitializeAArch64Disassembler() { -  TargetRegistry::RegisterMCDisassembler(TheAArch64Target, -                                         createAArch64Disassembler); -} +  switch (Inst.getOpcode()) { +  default: +    return Fail; +  case AArch64::PRFMui: +    // Rt is an immediate in prefetch. +    Inst.addOperand(MCOperand::CreateImm(Rt)); +    break; +  case AArch64::STRBBui: +  case AArch64::LDRBBui: +  case AArch64::LDRSBWui: +  case AArch64::STRHHui: +  case AArch64::LDRHHui: +  case AArch64::LDRSHWui: +  case AArch64::STRWui: +  case AArch64::LDRWui: +    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDRSBXui: +  case AArch64::LDRSHXui: +  case AArch64::LDRSWui: +  case AArch64::STRXui: +  case AArch64::LDRXui: +    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDRQui: +  case AArch64::STRQui: +    DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDRDui: +  case AArch64::STRDui: +    DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDRSui: +  case AArch64::STRSui: +    DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDRHui: +  case AArch64::STRHui: +    DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDRBui: +  case AArch64::STRBui: +    DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  } -template <A64SE::ShiftExtSpecifiers Ext, bool IsHalf> -static DecodeStatus -DecodeNeonMovImmShiftOperand(llvm::MCInst &Inst, unsigned ShiftAmount, -                             uint64_t Address, const void *Decoder) { -  bool IsLSL = false; -  if (Ext == A64SE::LSL) -    IsLSL = true; -  else if (Ext != A64SE::MSL) -    return MCDisassembler::Fail; - -  // MSL and LSLH accepts encoded shift amount 0 or 1. -  if ((!IsLSL || (IsLSL && IsHalf)) && ShiftAmount != 0 && ShiftAmount != 1) -    return MCDisassembler::Fail; - -  // LSL  accepts encoded shift amount 0, 1, 2 or 3. -  if (IsLSL && ShiftAmount > 3) -    return MCDisassembler::Fail; - -  Inst.addOperand(MCOperand::CreateImm(ShiftAmount)); -  return MCDisassembler::Success; +  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +  if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4)) +    Inst.addOperand(MCOperand::CreateImm(offset)); +  return Success;  } -// Decode post-index vector load/store instructions. -// This is necessary as we need to decode Rm: if Rm == 0b11111, the last -// operand is an immediate equal the the length of vector list in bytes, -// or Rm is decoded to a GPR64noxzr register. -static DecodeStatus DecodeVLDSTPostInstruction(MCInst &Inst, unsigned Insn, -                                               uint64_t Address, -                                               const void *Decoder) { -  unsigned Rt = fieldFromInstruction(Insn, 0, 5); -  unsigned Rn = fieldFromInstruction(Insn, 5, 5); -  unsigned Rm = fieldFromInstruction(Insn, 16, 5); -  unsigned Opcode = fieldFromInstruction(Insn, 12, 4); -  unsigned IsLoad = fieldFromInstruction(Insn, 22, 1); -  // 0 for 64bit vector list, 1 for 128bit vector list -  unsigned Is128BitVec = fieldFromInstruction(Insn, 30, 1); +static DecodeStatus DecodeSignedLdStInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Addr, +                                                const void *Decoder) { +  unsigned Rt = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  int64_t offset = fieldFromInstruction(insn, 12, 9); -  unsigned NumVecs; -  switch (Opcode) { -  case 0: // ld4/st4 -  case 2: // ld1/st1 with 4 vectors -    NumVecs = 4; break; -  case 4: // ld3/st3 -  case 6: // ld1/st1 with 3 vectors -    NumVecs = 3; break; -  case 7: // ld1/st1 with 1 vector -    NumVecs = 1; break; -  case 8:  // ld2/st2 -  case 10: // ld1/st1 with 2 vectors -    NumVecs = 2; break; +  // offset is a 9-bit signed immediate, so sign extend it to +  // fill the unsigned. +  if (offset & (1 << (9 - 1))) +    offset |= ~((1LL << 9) - 1); + +  // First operand is always the writeback to the address register, if needed. +  switch (Inst.getOpcode()) {    default: -    llvm_unreachable("Invalid opcode for post-index load/store instructions"); +    break; +  case AArch64::LDRSBWpre: +  case AArch64::LDRSHWpre: +  case AArch64::STRBBpre: +  case AArch64::LDRBBpre: +  case AArch64::STRHHpre: +  case AArch64::LDRHHpre: +  case AArch64::STRWpre: +  case AArch64::LDRWpre: +  case AArch64::LDRSBWpost: +  case AArch64::LDRSHWpost: +  case AArch64::STRBBpost: +  case AArch64::LDRBBpost: +  case AArch64::STRHHpost: +  case AArch64::LDRHHpost: +  case AArch64::STRWpost: +  case AArch64::LDRWpost: +  case AArch64::LDRSBXpre: +  case AArch64::LDRSHXpre: +  case AArch64::STRXpre: +  case AArch64::LDRSWpre: +  case AArch64::LDRXpre: +  case AArch64::LDRSBXpost: +  case AArch64::LDRSHXpost: +  case AArch64::STRXpost: +  case AArch64::LDRSWpost: +  case AArch64::LDRXpost: +  case AArch64::LDRQpre: +  case AArch64::STRQpre: +  case AArch64::LDRQpost: +  case AArch64::STRQpost: +  case AArch64::LDRDpre: +  case AArch64::STRDpre: +  case AArch64::LDRDpost: +  case AArch64::STRDpost: +  case AArch64::LDRSpre: +  case AArch64::STRSpre: +  case AArch64::LDRSpost: +  case AArch64::STRSpost: +  case AArch64::LDRHpre: +  case AArch64::STRHpre: +  case AArch64::LDRHpost: +  case AArch64::STRHpost: +  case AArch64::LDRBpre: +  case AArch64::STRBpre: +  case AArch64::LDRBpost: +  case AArch64::STRBpost: +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +    break;    } -  // Decode vector list of 1/2/3/4 vectors for load instructions. -  if (IsLoad) { -    switch (NumVecs) { -    case 1: -      Is128BitVec ? DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 2: -      Is128BitVec ? DecodeQPairRegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeDPairRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 3: -      Is128BitVec ? DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeDTripleRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 4: -      Is128BitVec ? DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeDQuadRegisterClass(Inst, Rt, Address, Decoder); -      break; -    } +  switch (Inst.getOpcode()) { +  default: +    return Fail; +  case AArch64::PRFUMi: +    // Rt is an immediate in prefetch. +    Inst.addOperand(MCOperand::CreateImm(Rt)); +    break; +  case AArch64::STURBBi: +  case AArch64::LDURBBi: +  case AArch64::LDURSBWi: +  case AArch64::STURHHi: +  case AArch64::LDURHHi: +  case AArch64::LDURSHWi: +  case AArch64::STURWi: +  case AArch64::LDURWi: +  case AArch64::LDTRSBWi: +  case AArch64::LDTRSHWi: +  case AArch64::STTRWi: +  case AArch64::LDTRWi: +  case AArch64::STTRHi: +  case AArch64::LDTRHi: +  case AArch64::LDTRBi: +  case AArch64::STTRBi: +  case AArch64::LDRSBWpre: +  case AArch64::LDRSHWpre: +  case AArch64::STRBBpre: +  case AArch64::LDRBBpre: +  case AArch64::STRHHpre: +  case AArch64::LDRHHpre: +  case AArch64::STRWpre: +  case AArch64::LDRWpre: +  case AArch64::LDRSBWpost: +  case AArch64::LDRSHWpost: +  case AArch64::STRBBpost: +  case AArch64::LDRBBpost: +  case AArch64::STRHHpost: +  case AArch64::LDRHHpost: +  case AArch64::STRWpost: +  case AArch64::LDRWpost: +    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDURSBXi: +  case AArch64::LDURSHXi: +  case AArch64::LDURSWi: +  case AArch64::STURXi: +  case AArch64::LDURXi: +  case AArch64::LDTRSBXi: +  case AArch64::LDTRSHXi: +  case AArch64::LDTRSWi: +  case AArch64::STTRXi: +  case AArch64::LDTRXi: +  case AArch64::LDRSBXpre: +  case AArch64::LDRSHXpre: +  case AArch64::STRXpre: +  case AArch64::LDRSWpre: +  case AArch64::LDRXpre: +  case AArch64::LDRSBXpost: +  case AArch64::LDRSHXpost: +  case AArch64::STRXpost: +  case AArch64::LDRSWpost: +  case AArch64::LDRXpost: +    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDURQi: +  case AArch64::STURQi: +  case AArch64::LDRQpre: +  case AArch64::STRQpre: +  case AArch64::LDRQpost: +  case AArch64::STRQpost: +    DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDURDi: +  case AArch64::STURDi: +  case AArch64::LDRDpre: +  case AArch64::STRDpre: +  case AArch64::LDRDpost: +  case AArch64::STRDpost: +    DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDURSi: +  case AArch64::STURSi: +  case AArch64::LDRSpre: +  case AArch64::STRSpre: +  case AArch64::LDRSpost: +  case AArch64::STRSpost: +    DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDURHi: +  case AArch64::STURHi: +  case AArch64::LDRHpre: +  case AArch64::STRHpre: +  case AArch64::LDRHpost: +  case AArch64::STRHpost: +    DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); +    break; +  case AArch64::LDURBi: +  case AArch64::STURBi: +  case AArch64::LDRBpre: +  case AArch64::STRBpre: +  case AArch64::LDRBpost: +  case AArch64::STRBpost: +    DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); +    break;    } -  // Decode write back register, which is equal to Rn. -  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); - -  if (Rm == 31) // If Rm is 0x11111, add the vector list length in byte -    Inst.addOperand(MCOperand::CreateImm(NumVecs * (Is128BitVec ? 16 : 8))); -  else // Decode Rm -    DecodeGPR64noxzrRegisterClass(Inst, Rm, Address, Decoder); - -  // Decode vector list of 1/2/3/4 vectors for load instructions. -  if (!IsLoad) { -    switch (NumVecs) { -    case 1: -      Is128BitVec ? DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 2: -      Is128BitVec ? DecodeQPairRegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeDPairRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 3: -      Is128BitVec ? DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeDTripleRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 4: -      Is128BitVec ? DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder) -                  : DecodeDQuadRegisterClass(Inst, Rt, Address, Decoder); -      break; -    } -  } +  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +  Inst.addOperand(MCOperand::CreateImm(offset)); + +  bool IsLoad = fieldFromInstruction(insn, 22, 1); +  bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0; +  bool IsFP = fieldFromInstruction(insn, 26, 1); -  return MCDisassembler::Success; +  // Cannot write back to a transfer register (but xzr != sp). +  if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) +    return SoftFail; + +  return Success;  } -// Decode post-index vector load/store lane instructions. -// This is necessary as we need to decode Rm: if Rm == 0b11111, the last -// operand is an immediate equal the the length of the changed bytes, -// or Rm is decoded to a GPR64noxzr register. -static DecodeStatus DecodeVLDSTLanePostInstruction(MCInst &Inst, unsigned Insn, -                                                   uint64_t Address, +static DecodeStatus DecodeExclusiveLdStInstruction(llvm::MCInst &Inst, +                                                   uint32_t insn, uint64_t Addr,                                                     const void *Decoder) { -  bool Is64bitVec = false; -  bool IsLoadDup = false; -  bool IsLoad = false; -  // The total number of bytes transferred. -  // TransferBytes = NumVecs * OneLaneBytes -  unsigned TransferBytes = 0; -  unsigned NumVecs = 0; -  unsigned Opc = Inst.getOpcode(); -  switch (Opc) { -  case AArch64::LD1R_WB_8B_fixed: case AArch64::LD1R_WB_8B_register: -  case AArch64::LD1R_WB_4H_fixed: case AArch64::LD1R_WB_4H_register: -  case AArch64::LD1R_WB_2S_fixed: case AArch64::LD1R_WB_2S_register: -  case AArch64::LD1R_WB_1D_fixed: case AArch64::LD1R_WB_1D_register: { -    switch (Opc) { -    case AArch64::LD1R_WB_8B_fixed: case AArch64::LD1R_WB_8B_register: -      TransferBytes = 1; break; -    case AArch64::LD1R_WB_4H_fixed: case AArch64::LD1R_WB_4H_register: -      TransferBytes = 2; break; -    case AArch64::LD1R_WB_2S_fixed: case AArch64::LD1R_WB_2S_register: -      TransferBytes = 4; break; -    case AArch64::LD1R_WB_1D_fixed: case AArch64::LD1R_WB_1D_register: -      TransferBytes = 8; break; -    } -    Is64bitVec = true; -    IsLoadDup = true; -    NumVecs = 1; -    break; -  } +  unsigned Rt = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned Rt2 = fieldFromInstruction(insn, 10, 5); +  unsigned Rs = fieldFromInstruction(insn, 16, 5); -  case AArch64::LD1R_WB_16B_fixed: case AArch64::LD1R_WB_16B_register: -  case AArch64::LD1R_WB_8H_fixed: case AArch64::LD1R_WB_8H_register: -  case AArch64::LD1R_WB_4S_fixed: case AArch64::LD1R_WB_4S_register: -  case AArch64::LD1R_WB_2D_fixed: case AArch64::LD1R_WB_2D_register: { -    switch (Opc) { -    case AArch64::LD1R_WB_16B_fixed: case AArch64::LD1R_WB_16B_register: -      TransferBytes = 1; break; -    case AArch64::LD1R_WB_8H_fixed: case AArch64::LD1R_WB_8H_register: -      TransferBytes = 2; break; -    case AArch64::LD1R_WB_4S_fixed: case AArch64::LD1R_WB_4S_register: -      TransferBytes = 4; break; -    case AArch64::LD1R_WB_2D_fixed: case AArch64::LD1R_WB_2D_register: -      TransferBytes = 8; break; -    } -    IsLoadDup = true; -    NumVecs = 1; +  unsigned Opcode = Inst.getOpcode(); +  switch (Opcode) { +  default: +    return Fail; +  case AArch64::STLXRW: +  case AArch64::STLXRB: +  case AArch64::STLXRH: +  case AArch64::STXRW: +  case AArch64::STXRB: +  case AArch64::STXRH: +    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); +  // FALLTHROUGH +  case AArch64::LDARW: +  case AArch64::LDARB: +  case AArch64::LDARH: +  case AArch64::LDAXRW: +  case AArch64::LDAXRB: +  case AArch64::LDAXRH: +  case AArch64::LDXRW: +  case AArch64::LDXRB: +  case AArch64::LDXRH: +  case AArch64::STLRW: +  case AArch64::STLRB: +  case AArch64::STLRH: +    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);      break; -  } - -  case AArch64::LD2R_WB_8B_fixed: case AArch64::LD2R_WB_8B_register: -  case AArch64::LD2R_WB_4H_fixed: case AArch64::LD2R_WB_4H_register: -  case AArch64::LD2R_WB_2S_fixed: case AArch64::LD2R_WB_2S_register: -  case AArch64::LD2R_WB_1D_fixed: case AArch64::LD2R_WB_1D_register: { -    switch (Opc) { -    case AArch64::LD2R_WB_8B_fixed: case AArch64::LD2R_WB_8B_register: -      TransferBytes = 2; break; -    case AArch64::LD2R_WB_4H_fixed: case AArch64::LD2R_WB_4H_register: -      TransferBytes = 4; break; -    case AArch64::LD2R_WB_2S_fixed: case AArch64::LD2R_WB_2S_register: -      TransferBytes = 8; break; -    case AArch64::LD2R_WB_1D_fixed: case AArch64::LD2R_WB_1D_register: -      TransferBytes = 16; break; -    } -    Is64bitVec = true; -    IsLoadDup = true; -    NumVecs = 2; +  case AArch64::STLXRX: +  case AArch64::STXRX: +    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); +  // FALLTHROUGH +  case AArch64::LDARX: +  case AArch64::LDAXRX: +  case AArch64::LDXRX: +  case AArch64::STLRX: +    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);      break; -  } - -  case AArch64::LD2R_WB_16B_fixed: case AArch64::LD2R_WB_16B_register: -  case AArch64::LD2R_WB_8H_fixed: case AArch64::LD2R_WB_8H_register: -  case AArch64::LD2R_WB_4S_fixed: case AArch64::LD2R_WB_4S_register: -  case AArch64::LD2R_WB_2D_fixed: case AArch64::LD2R_WB_2D_register: { -    switch (Opc) { -    case AArch64::LD2R_WB_16B_fixed: case AArch64::LD2R_WB_16B_register: -      TransferBytes = 2; break; -    case AArch64::LD2R_WB_8H_fixed: case AArch64::LD2R_WB_8H_register: -      TransferBytes = 4; break; -    case AArch64::LD2R_WB_4S_fixed: case AArch64::LD2R_WB_4S_register: -      TransferBytes = 8; break; -    case AArch64::LD2R_WB_2D_fixed: case AArch64::LD2R_WB_2D_register: -      TransferBytes = 16; break; -    } -    IsLoadDup = true; -    NumVecs = 2; +  case AArch64::STLXPW: +  case AArch64::STXPW: +    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); +  // FALLTHROUGH +  case AArch64::LDAXPW: +  case AArch64::LDXPW: +    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);      break; -  } - -  case AArch64::LD3R_WB_8B_fixed: case AArch64::LD3R_WB_8B_register: -  case AArch64::LD3R_WB_4H_fixed: case AArch64::LD3R_WB_4H_register: -  case AArch64::LD3R_WB_2S_fixed: case AArch64::LD3R_WB_2S_register: -  case AArch64::LD3R_WB_1D_fixed: case AArch64::LD3R_WB_1D_register: { -    switch (Opc) { -    case AArch64::LD3R_WB_8B_fixed: case AArch64::LD3R_WB_8B_register: -      TransferBytes = 3; break; -    case AArch64::LD3R_WB_4H_fixed: case AArch64::LD3R_WB_4H_register: -      TransferBytes = 6; break; -    case AArch64::LD3R_WB_2S_fixed: case AArch64::LD3R_WB_2S_register: -      TransferBytes = 12; break; -    case AArch64::LD3R_WB_1D_fixed: case AArch64::LD3R_WB_1D_register: -      TransferBytes = 24; break; -    } -    Is64bitVec = true; -    IsLoadDup = true; -    NumVecs = 3; +  case AArch64::STLXPX: +  case AArch64::STXPX: +    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); +  // FALLTHROUGH +  case AArch64::LDAXPX: +  case AArch64::LDXPX: +    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);      break;    } -  case AArch64::LD3R_WB_16B_fixed: case AArch64::LD3R_WB_16B_register: -  case AArch64::LD3R_WB_4S_fixed: case AArch64::LD3R_WB_8H_register: -  case AArch64::LD3R_WB_8H_fixed: case AArch64::LD3R_WB_4S_register: -  case AArch64::LD3R_WB_2D_fixed: case AArch64::LD3R_WB_2D_register: { -    switch (Opc) { -    case AArch64::LD3R_WB_16B_fixed: case AArch64::LD3R_WB_16B_register: -      TransferBytes = 3; break; -    case AArch64::LD3R_WB_8H_fixed: case AArch64::LD3R_WB_8H_register: -      TransferBytes = 6; break; -    case AArch64::LD3R_WB_4S_fixed: case AArch64::LD3R_WB_4S_register: -      TransferBytes = 12; break; -    case AArch64::LD3R_WB_2D_fixed: case AArch64::LD3R_WB_2D_register: -      TransferBytes = 24; break; -    } -    IsLoadDup = true; -    NumVecs = 3; -    break; -  } +  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); -  case AArch64::LD4R_WB_8B_fixed: case AArch64::LD4R_WB_8B_register: -  case AArch64::LD4R_WB_4H_fixed: case AArch64::LD4R_WB_4H_register: -  case AArch64::LD4R_WB_2S_fixed: case AArch64::LD4R_WB_2S_register: -  case AArch64::LD4R_WB_1D_fixed: case AArch64::LD4R_WB_1D_register: { -    switch (Opc) { -    case AArch64::LD4R_WB_8B_fixed: case AArch64::LD4R_WB_8B_register: -      TransferBytes = 4; break; -    case AArch64::LD4R_WB_4H_fixed: case AArch64::LD4R_WB_4H_register: -      TransferBytes = 8; break; -    case AArch64::LD4R_WB_2S_fixed: case AArch64::LD4R_WB_2S_register: -      TransferBytes = 16; break; -    case AArch64::LD4R_WB_1D_fixed: case AArch64::LD4R_WB_1D_register: -      TransferBytes = 32; break; -    } -    Is64bitVec = true; -    IsLoadDup = true; -    NumVecs = 4; -    break; -  } +  // You shouldn't load to the same register twice in an instruction... +  if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW || +       Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) && +      Rt == Rt2) +    return SoftFail; -  case AArch64::LD4R_WB_16B_fixed: case AArch64::LD4R_WB_16B_register: -  case AArch64::LD4R_WB_4S_fixed: case AArch64::LD4R_WB_8H_register: -  case AArch64::LD4R_WB_8H_fixed: case AArch64::LD4R_WB_4S_register: -  case AArch64::LD4R_WB_2D_fixed: case AArch64::LD4R_WB_2D_register: { -    switch (Opc) { -    case AArch64::LD4R_WB_16B_fixed: case AArch64::LD4R_WB_16B_register: -      TransferBytes = 4; break; -    case AArch64::LD4R_WB_8H_fixed: case AArch64::LD4R_WB_8H_register: -      TransferBytes = 8; break; -    case AArch64::LD4R_WB_4S_fixed: case AArch64::LD4R_WB_4S_register: -      TransferBytes = 16; break; -    case AArch64::LD4R_WB_2D_fixed: case AArch64::LD4R_WB_2D_register: -      TransferBytes = 32; break; -    } -    IsLoadDup = true; -    NumVecs = 4; -    break; -  } +  return Success; +} -  case AArch64::LD1LN_WB_B_fixed: case AArch64::LD1LN_WB_B_register: -  case AArch64::LD1LN_WB_H_fixed: case AArch64::LD1LN_WB_H_register: -  case AArch64::LD1LN_WB_S_fixed: case AArch64::LD1LN_WB_S_register: -  case AArch64::LD1LN_WB_D_fixed: case AArch64::LD1LN_WB_D_register: { -    switch (Opc) { -    case AArch64::LD1LN_WB_B_fixed: case AArch64::LD1LN_WB_B_register: -      TransferBytes = 1; break; -    case AArch64::LD1LN_WB_H_fixed: case AArch64::LD1LN_WB_H_register: -      TransferBytes = 2; break; -    case AArch64::LD1LN_WB_S_fixed: case AArch64::LD1LN_WB_S_register: -      TransferBytes = 4; break; -    case AArch64::LD1LN_WB_D_fixed: case AArch64::LD1LN_WB_D_register: -      TransferBytes = 8; break; -    } -    IsLoad = true; -    NumVecs = 1; -    break; -  } +static DecodeStatus DecodePairLdStInstruction(llvm::MCInst &Inst, uint32_t insn, +                                              uint64_t Addr, +                                              const void *Decoder) { +  unsigned Rt = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned Rt2 = fieldFromInstruction(insn, 10, 5); +  int64_t offset = fieldFromInstruction(insn, 15, 7); +  bool IsLoad = fieldFromInstruction(insn, 22, 1); -  case AArch64::LD2LN_WB_B_fixed: case AArch64::LD2LN_WB_B_register: -  case AArch64::LD2LN_WB_H_fixed: case AArch64::LD2LN_WB_H_register: -  case AArch64::LD2LN_WB_S_fixed: case AArch64::LD2LN_WB_S_register: -  case AArch64::LD2LN_WB_D_fixed: case AArch64::LD2LN_WB_D_register: { -    switch (Opc) { -    case AArch64::LD2LN_WB_B_fixed: case AArch64::LD2LN_WB_B_register: -      TransferBytes = 2; break; -    case AArch64::LD2LN_WB_H_fixed: case AArch64::LD2LN_WB_H_register: -      TransferBytes = 4; break; -    case AArch64::LD2LN_WB_S_fixed: case AArch64::LD2LN_WB_S_register: -      TransferBytes = 8; break; -    case AArch64::LD2LN_WB_D_fixed: case AArch64::LD2LN_WB_D_register: -      TransferBytes = 16; break; -    } -    IsLoad = true; -    NumVecs = 2; -    break; -  } +  // offset is a 7-bit signed immediate, so sign extend it to +  // fill the unsigned. +  if (offset & (1 << (7 - 1))) +    offset |= ~((1LL << 7) - 1); -  case AArch64::LD3LN_WB_B_fixed: case AArch64::LD3LN_WB_B_register: -  case AArch64::LD3LN_WB_H_fixed: case AArch64::LD3LN_WB_H_register: -  case AArch64::LD3LN_WB_S_fixed: case AArch64::LD3LN_WB_S_register: -  case AArch64::LD3LN_WB_D_fixed: case AArch64::LD3LN_WB_D_register: { -    switch (Opc) { -    case AArch64::LD3LN_WB_B_fixed: case AArch64::LD3LN_WB_B_register: -      TransferBytes = 3; break; -    case AArch64::LD3LN_WB_H_fixed: case AArch64::LD3LN_WB_H_register: -      TransferBytes = 6; break; -    case AArch64::LD3LN_WB_S_fixed: case AArch64::LD3LN_WB_S_register: -      TransferBytes = 12; break; -    case AArch64::LD3LN_WB_D_fixed: case AArch64::LD3LN_WB_D_register: -      TransferBytes = 24; break; -    } -    IsLoad = true; -    NumVecs = 3; -    break; -  } +  unsigned Opcode = Inst.getOpcode(); +  bool NeedsDisjointWritebackTransfer = false; -  case AArch64::LD4LN_WB_B_fixed: case AArch64::LD4LN_WB_B_register: -  case AArch64::LD4LN_WB_H_fixed: case AArch64::LD4LN_WB_H_register: -  case AArch64::LD4LN_WB_S_fixed: case AArch64::LD4LN_WB_S_register: -  case AArch64::LD4LN_WB_D_fixed: case AArch64::LD4LN_WB_D_register: { -    switch (Opc) { -    case AArch64::LD4LN_WB_B_fixed: case AArch64::LD4LN_WB_B_register: -      TransferBytes = 4; break; -    case AArch64::LD4LN_WB_H_fixed: case AArch64::LD4LN_WB_H_register: -      TransferBytes = 8; break; -    case AArch64::LD4LN_WB_S_fixed: case AArch64::LD4LN_WB_S_register: -      TransferBytes = 16; break; -    case AArch64::LD4LN_WB_D_fixed: case AArch64::LD4LN_WB_D_register: -      TransferBytes = 32; break; -    } -    IsLoad = true; -    NumVecs = 4; +  // First operand is always writeback of base register. +  switch (Opcode) { +  default:      break; -  } - -  case AArch64::ST1LN_WB_B_fixed: case AArch64::ST1LN_WB_B_register: -  case AArch64::ST1LN_WB_H_fixed: case AArch64::ST1LN_WB_H_register: -  case AArch64::ST1LN_WB_S_fixed: case AArch64::ST1LN_WB_S_register: -  case AArch64::ST1LN_WB_D_fixed: case AArch64::ST1LN_WB_D_register: { -    switch (Opc) { -    case AArch64::ST1LN_WB_B_fixed: case AArch64::ST1LN_WB_B_register: -      TransferBytes = 1; break; -    case AArch64::ST1LN_WB_H_fixed: case AArch64::ST1LN_WB_H_register: -      TransferBytes = 2; break; -    case AArch64::ST1LN_WB_S_fixed: case AArch64::ST1LN_WB_S_register: -      TransferBytes = 4; break; -    case AArch64::ST1LN_WB_D_fixed: case AArch64::ST1LN_WB_D_register: -      TransferBytes = 8; break; -    } -    NumVecs = 1; +  case AArch64::LDPXpost: +  case AArch64::STPXpost: +  case AArch64::LDPSWpost: +  case AArch64::LDPXpre: +  case AArch64::STPXpre: +  case AArch64::LDPSWpre: +  case AArch64::LDPWpost: +  case AArch64::STPWpost: +  case AArch64::LDPWpre: +  case AArch64::STPWpre: +  case AArch64::LDPQpost: +  case AArch64::STPQpost: +  case AArch64::LDPQpre: +  case AArch64::STPQpre: +  case AArch64::LDPDpost: +  case AArch64::STPDpost: +  case AArch64::LDPDpre: +  case AArch64::STPDpre: +  case AArch64::LDPSpost: +  case AArch64::STPSpost: +  case AArch64::LDPSpre: +  case AArch64::STPSpre: +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);      break;    } -  case AArch64::ST2LN_WB_B_fixed: case AArch64::ST2LN_WB_B_register: -  case AArch64::ST2LN_WB_H_fixed: case AArch64::ST2LN_WB_H_register: -  case AArch64::ST2LN_WB_S_fixed: case AArch64::ST2LN_WB_S_register: -  case AArch64::ST2LN_WB_D_fixed: case AArch64::ST2LN_WB_D_register: { -    switch (Opc) { -    case AArch64::ST2LN_WB_B_fixed: case AArch64::ST2LN_WB_B_register: -      TransferBytes = 2; break; -    case AArch64::ST2LN_WB_H_fixed: case AArch64::ST2LN_WB_H_register: -      TransferBytes = 4; break; -    case AArch64::ST2LN_WB_S_fixed: case AArch64::ST2LN_WB_S_register: -      TransferBytes = 8; break; -    case AArch64::ST2LN_WB_D_fixed: case AArch64::ST2LN_WB_D_register: -      TransferBytes = 16; break; -    } -    NumVecs = 2; +  switch (Opcode) { +  default: +    return Fail; +  case AArch64::LDPXpost: +  case AArch64::STPXpost: +  case AArch64::LDPSWpost: +  case AArch64::LDPXpre: +  case AArch64::STPXpre: +  case AArch64::LDPSWpre: +    NeedsDisjointWritebackTransfer = true; +    // Fallthrough +  case AArch64::LDNPXi: +  case AArch64::STNPXi: +  case AArch64::LDPXi: +  case AArch64::STPXi: +  case AArch64::LDPSWi: +    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);      break; -  } - -  case AArch64::ST3LN_WB_B_fixed: case AArch64::ST3LN_WB_B_register: -  case AArch64::ST3LN_WB_H_fixed: case AArch64::ST3LN_WB_H_register: -  case AArch64::ST3LN_WB_S_fixed: case AArch64::ST3LN_WB_S_register: -  case AArch64::ST3LN_WB_D_fixed: case AArch64::ST3LN_WB_D_register: { -    switch (Opc) { -    case AArch64::ST3LN_WB_B_fixed: case AArch64::ST3LN_WB_B_register: -      TransferBytes = 3; break; -    case AArch64::ST3LN_WB_H_fixed: case AArch64::ST3LN_WB_H_register: -      TransferBytes = 6; break; -    case AArch64::ST3LN_WB_S_fixed: case AArch64::ST3LN_WB_S_register: -      TransferBytes = 12; break; -    case AArch64::ST3LN_WB_D_fixed: case AArch64::ST3LN_WB_D_register: -      TransferBytes = 24; break; -    } -    NumVecs = 3; +  case AArch64::LDPWpost: +  case AArch64::STPWpost: +  case AArch64::LDPWpre: +  case AArch64::STPWpre: +    NeedsDisjointWritebackTransfer = true; +    // Fallthrough +  case AArch64::LDNPWi: +  case AArch64::STNPWi: +  case AArch64::LDPWi: +  case AArch64::STPWi: +    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);      break; -  } - -  case AArch64::ST4LN_WB_B_fixed: case AArch64::ST4LN_WB_B_register: -  case AArch64::ST4LN_WB_H_fixed: case AArch64::ST4LN_WB_H_register: -  case AArch64::ST4LN_WB_S_fixed: case AArch64::ST4LN_WB_S_register: -  case AArch64::ST4LN_WB_D_fixed: case AArch64::ST4LN_WB_D_register: { -    switch (Opc) { -    case AArch64::ST4LN_WB_B_fixed: case AArch64::ST4LN_WB_B_register: -      TransferBytes = 4; break; -    case AArch64::ST4LN_WB_H_fixed: case AArch64::ST4LN_WB_H_register: -      TransferBytes = 8; break; -    case AArch64::ST4LN_WB_S_fixed: case AArch64::ST4LN_WB_S_register: -      TransferBytes = 16; break; -    case AArch64::ST4LN_WB_D_fixed: case AArch64::ST4LN_WB_D_register: -      TransferBytes = 32; break; -    } -    NumVecs = 4; +  case AArch64::LDNPQi: +  case AArch64::STNPQi: +  case AArch64::LDPQpost: +  case AArch64::STPQpost: +  case AArch64::LDPQi: +  case AArch64::STPQi: +  case AArch64::LDPQpre: +  case AArch64::STPQpre: +    DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder); +    break; +  case AArch64::LDNPDi: +  case AArch64::STNPDi: +  case AArch64::LDPDpost: +  case AArch64::STPDpost: +  case AArch64::LDPDi: +  case AArch64::STPDi: +  case AArch64::LDPDpre: +  case AArch64::STPDpre: +    DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder); +    break; +  case AArch64::LDNPSi: +  case AArch64::STNPSi: +  case AArch64::LDPSpost: +  case AArch64::STPSpost: +  case AArch64::LDPSi: +  case AArch64::STPSi: +  case AArch64::LDPSpre: +  case AArch64::STPSpre: +    DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); +    DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);      break;    } -  default: -    return MCDisassembler::Fail; -  } // End of switch (Opc) +  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +  Inst.addOperand(MCOperand::CreateImm(offset)); -  unsigned Rt = fieldFromInstruction(Insn, 0, 5); -  unsigned Rn = fieldFromInstruction(Insn, 5, 5); -  unsigned Rm = fieldFromInstruction(Insn, 16, 5); - -  // Decode post-index of load duplicate lane -  if (IsLoadDup) { -    switch (NumVecs) { -    case 1: -      Is64bitVec ? DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder) -                 : DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 2: -      Is64bitVec ? DecodeDPairRegisterClass(Inst, Rt, Address, Decoder) -                 : DecodeQPairRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 3: -      Is64bitVec ? DecodeDTripleRegisterClass(Inst, Rt, Address, Decoder) -                 : DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 4: -      Is64bitVec ? DecodeDQuadRegisterClass(Inst, Rt, Address, Decoder) -                 : DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder); -    } - -    // Decode write back register, which is equal to Rn. -    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -    DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); - -    if (Rm == 31) // If Rm is 0x11111, add the number of transferred bytes -      Inst.addOperand(MCOperand::CreateImm(TransferBytes)); -    else // Decode Rm -      DecodeGPR64noxzrRegisterClass(Inst, Rm, Address, Decoder); - -    return MCDisassembler::Success; -  } +  // You shouldn't load to the same register twice in an instruction... +  if (IsLoad && Rt == Rt2) +    return SoftFail; -  // Decode post-index of load/store lane -  // Loads have a vector list as output. -  if (IsLoad) { -    switch (NumVecs) { -    case 1: -      DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 2: -      DecodeQPairRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 3: -      DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder); -      break; -    case 4: -      DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder); -    } -  } +  // ... or do any operation that writes-back to a transfer register. But note +  // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different. +  if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn)) +    return SoftFail; + +  return Success; +} -  // Decode write back register, which is equal to Rn. -  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); -  DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder); +static DecodeStatus DecodeAddSubERegInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Addr, +                                                const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned Rm = fieldFromInstruction(insn, 16, 5); +  unsigned extend = fieldFromInstruction(insn, 10, 6); -  if (Rm == 31) // If Rm is 0x11111, add the number of transferred bytes -    Inst.addOperand(MCOperand::CreateImm(TransferBytes)); -  else // Decode Rm -    DecodeGPR64noxzrRegisterClass(Inst, Rm, Address, Decoder); +  unsigned shift = extend & 0x7; +  if (shift > 4) +    return Fail; -  // Decode the source vector list. -  switch (NumVecs) { -  case 1: -    DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder); -    break; -  case 2: -    DecodeQPairRegisterClass(Inst, Rt, Address, Decoder); +  switch (Inst.getOpcode()) { +  default: +    return Fail; +  case AArch64::ADDWrx: +  case AArch64::SUBWrx: +    DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);      break; -  case 3: -    DecodeQTripleRegisterClass(Inst, Rt, Address, Decoder); +  case AArch64::ADDSWrx: +  case AArch64::SUBSWrx: +    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);      break; -  case 4: -    DecodeQQuadRegisterClass(Inst, Rt, Address, Decoder); -  } - -  // Decode lane -  unsigned Q = fieldFromInstruction(Insn, 30, 1); -  unsigned S = fieldFromInstruction(Insn, 10, 3); -  unsigned lane = 0; -  // Calculate the number of lanes by number of vectors and transfered bytes. -  // NumLanes = 16 bytes / bytes of each lane -  unsigned NumLanes = 16 / (TransferBytes / NumVecs); -  switch (NumLanes) { -  case 16: // A vector has 16 lanes, each lane is 1 bytes. -    lane = (Q << 3) | S; +  case AArch64::ADDXrx: +  case AArch64::SUBXrx: +    DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);      break; -  case 8: -    lane = (Q << 2) | (S >> 1); +  case AArch64::ADDSXrx: +  case AArch64::SUBSXrx: +    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);      break; -  case 4: -    lane = (Q << 1) | (S >> 2); +  case AArch64::ADDXrx64: +  case AArch64::SUBXrx64: +    DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);      break; -  case 2: -    lane = Q; +  case AArch64::SUBSXrx64: +  case AArch64::ADDSXrx64: +    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);      break;    } -  Inst.addOperand(MCOperand::CreateImm(lane)); -  return MCDisassembler::Success; +  Inst.addOperand(MCOperand::CreateImm(extend)); +  return Success;  } -static DecodeStatus DecodeSHLLInstruction(MCInst &Inst, unsigned Insn, -                                          uint64_t Address, -                                          const void *Decoder) { -  unsigned Rd = fieldFromInstruction(Insn, 0, 5); -  unsigned Rn = fieldFromInstruction(Insn, 5, 5); -  unsigned size = fieldFromInstruction(Insn, 22, 2); -  unsigned Q = fieldFromInstruction(Insn, 30, 1); +static DecodeStatus DecodeLogicalImmInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Addr, +                                                const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned Datasize = fieldFromInstruction(insn, 31, 1); +  unsigned imm; + +  if (Datasize) { +    if (Inst.getOpcode() == AArch64::ANDSXri) +      DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +    else +      DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); +    imm = fieldFromInstruction(insn, 10, 13); +    if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64)) +      return Fail; +  } else { +    if (Inst.getOpcode() == AArch64::ANDSWri) +      DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); +    else +      DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); +    imm = fieldFromInstruction(insn, 10, 12); +    if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32)) +      return Fail; +  } +  Inst.addOperand(MCOperand::CreateImm(imm)); +  return Success; +} -  DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder); +static DecodeStatus DecodeModImmInstruction(llvm::MCInst &Inst, uint32_t insn, +                                            uint64_t Addr, +                                            const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned cmode = fieldFromInstruction(insn, 12, 4); +  unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; +  imm |= fieldFromInstruction(insn, 5, 5); -  if(Q) -    DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder); +  if (Inst.getOpcode() == AArch64::MOVID) +    DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);    else -    DecodeFPR64RegisterClass(Inst, Rn, Address, Decoder); +    DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); + +  Inst.addOperand(MCOperand::CreateImm(imm)); -  switch (size) { -  case 0: -    Inst.addOperand(MCOperand::CreateImm(8)); +  switch (Inst.getOpcode()) { +  default:      break; -  case 1: -    Inst.addOperand(MCOperand::CreateImm(16)); +  case AArch64::MOVIv4i16: +  case AArch64::MOVIv8i16: +  case AArch64::MVNIv4i16: +  case AArch64::MVNIv8i16: +  case AArch64::MOVIv2i32: +  case AArch64::MOVIv4i32: +  case AArch64::MVNIv2i32: +  case AArch64::MVNIv4i32: +    Inst.addOperand(MCOperand::CreateImm((cmode & 6) << 2));      break; -  case 2: -    Inst.addOperand(MCOperand::CreateImm(32)); +  case AArch64::MOVIv2s_msl: +  case AArch64::MOVIv4s_msl: +  case AArch64::MVNIv2s_msl: +  case AArch64::MVNIv4s_msl: +    Inst.addOperand(MCOperand::CreateImm(cmode & 1 ? 0x110 : 0x108));      break; -  default : -    return MCDisassembler::Fail;    } -  return MCDisassembler::Success; + +  return Success; +} + +static DecodeStatus DecodeModImmTiedInstruction(llvm::MCInst &Inst, +                                                uint32_t insn, uint64_t Addr, +                                                const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned cmode = fieldFromInstruction(insn, 12, 4); +  unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; +  imm |= fieldFromInstruction(insn, 5, 5); + +  // Tied operands added twice. +  DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); +  DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); + +  Inst.addOperand(MCOperand::CreateImm(imm)); +  Inst.addOperand(MCOperand::CreateImm((cmode & 6) << 2)); + +  return Success; +} + +static DecodeStatus DecodeAdrInstruction(llvm::MCInst &Inst, uint32_t insn, +                                         uint64_t Addr, const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  int64_t imm = fieldFromInstruction(insn, 5, 19) << 2; +  imm |= fieldFromInstruction(insn, 29, 2); +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); + +  // Sign-extend the 21-bit immediate. +  if (imm & (1 << (21 - 1))) +    imm |= ~((1LL << 21) - 1); + +  DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +  if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4)) +    Inst.addOperand(MCOperand::CreateImm(imm)); + +  return Success; +} + +static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn, +                                        uint64_t Addr, const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); +  unsigned Imm = fieldFromInstruction(insn, 10, 14); +  unsigned S = fieldFromInstruction(insn, 29, 1); +  unsigned Datasize = fieldFromInstruction(insn, 31, 1); + +  unsigned ShifterVal = (Imm >> 12) & 3; +  unsigned ImmVal = Imm & 0xFFF; +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); + +  if (ShifterVal != 0 && ShifterVal != 1) +    return Fail; + +  if (Datasize) { +    if (Rd == 31 && !S) +      DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); +    else +      DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); +  } else { +    if (Rd == 31 && !S) +      DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); +    else +      DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); +    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); +  } + +  if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4)) +    Inst.addOperand(MCOperand::CreateImm(ImmVal)); +  Inst.addOperand(MCOperand::CreateImm(12 * ShifterVal)); +  return Success; +} + +static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn, +                                              uint64_t Addr, +                                              const void *Decoder) { +  int64_t imm = fieldFromInstruction(insn, 0, 26); +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); + +  // Sign-extend the 26-bit immediate. +  if (imm & (1 << (26 - 1))) +    imm |= ~((1LL << 26) - 1); + +  if (!Dis->tryAddingSymbolicOperand(Inst, imm << 2, Addr, true, 0, 4)) +    Inst.addOperand(MCOperand::CreateImm(imm)); + +  return Success; +} + +static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst, +                                                  uint32_t insn, uint64_t Addr, +                                                  const void *Decoder) { +  uint64_t op1 = fieldFromInstruction(insn, 16, 3); +  uint64_t op2 = fieldFromInstruction(insn, 5, 3); +  uint64_t crm = fieldFromInstruction(insn, 8, 4); + +  uint64_t pstate_field = (op1 << 3) | op2; + +  Inst.addOperand(MCOperand::CreateImm(pstate_field)); +  Inst.addOperand(MCOperand::CreateImm(crm)); + +  bool ValidNamed; +  (void)AArch64PState::PStateMapper().toString(pstate_field, ValidNamed); +   +  return ValidNamed ? Success : Fail;  } +static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn, +                                        uint64_t Addr, const void *Decoder) { +  uint64_t Rt = fieldFromInstruction(insn, 0, 5); +  uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5; +  bit |= fieldFromInstruction(insn, 19, 5); +  int64_t dst = fieldFromInstruction(insn, 5, 14); +  const AArch64Disassembler *Dis = +      static_cast<const AArch64Disassembler *>(Decoder); + +  // Sign-extend 14-bit immediate. +  if (dst & (1 << (14 - 1))) +    dst |= ~((1LL << 14) - 1); + +  if (fieldFromInstruction(insn, 31, 1) == 0) +    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); +  else +    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); +  Inst.addOperand(MCOperand::CreateImm(bit)); +  if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4)) +    Inst.addOperand(MCOperand::CreateImm(dst)); + +  return Success; +}  | 
