10b57cec5SDimitry Andric //===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "ARMBaseInstrInfo.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/ARMAddressingModes.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/ARMBaseInfo.h"
120b57cec5SDimitry Andric #include "MCTargetDesc/ARMMCTargetDesc.h"
130b57cec5SDimitry Andric #include "TargetInfo/ARMTargetInfo.h"
140b57cec5SDimitry Andric #include "Utils/ARMBaseInfo.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/SubtargetFeature.h"
220b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
230b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
240b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
250b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h"
260b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
270b57cec5SDimitry Andric #include <algorithm>
280b57cec5SDimitry Andric #include <cassert>
290b57cec5SDimitry Andric #include <cstdint>
300b57cec5SDimitry Andric #include <vector>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric using namespace llvm;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric #define DEBUG_TYPE "arm-disassembler"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric namespace {
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   // Handles the condition code status of instructions in IT blocks
410b57cec5SDimitry Andric   class ITStatus
420b57cec5SDimitry Andric   {
430b57cec5SDimitry Andric     public:
440b57cec5SDimitry Andric       // Returns the condition code for instruction in IT block
getITCC()450b57cec5SDimitry Andric       unsigned getITCC() {
460b57cec5SDimitry Andric         unsigned CC = ARMCC::AL;
470b57cec5SDimitry Andric         if (instrInITBlock())
480b57cec5SDimitry Andric           CC = ITStates.back();
490b57cec5SDimitry Andric         return CC;
500b57cec5SDimitry Andric       }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric       // Advances the IT block state to the next T or E
advanceITState()530b57cec5SDimitry Andric       void advanceITState() {
540b57cec5SDimitry Andric         ITStates.pop_back();
550b57cec5SDimitry Andric       }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric       // Returns true if the current instruction is in an IT block
instrInITBlock()580b57cec5SDimitry Andric       bool instrInITBlock() {
590b57cec5SDimitry Andric         return !ITStates.empty();
600b57cec5SDimitry Andric       }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric       // Returns true if current instruction is the last instruction in an IT block
instrLastInITBlock()630b57cec5SDimitry Andric       bool instrLastInITBlock() {
640b57cec5SDimitry Andric         return ITStates.size() == 1;
650b57cec5SDimitry Andric       }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric       // Called when decoding an IT instruction. Sets the IT state for
680b57cec5SDimitry Andric       // the following instructions that for the IT block. Firstcond
690b57cec5SDimitry Andric       // corresponds to the field in the IT instruction encoding; Mask
700b57cec5SDimitry Andric       // is in the MCOperand format in which 1 means 'else' and 0 'then'.
setITState(char Firstcond,char Mask)710b57cec5SDimitry Andric       void setITState(char Firstcond, char Mask) {
720b57cec5SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
730b57cec5SDimitry Andric         unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
740b57cec5SDimitry Andric         unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
750b57cec5SDimitry Andric         assert(NumTZ <= 3 && "Invalid IT mask!");
760b57cec5SDimitry Andric         // push condition codes onto the stack the correct order for the pops
770b57cec5SDimitry Andric         for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
780b57cec5SDimitry Andric           unsigned Else = (Mask >> Pos) & 1;
790b57cec5SDimitry Andric           ITStates.push_back(CCBits ^ Else);
800b57cec5SDimitry Andric         }
810b57cec5SDimitry Andric         ITStates.push_back(CCBits);
820b57cec5SDimitry Andric       }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric     private:
850b57cec5SDimitry Andric       std::vector<unsigned char> ITStates;
860b57cec5SDimitry Andric   };
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   class VPTStatus
890b57cec5SDimitry Andric   {
900b57cec5SDimitry Andric     public:
getVPTPred()910b57cec5SDimitry Andric       unsigned getVPTPred() {
920b57cec5SDimitry Andric         unsigned Pred = ARMVCC::None;
930b57cec5SDimitry Andric         if (instrInVPTBlock())
940b57cec5SDimitry Andric           Pred = VPTStates.back();
950b57cec5SDimitry Andric         return Pred;
960b57cec5SDimitry Andric       }
970b57cec5SDimitry Andric 
advanceVPTState()980b57cec5SDimitry Andric       void advanceVPTState() {
990b57cec5SDimitry Andric         VPTStates.pop_back();
1000b57cec5SDimitry Andric       }
1010b57cec5SDimitry Andric 
instrInVPTBlock()1020b57cec5SDimitry Andric       bool instrInVPTBlock() {
1030b57cec5SDimitry Andric         return !VPTStates.empty();
1040b57cec5SDimitry Andric       }
1050b57cec5SDimitry Andric 
instrLastInVPTBlock()1060b57cec5SDimitry Andric       bool instrLastInVPTBlock() {
1070b57cec5SDimitry Andric         return VPTStates.size() == 1;
1080b57cec5SDimitry Andric       }
1090b57cec5SDimitry Andric 
setVPTState(char Mask)1100b57cec5SDimitry Andric       void setVPTState(char Mask) {
1110b57cec5SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
1120b57cec5SDimitry Andric         unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
1130b57cec5SDimitry Andric         assert(NumTZ <= 3 && "Invalid VPT mask!");
1140b57cec5SDimitry Andric         // push predicates onto the stack the correct order for the pops
1150b57cec5SDimitry Andric         for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
1160b57cec5SDimitry Andric           bool T = ((Mask >> Pos) & 1) == 0;
1170b57cec5SDimitry Andric           if (T)
1180b57cec5SDimitry Andric             VPTStates.push_back(ARMVCC::Then);
1190b57cec5SDimitry Andric           else
1200b57cec5SDimitry Andric             VPTStates.push_back(ARMVCC::Else);
1210b57cec5SDimitry Andric         }
1220b57cec5SDimitry Andric         VPTStates.push_back(ARMVCC::Then);
1230b57cec5SDimitry Andric       }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric     private:
1260b57cec5SDimitry Andric       SmallVector<unsigned char, 4> VPTStates;
1270b57cec5SDimitry Andric   };
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric /// ARM disassembler for all ARM platforms.
1300b57cec5SDimitry Andric class ARMDisassembler : public MCDisassembler {
1310b57cec5SDimitry Andric public:
ARMDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)1320b57cec5SDimitry Andric   ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
1330b57cec5SDimitry Andric     MCDisassembler(STI, Ctx) {
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   ~ARMDisassembler() override = default;
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
1390b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
1400b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric private:
1430b57cec5SDimitry Andric   DecodeStatus getARMInstruction(MCInst &Instr, uint64_t &Size,
1440b57cec5SDimitry Andric                                  ArrayRef<uint8_t> Bytes, uint64_t Address,
1450b57cec5SDimitry Andric                                  raw_ostream &CStream) const;
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   DecodeStatus getThumbInstruction(MCInst &Instr, uint64_t &Size,
1480b57cec5SDimitry Andric                                    ArrayRef<uint8_t> Bytes, uint64_t Address,
1490b57cec5SDimitry Andric                                    raw_ostream &CStream) const;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   mutable ITStatus ITBlock;
1520b57cec5SDimitry Andric   mutable VPTStatus VPTBlock;
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   DecodeStatus AddThumbPredicate(MCInst&) const;
1550b57cec5SDimitry Andric   void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const;
1560b57cec5SDimitry Andric };
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric } // end anonymous namespace
1590b57cec5SDimitry Andric 
Check(DecodeStatus & Out,DecodeStatus In)1600b57cec5SDimitry Andric static bool Check(DecodeStatus &Out, DecodeStatus In) {
1610b57cec5SDimitry Andric   switch (In) {
1620b57cec5SDimitry Andric     case MCDisassembler::Success:
1630b57cec5SDimitry Andric       // Out stays the same.
1640b57cec5SDimitry Andric       return true;
1650b57cec5SDimitry Andric     case MCDisassembler::SoftFail:
1660b57cec5SDimitry Andric       Out = In;
1670b57cec5SDimitry Andric       return true;
1680b57cec5SDimitry Andric     case MCDisassembler::Fail:
1690b57cec5SDimitry Andric       Out = In;
1700b57cec5SDimitry Andric       return false;
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric   llvm_unreachable("Invalid DecodeStatus!");
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric // Forward declare these because the autogenerated code will reference them.
1760b57cec5SDimitry Andric // Definitions are further down.
1770b57cec5SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1780b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
1790b57cec5SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1800b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
1810b57cec5SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
1820b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
1830b57cec5SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
1840b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
1855ffd83dbSDimitry Andric static DecodeStatus
1865ffd83dbSDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
1875ffd83dbSDimitry Andric                                         uint64_t Address, const void *Decoder);
1880b57cec5SDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
1890b57cec5SDimitry Andric                                                unsigned RegNo, uint64_t Address,
1900b57cec5SDimitry Andric                                                const void *Decoder);
1910b57cec5SDimitry Andric static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
1920b57cec5SDimitry Andric                                                unsigned RegNo, uint64_t Address,
1930b57cec5SDimitry Andric                                                const void *Decoder);
1940b57cec5SDimitry Andric static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst,
1950b57cec5SDimitry Andric                                                unsigned RegNo, uint64_t Address,
1960b57cec5SDimitry Andric                                                const void *Decoder);
1970b57cec5SDimitry Andric static DecodeStatus DecodeGPRwithZRnospRegisterClass(
1980b57cec5SDimitry Andric     MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder);
1990b57cec5SDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
2000b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2010b57cec5SDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
2020b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2030b57cec5SDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
2040b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2050b57cec5SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
2060b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2075ffd83dbSDimitry Andric static DecodeStatus DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo,
2085ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder);
209480093f4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
210480093f4SDimitry Andric                                              uint64_t Address,
211480093f4SDimitry Andric                                              const void *Decoder);
2120b57cec5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
2130b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2140b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
2150b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2160b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
2170b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2180b57cec5SDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
2190b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2200b57cec5SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
2210b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2220b57cec5SDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
2230b57cec5SDimitry Andric                                                 unsigned RegNo,
2240b57cec5SDimitry Andric                                                 uint64_t Address,
2250b57cec5SDimitry Andric                                                 const void *Decoder);
2260b57cec5SDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
2270b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2280b57cec5SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
2290b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2300b57cec5SDimitry Andric static DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
2310b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2320b57cec5SDimitry Andric static DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
2330b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2340b57cec5SDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
2350b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder);
2360b57cec5SDimitry Andric static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
2370b57cec5SDimitry Andric                                unsigned RegNo, uint64_t Address,
2380b57cec5SDimitry Andric                                const void *Decoder);
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
2410b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2420b57cec5SDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
2430b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2440b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
2450b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2460b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
2470b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2480b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
2490b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
2520b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2530b57cec5SDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
2540b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2550b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
2560b57cec5SDimitry Andric                                                   unsigned Insn,
2570b57cec5SDimitry Andric                                                   uint64_t Address,
2580b57cec5SDimitry Andric                                                   const void *Decoder);
2590b57cec5SDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
2600b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2610b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
2620b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2630b57cec5SDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
2640b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2650b57cec5SDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
2660b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
2690b57cec5SDimitry Andric                                                   unsigned Insn,
2700b57cec5SDimitry Andric                                                   uint64_t Adddress,
2710b57cec5SDimitry Andric                                                   const void *Decoder);
2720b57cec5SDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2730b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2740b57cec5SDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2750b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2760b57cec5SDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2770b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2780b57cec5SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
2790b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2800b57cec5SDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
2810b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2820b57cec5SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
2830b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2840b57cec5SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
2850b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2860b57cec5SDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2870b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2880b57cec5SDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2890b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2900b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2910b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2920b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
2930b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2940b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2950b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2960b57cec5SDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2970b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
2980b57cec5SDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
2990b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3000b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
3010b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3020b57cec5SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
3030b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3040b57cec5SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
3050b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3060b57cec5SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
3070b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3080b57cec5SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
3090b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3100b57cec5SDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
3110b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3120b57cec5SDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
3130b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3140b57cec5SDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
3150b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3160b57cec5SDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
3170b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3180b57cec5SDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
3190b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3200b57cec5SDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
3210b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3228bcb0991SDimitry Andric static DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst,unsigned Val,
3230b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3240b57cec5SDimitry Andric static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst,unsigned Val,
3250b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3260b57cec5SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
3270b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3280b57cec5SDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
3290b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3300b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
3310b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3320b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
3330b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3340b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
3350b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3360b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
3370b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3380b57cec5SDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
3390b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3400b57cec5SDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
3410b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3420b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
3430b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3440b57cec5SDimitry Andric template<int shift>
3450b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
3460b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3470b57cec5SDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
3480b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3490b57cec5SDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
3500b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3510b57cec5SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
3520b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3530b57cec5SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
3540b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3550b57cec5SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
3560b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3570b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
3580b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3590b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
3600b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3610b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
3620b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3630b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
3640b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3650b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
3660b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3670b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
3680b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3690b57cec5SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
3700b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3710b57cec5SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
3720b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3730b57cec5SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
3740b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3750b57cec5SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
3760b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3770b57cec5SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
3780b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3790b57cec5SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
3800b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3810b57cec5SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
3820b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3830b57cec5SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
3840b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3850b57cec5SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
3860b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3870b57cec5SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
3880b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3890b57cec5SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
3900b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
3910b57cec5SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
3920b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
3930b57cec5SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
3940b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
3950b57cec5SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Insn,
3960b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder);
3970b57cec5SDimitry Andric static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
3980b57cec5SDimitry Andric                                                        unsigned Val,
3990b57cec5SDimitry Andric                                                        uint64_t Address,
4000b57cec5SDimitry Andric                                                        const void *Decoder);
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
4030b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4040b57cec5SDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
4050b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4060b57cec5SDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
4070b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4080b57cec5SDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
4090b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4100b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
4110b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4120b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
4130b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4140b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
4150b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4160b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
4170b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4180b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
4190b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4200b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
4210b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4220b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
4230b57cec5SDimitry Andric                                uint64_t Address, const void* Decoder);
4240b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
4250b57cec5SDimitry Andric                                uint64_t Address, const void* Decoder);
4260b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
4270b57cec5SDimitry Andric                                uint64_t Address, const void* Decoder);
4280b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
4290b57cec5SDimitry Andric                                uint64_t Address, const void* Decoder);
4300b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
4310b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4320b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val,
4330b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4340b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
4350b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4360b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
4370b57cec5SDimitry Andric                                            uint64_t Address,
4380b57cec5SDimitry Andric                                            const void *Decoder);
4390b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
4400b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4410b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
4420b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4430b57cec5SDimitry Andric template<int shift>
4440b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val,
4450b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4460b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
4470b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4480b57cec5SDimitry Andric template<int shift>
4490b57cec5SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
4500b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4510b57cec5SDimitry Andric template<int shift, int WriteBack>
4520b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
4530b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4540b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
4550b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4560b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
4570b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4580b57cec5SDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
4590b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4600b57cec5SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
4610b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4620b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
4630b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4640b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
4650b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4660b57cec5SDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
4670b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4680b57cec5SDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
4690b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4700b57cec5SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
4710b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4720b57cec5SDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
4730b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4740b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
4750b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4760b57cec5SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
4770b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4780b57cec5SDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
4790b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4800b57cec5SDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
4810b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder);
4820b57cec5SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
4830b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4840b57cec5SDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
4850b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4860b57cec5SDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
4870b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
4900b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder);
4910b57cec5SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
4920b57cec5SDimitry Andric                                             uint64_t Address, const void *Decoder);
4930b57cec5SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
4940b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder);
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
4970b57cec5SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned val,
4980b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder);
4990b57cec5SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned val,
5000b57cec5SDimitry Andric                                                uint64_t Address,
5010b57cec5SDimitry Andric                                                const void *Decoder);
5020b57cec5SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
5030b57cec5SDimitry Andric                                           uint64_t Address,
5040b57cec5SDimitry Andric                                           const void *Decoder);
5050b57cec5SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
5060b57cec5SDimitry Andric                                  const void *Decoder);
5070b57cec5SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
5080b57cec5SDimitry Andric                                            uint64_t Address,
5090b57cec5SDimitry Andric                                            const void *Decoder);
5100b57cec5SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
5110b57cec5SDimitry Andric                                   const void *Decoder);
5120b57cec5SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
5130b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder);
5140b57cec5SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val,
5150b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder);
5160b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val,
5170b57cec5SDimitry Andric                                                      uint64_t Address,
5180b57cec5SDimitry Andric                                                      const void *Decoder);
5190b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val,
5200b57cec5SDimitry Andric                                                      uint64_t Address,
5210b57cec5SDimitry Andric                                                      const void *Decoder);
5220b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val,
5230b57cec5SDimitry Andric                                                      uint64_t Address,
5240b57cec5SDimitry Andric                                                      const void *Decoder);
5250b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst,
5260b57cec5SDimitry Andric                                                        unsigned Val,
5270b57cec5SDimitry Andric                                                        uint64_t Address,
5280b57cec5SDimitry Andric                                                        const void *Decoder);
5290b57cec5SDimitry Andric template<bool Writeback>
5300b57cec5SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn,
5310b57cec5SDimitry Andric                                           uint64_t Address,
5320b57cec5SDimitry Andric                                           const void *Decoder);
5330b57cec5SDimitry Andric template<int shift>
5340b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
5350b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder);
5360b57cec5SDimitry Andric template<int shift>
5370b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
5380b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder);
5390b57cec5SDimitry Andric template<int shift>
5400b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
5410b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder);
5420b57cec5SDimitry Andric template<unsigned MinLog, unsigned MaxLog>
5430b57cec5SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
5440b57cec5SDimitry Andric                                           uint64_t Address,
5450b57cec5SDimitry Andric                                           const void *Decoder);
5460b57cec5SDimitry Andric template<unsigned start>
5470b57cec5SDimitry Andric static DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val,
5480b57cec5SDimitry Andric                                                     uint64_t Address,
5490b57cec5SDimitry Andric                                                     const void *Decoder);
5500b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
5510b57cec5SDimitry Andric                                          uint64_t Address,
5520b57cec5SDimitry Andric                                          const void *Decoder);
5530b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
5540b57cec5SDimitry Andric                                          uint64_t Address,
5550b57cec5SDimitry Andric                                          const void *Decoder);
5560b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
5570b57cec5SDimitry Andric                                       uint64_t Address, const void *Decoder);
5580b57cec5SDimitry Andric typedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val,
5590b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder);
5600b57cec5SDimitry Andric template<bool scalar, OperandDecoder predicate_decoder>
5610b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn,
5620b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder);
5630b57cec5SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn,
5640b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder);
5658bcb0991SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
5668bcb0991SDimitry Andric                                    uint64_t Address, const void *Decoder);
5670b57cec5SDimitry Andric static DecodeStatus DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn,
5680b57cec5SDimitry Andric                                                   uint64_t Address,
5690b57cec5SDimitry Andric                                                   const void *Decoder);
570480093f4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
571480093f4SDimitry Andric                                         uint64_t Address, const void *Decoder);
572480093f4SDimitry Andric 
5730b57cec5SDimitry Andric #include "ARMGenDisassemblerTables.inc"
5740b57cec5SDimitry Andric 
createARMDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)5750b57cec5SDimitry Andric static MCDisassembler *createARMDisassembler(const Target &T,
5760b57cec5SDimitry Andric                                              const MCSubtargetInfo &STI,
5770b57cec5SDimitry Andric                                              MCContext &Ctx) {
5780b57cec5SDimitry Andric   return new ARMDisassembler(STI, Ctx);
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric // Post-decoding checks
checkDecodedInstruction(MCInst & MI,uint64_t & Size,uint64_t Address,raw_ostream & CS,uint32_t Insn,DecodeStatus Result)5820b57cec5SDimitry Andric static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
583480093f4SDimitry Andric                                             uint64_t Address, raw_ostream &CS,
5840b57cec5SDimitry Andric                                             uint32_t Insn,
5850b57cec5SDimitry Andric                                             DecodeStatus Result) {
5860b57cec5SDimitry Andric   switch (MI.getOpcode()) {
5870b57cec5SDimitry Andric     case ARM::HVC: {
5880b57cec5SDimitry Andric       // HVC is undefined if condition = 0xf otherwise upredictable
5890b57cec5SDimitry Andric       // if condition != 0xe
5900b57cec5SDimitry Andric       uint32_t Cond = (Insn >> 28) & 0xF;
5910b57cec5SDimitry Andric       if (Cond == 0xF)
5920b57cec5SDimitry Andric         return MCDisassembler::Fail;
5930b57cec5SDimitry Andric       if (Cond != 0xE)
5940b57cec5SDimitry Andric         return MCDisassembler::SoftFail;
5950b57cec5SDimitry Andric       return Result;
5960b57cec5SDimitry Andric     }
5970b57cec5SDimitry Andric     case ARM::t2ADDri:
5980b57cec5SDimitry Andric     case ARM::t2ADDri12:
5990b57cec5SDimitry Andric     case ARM::t2ADDrr:
6000b57cec5SDimitry Andric     case ARM::t2ADDrs:
6010b57cec5SDimitry Andric     case ARM::t2SUBri:
6020b57cec5SDimitry Andric     case ARM::t2SUBri12:
6030b57cec5SDimitry Andric     case ARM::t2SUBrr:
6040b57cec5SDimitry Andric     case ARM::t2SUBrs:
6050b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == ARM::SP &&
6060b57cec5SDimitry Andric           MI.getOperand(1).getReg() != ARM::SP)
6070b57cec5SDimitry Andric         return MCDisassembler::SoftFail;
6080b57cec5SDimitry Andric       return Result;
6090b57cec5SDimitry Andric     default: return Result;
6100b57cec5SDimitry Andric   }
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const6130b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
6140b57cec5SDimitry Andric                                              ArrayRef<uint8_t> Bytes,
615480093f4SDimitry Andric                                              uint64_t Address,
6160b57cec5SDimitry Andric                                              raw_ostream &CS) const {
6170b57cec5SDimitry Andric   if (STI.getFeatureBits()[ARM::ModeThumb])
618480093f4SDimitry Andric     return getThumbInstruction(MI, Size, Bytes, Address, CS);
619480093f4SDimitry Andric   return getARMInstruction(MI, Size, Bytes, Address, CS);
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric 
getARMInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const6220b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
6230b57cec5SDimitry Andric                                                 ArrayRef<uint8_t> Bytes,
6240b57cec5SDimitry Andric                                                 uint64_t Address,
6250b57cec5SDimitry Andric                                                 raw_ostream &CS) const {
6260b57cec5SDimitry Andric   CommentStream = &CS;
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   assert(!STI.getFeatureBits()[ARM::ModeThumb] &&
6290b57cec5SDimitry Andric          "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
6300b57cec5SDimitry Andric          "mode!");
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
6330b57cec5SDimitry Andric   if (Bytes.size() < 4) {
6340b57cec5SDimitry Andric     Size = 0;
6350b57cec5SDimitry Andric     return MCDisassembler::Fail;
6360b57cec5SDimitry Andric   }
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric   // Encoded as a small-endian 32-bit word in the stream.
6390b57cec5SDimitry Andric   uint32_t Insn =
6400b57cec5SDimitry Andric       (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   // Calling the auto-generated decoder function.
6430b57cec5SDimitry Andric   DecodeStatus Result =
6440b57cec5SDimitry Andric       decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
6450b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
6460b57cec5SDimitry Andric     Size = 4;
647480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
6480b57cec5SDimitry Andric   }
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   struct DecodeTable {
6510b57cec5SDimitry Andric     const uint8_t *P;
6520b57cec5SDimitry Andric     bool DecodePred;
6530b57cec5SDimitry Andric   };
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric   const DecodeTable Tables[] = {
6560b57cec5SDimitry Andric       {DecoderTableVFP32, false},      {DecoderTableVFPV832, false},
6570b57cec5SDimitry Andric       {DecoderTableNEONData32, true},  {DecoderTableNEONLoadStore32, true},
6580b57cec5SDimitry Andric       {DecoderTableNEONDup32, true},   {DecoderTablev8NEON32, false},
6590b57cec5SDimitry Andric       {DecoderTablev8Crypto32, false},
6600b57cec5SDimitry Andric   };
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   for (auto Table : Tables) {
6630b57cec5SDimitry Andric     Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
6640b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
6650b57cec5SDimitry Andric       Size = 4;
6660b57cec5SDimitry Andric       // Add a fake predicate operand, because we share these instruction
6670b57cec5SDimitry Andric       // definitions with Thumb2 where these instructions are predicable.
6680b57cec5SDimitry Andric       if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
6690b57cec5SDimitry Andric         return MCDisassembler::Fail;
6700b57cec5SDimitry Andric       return Result;
6710b57cec5SDimitry Andric     }
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   Result =
6750b57cec5SDimitry Andric       decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
6760b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
6770b57cec5SDimitry Andric     Size = 4;
678480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
6790b57cec5SDimitry Andric   }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   Size = 4;
6820b57cec5SDimitry Andric   return MCDisassembler::Fail;
6830b57cec5SDimitry Andric }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric namespace llvm {
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric extern const MCInstrDesc ARMInsts[];
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric } // end namespace llvm
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
6920b57cec5SDimitry Andric /// immediate Value in the MCInst.  The immediate Value has had any PC
6930b57cec5SDimitry Andric /// adjustment made by the caller.  If the instruction is a branch instruction
6940b57cec5SDimitry Andric /// then isBranch is true, else false.  If the getOpInfo() function was set as
6950b57cec5SDimitry Andric /// part of the setupForSymbolicDisassembly() call then that function is called
6960b57cec5SDimitry Andric /// to get any symbolic information at the Address for this instruction.  If
6970b57cec5SDimitry Andric /// that returns non-zero then the symbolic information it returns is used to
6980b57cec5SDimitry Andric /// create an MCExpr and that is added as an operand to the MCInst.  If
6990b57cec5SDimitry Andric /// getOpInfo() returns zero and isBranch is true then a symbol look up for
7000b57cec5SDimitry Andric /// Value is done and if a symbol is found an MCExpr is created with that, else
7010b57cec5SDimitry Andric /// an MCExpr with Value is created.  This function returns true if it adds an
7020b57cec5SDimitry Andric /// operand to the MCInst and false otherwise.
tryAddingSymbolicOperand(uint64_t Address,int32_t Value,bool isBranch,uint64_t InstSize,MCInst & MI,const void * Decoder)7030b57cec5SDimitry Andric static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
7040b57cec5SDimitry Andric                                      bool isBranch, uint64_t InstSize,
7050b57cec5SDimitry Andric                                      MCInst &MI, const void *Decoder) {
7060b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
7070b57cec5SDimitry Andric   // FIXME: Does it make sense for value to be negative?
7080b57cec5SDimitry Andric   return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch,
7090b57cec5SDimitry Andric                                        /* Offset */ 0, InstSize);
7100b57cec5SDimitry Andric }
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
7130b57cec5SDimitry Andric /// referenced by a load instruction with the base register that is the Pc.
7140b57cec5SDimitry Andric /// These can often be values in a literal pool near the Address of the
7150b57cec5SDimitry Andric /// instruction.  The Address of the instruction and its immediate Value are
7160b57cec5SDimitry Andric /// used as a possible literal pool entry.  The SymbolLookUp call back will
7170b57cec5SDimitry Andric /// return the name of a symbol referenced by the literal pool's entry if
7180b57cec5SDimitry Andric /// the referenced address is that of a symbol.  Or it will return a pointer to
7190b57cec5SDimitry Andric /// a literal 'C' string if the referenced address of the literal pool's entry
7200b57cec5SDimitry Andric /// is an address into a section with 'C' string literals.
tryAddingPcLoadReferenceComment(uint64_t Address,int Value,const void * Decoder)7210b57cec5SDimitry Andric static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
7220b57cec5SDimitry Andric                                             const void *Decoder) {
7230b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
7240b57cec5SDimitry Andric   Dis->tryAddingPcLoadReferenceComment(Value, Address);
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric // Thumb1 instructions don't have explicit S bits.  Rather, they
7280b57cec5SDimitry Andric // implicitly set CPSR.  Since it's not represented in the encoding, the
7290b57cec5SDimitry Andric // auto-generated decoder won't inject the CPSR operand.  We need to fix
7300b57cec5SDimitry Andric // that as a post-pass.
AddThumb1SBit(MCInst & MI,bool InITBlock)7310b57cec5SDimitry Andric static void AddThumb1SBit(MCInst &MI, bool InITBlock) {
7320b57cec5SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
7330b57cec5SDimitry Andric   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
7340b57cec5SDimitry Andric   MCInst::iterator I = MI.begin();
7350b57cec5SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
7360b57cec5SDimitry Andric     if (I == MI.end()) break;
7370b57cec5SDimitry Andric     if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
7380b57cec5SDimitry Andric       if (i > 0 && OpInfo[i-1].isPredicate()) continue;
7390b57cec5SDimitry Andric       MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
7400b57cec5SDimitry Andric       return;
7410b57cec5SDimitry Andric     }
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric   MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
7450b57cec5SDimitry Andric }
7460b57cec5SDimitry Andric 
isVectorPredicable(unsigned Opcode)7470b57cec5SDimitry Andric static bool isVectorPredicable(unsigned Opcode) {
7480b57cec5SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
7490b57cec5SDimitry Andric   unsigned short NumOps = ARMInsts[Opcode].NumOperands;
7500b57cec5SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i) {
7510b57cec5SDimitry Andric     if (ARM::isVpred(OpInfo[i].OperandType))
7520b57cec5SDimitry Andric       return true;
7530b57cec5SDimitry Andric   }
7540b57cec5SDimitry Andric   return false;
7550b57cec5SDimitry Andric }
7560b57cec5SDimitry Andric 
7570b57cec5SDimitry Andric // Most Thumb instructions don't have explicit predicates in the
7580b57cec5SDimitry Andric // encoding, but rather get their predicates from IT context.  We need
7590b57cec5SDimitry Andric // to fix up the predicate operands using this context information as a
7600b57cec5SDimitry Andric // post-pass.
7610b57cec5SDimitry Andric MCDisassembler::DecodeStatus
AddThumbPredicate(MCInst & MI) const7620b57cec5SDimitry Andric ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
7630b57cec5SDimitry Andric   MCDisassembler::DecodeStatus S = Success;
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric   // A few instructions actually have predicates encoded in them.  Don't
7680b57cec5SDimitry Andric   // try to overwrite it if we're seeing one of those.
7690b57cec5SDimitry Andric   switch (MI.getOpcode()) {
7700b57cec5SDimitry Andric     case ARM::tBcc:
7710b57cec5SDimitry Andric     case ARM::t2Bcc:
7720b57cec5SDimitry Andric     case ARM::tCBZ:
7730b57cec5SDimitry Andric     case ARM::tCBNZ:
7740b57cec5SDimitry Andric     case ARM::tCPS:
7750b57cec5SDimitry Andric     case ARM::t2CPS3p:
7760b57cec5SDimitry Andric     case ARM::t2CPS2p:
7770b57cec5SDimitry Andric     case ARM::t2CPS1p:
7780b57cec5SDimitry Andric     case ARM::t2CSEL:
7790b57cec5SDimitry Andric     case ARM::t2CSINC:
7800b57cec5SDimitry Andric     case ARM::t2CSINV:
7810b57cec5SDimitry Andric     case ARM::t2CSNEG:
7820b57cec5SDimitry Andric     case ARM::tMOVSr:
7830b57cec5SDimitry Andric     case ARM::tSETEND:
7840b57cec5SDimitry Andric       // Some instructions (mostly conditional branches) are not
7850b57cec5SDimitry Andric       // allowed in IT blocks.
7860b57cec5SDimitry Andric       if (ITBlock.instrInITBlock())
7870b57cec5SDimitry Andric         S = SoftFail;
7880b57cec5SDimitry Andric       else
7890b57cec5SDimitry Andric         return Success;
7900b57cec5SDimitry Andric       break;
7910b57cec5SDimitry Andric     case ARM::t2HINT:
7920b57cec5SDimitry Andric       if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
7930b57cec5SDimitry Andric         S = SoftFail;
7940b57cec5SDimitry Andric       break;
7950b57cec5SDimitry Andric     case ARM::tB:
7960b57cec5SDimitry Andric     case ARM::t2B:
7970b57cec5SDimitry Andric     case ARM::t2TBB:
7980b57cec5SDimitry Andric     case ARM::t2TBH:
7990b57cec5SDimitry Andric       // Some instructions (mostly unconditional branches) can
8000b57cec5SDimitry Andric       // only appears at the end of, or outside of, an IT.
8010b57cec5SDimitry Andric       if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
8020b57cec5SDimitry Andric         S = SoftFail;
8030b57cec5SDimitry Andric       break;
8040b57cec5SDimitry Andric     default:
8050b57cec5SDimitry Andric       break;
8060b57cec5SDimitry Andric   }
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   // Warn on non-VPT predicable instruction in a VPT block and a VPT
8090b57cec5SDimitry Andric   // predicable instruction in an IT block
8100b57cec5SDimitry Andric   if ((!isVectorPredicable(MI.getOpcode()) && VPTBlock.instrInVPTBlock()) ||
8110b57cec5SDimitry Andric        (isVectorPredicable(MI.getOpcode()) && ITBlock.instrInITBlock()))
8120b57cec5SDimitry Andric     S = SoftFail;
8130b57cec5SDimitry Andric 
8140b57cec5SDimitry Andric   // If we're in an IT/VPT block, base the predicate on that.  Otherwise,
8150b57cec5SDimitry Andric   // assume a predicate of AL.
8160b57cec5SDimitry Andric   unsigned CC = ARMCC::AL;
8170b57cec5SDimitry Andric   unsigned VCC = ARMVCC::None;
8180b57cec5SDimitry Andric   if (ITBlock.instrInITBlock()) {
8190b57cec5SDimitry Andric     CC = ITBlock.getITCC();
8200b57cec5SDimitry Andric     ITBlock.advanceITState();
8210b57cec5SDimitry Andric   } else if (VPTBlock.instrInVPTBlock()) {
8220b57cec5SDimitry Andric     VCC = VPTBlock.getVPTPred();
8230b57cec5SDimitry Andric     VPTBlock.advanceVPTState();
8240b57cec5SDimitry Andric   }
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
8270b57cec5SDimitry Andric   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   MCInst::iterator CCI = MI.begin();
8300b57cec5SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++CCI) {
8310b57cec5SDimitry Andric     if (OpInfo[i].isPredicate() || CCI == MI.end()) break;
8320b57cec5SDimitry Andric   }
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric   if (ARMInsts[MI.getOpcode()].isPredicable()) {
8350b57cec5SDimitry Andric     CCI = MI.insert(CCI, MCOperand::createImm(CC));
8360b57cec5SDimitry Andric     ++CCI;
8370b57cec5SDimitry Andric     if (CC == ARMCC::AL)
8380b57cec5SDimitry Andric       MI.insert(CCI, MCOperand::createReg(0));
8390b57cec5SDimitry Andric     else
8400b57cec5SDimitry Andric       MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
8410b57cec5SDimitry Andric   } else if (CC != ARMCC::AL) {
8420b57cec5SDimitry Andric     Check(S, SoftFail);
8430b57cec5SDimitry Andric   }
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric   MCInst::iterator VCCI = MI.begin();
8460b57cec5SDimitry Andric   unsigned VCCPos;
8470b57cec5SDimitry Andric   for (VCCPos = 0; VCCPos < NumOps; ++VCCPos, ++VCCI) {
8480b57cec5SDimitry Andric     if (ARM::isVpred(OpInfo[VCCPos].OperandType) || VCCI == MI.end()) break;
8490b57cec5SDimitry Andric   }
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric   if (isVectorPredicable(MI.getOpcode())) {
8520b57cec5SDimitry Andric     VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
8530b57cec5SDimitry Andric     ++VCCI;
8540b57cec5SDimitry Andric     if (VCC == ARMVCC::None)
8550b57cec5SDimitry Andric       MI.insert(VCCI, MCOperand::createReg(0));
8560b57cec5SDimitry Andric     else
8570b57cec5SDimitry Andric       MI.insert(VCCI, MCOperand::createReg(ARM::P0));
8580b57cec5SDimitry Andric     if (OpInfo[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
8590b57cec5SDimitry Andric       int TiedOp = ARMInsts[MI.getOpcode()].getOperandConstraint(
8600b57cec5SDimitry Andric         VCCPos + 2, MCOI::TIED_TO);
8610b57cec5SDimitry Andric       assert(TiedOp >= 0 &&
8620b57cec5SDimitry Andric              "Inactive register in vpred_r is not tied to an output!");
863af732203SDimitry Andric       // Copy the operand to ensure it's not invalidated when MI grows.
864af732203SDimitry Andric       MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
8650b57cec5SDimitry Andric     }
8660b57cec5SDimitry Andric   } else if (VCC != ARMVCC::None) {
8670b57cec5SDimitry Andric     Check(S, SoftFail);
8680b57cec5SDimitry Andric   }
8690b57cec5SDimitry Andric 
8700b57cec5SDimitry Andric   return S;
8710b57cec5SDimitry Andric }
8720b57cec5SDimitry Andric 
8730b57cec5SDimitry Andric // Thumb VFP instructions are a special case.  Because we share their
8740b57cec5SDimitry Andric // encodings between ARM and Thumb modes, and they are predicable in ARM
8750b57cec5SDimitry Andric // mode, the auto-generated decoder will give them an (incorrect)
8760b57cec5SDimitry Andric // predicate operand.  We need to rewrite these operands based on the IT
8770b57cec5SDimitry Andric // context as a post-pass.
UpdateThumbVFPPredicate(DecodeStatus & S,MCInst & MI) const8780b57cec5SDimitry Andric void ARMDisassembler::UpdateThumbVFPPredicate(
8790b57cec5SDimitry Andric   DecodeStatus &S, MCInst &MI) const {
8800b57cec5SDimitry Andric   unsigned CC;
8810b57cec5SDimitry Andric   CC = ITBlock.getITCC();
8820b57cec5SDimitry Andric   if (CC == 0xF)
8830b57cec5SDimitry Andric     CC = ARMCC::AL;
8840b57cec5SDimitry Andric   if (ITBlock.instrInITBlock())
8850b57cec5SDimitry Andric     ITBlock.advanceITState();
8860b57cec5SDimitry Andric   else if (VPTBlock.instrInVPTBlock()) {
8870b57cec5SDimitry Andric     CC = VPTBlock.getVPTPred();
8880b57cec5SDimitry Andric     VPTBlock.advanceVPTState();
8890b57cec5SDimitry Andric   }
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
8920b57cec5SDimitry Andric   MCInst::iterator I = MI.begin();
8930b57cec5SDimitry Andric   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
8940b57cec5SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
8950b57cec5SDimitry Andric     if (OpInfo[i].isPredicate() ) {
8960b57cec5SDimitry Andric       if (CC != ARMCC::AL && !ARMInsts[MI.getOpcode()].isPredicable())
8970b57cec5SDimitry Andric         Check(S, SoftFail);
8980b57cec5SDimitry Andric       I->setImm(CC);
8990b57cec5SDimitry Andric       ++I;
9000b57cec5SDimitry Andric       if (CC == ARMCC::AL)
9010b57cec5SDimitry Andric         I->setReg(0);
9020b57cec5SDimitry Andric       else
9030b57cec5SDimitry Andric         I->setReg(ARM::CPSR);
9040b57cec5SDimitry Andric       return;
9050b57cec5SDimitry Andric     }
9060b57cec5SDimitry Andric   }
9070b57cec5SDimitry Andric }
9080b57cec5SDimitry Andric 
getThumbInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const9090b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
9100b57cec5SDimitry Andric                                                   ArrayRef<uint8_t> Bytes,
9110b57cec5SDimitry Andric                                                   uint64_t Address,
9120b57cec5SDimitry Andric                                                   raw_ostream &CS) const {
9130b57cec5SDimitry Andric   CommentStream = &CS;
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   assert(STI.getFeatureBits()[ARM::ModeThumb] &&
9160b57cec5SDimitry Andric          "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric   // We want to read exactly 2 bytes of data.
9190b57cec5SDimitry Andric   if (Bytes.size() < 2) {
9200b57cec5SDimitry Andric     Size = 0;
9210b57cec5SDimitry Andric     return MCDisassembler::Fail;
9220b57cec5SDimitry Andric   }
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric   uint16_t Insn16 = (Bytes[1] << 8) | Bytes[0];
9250b57cec5SDimitry Andric   DecodeStatus Result =
9260b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
9270b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
9280b57cec5SDimitry Andric     Size = 2;
9290b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
9300b57cec5SDimitry Andric     return Result;
9310b57cec5SDimitry Andric   }
9320b57cec5SDimitry Andric 
9330b57cec5SDimitry Andric   Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
9340b57cec5SDimitry Andric                              STI);
9350b57cec5SDimitry Andric   if (Result) {
9360b57cec5SDimitry Andric     Size = 2;
9370b57cec5SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
9380b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
9390b57cec5SDimitry Andric     AddThumb1SBit(MI, InITBlock);
9400b57cec5SDimitry Andric     return Result;
9410b57cec5SDimitry Andric   }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   Result =
9440b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
9450b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
9460b57cec5SDimitry Andric     Size = 2;
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric     // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
9490b57cec5SDimitry Andric     // the Thumb predicate.
9500b57cec5SDimitry Andric     if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
9510b57cec5SDimitry Andric       Result = MCDisassembler::SoftFail;
9520b57cec5SDimitry Andric 
9530b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric     // If we find an IT instruction, we need to parse its condition
9560b57cec5SDimitry Andric     // code and mask operands so that we can apply them correctly
9570b57cec5SDimitry Andric     // to the subsequent instructions.
9580b57cec5SDimitry Andric     if (MI.getOpcode() == ARM::t2IT) {
9590b57cec5SDimitry Andric       unsigned Firstcond = MI.getOperand(0).getImm();
9600b57cec5SDimitry Andric       unsigned Mask = MI.getOperand(1).getImm();
9610b57cec5SDimitry Andric       ITBlock.setITState(Firstcond, Mask);
9620b57cec5SDimitry Andric 
9630b57cec5SDimitry Andric       // An IT instruction that would give a 'NV' predicate is unpredictable.
9640b57cec5SDimitry Andric       if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
9650b57cec5SDimitry Andric         CS << "unpredictable IT predicate sequence";
9660b57cec5SDimitry Andric     }
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric     return Result;
9690b57cec5SDimitry Andric   }
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
9720b57cec5SDimitry Andric   if (Bytes.size() < 4) {
9730b57cec5SDimitry Andric     Size = 0;
9740b57cec5SDimitry Andric     return MCDisassembler::Fail;
9750b57cec5SDimitry Andric   }
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric   uint32_t Insn32 =
9780b57cec5SDimitry Andric       (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16);
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric   Result =
9810b57cec5SDimitry Andric       decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI);
9820b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
9830b57cec5SDimitry Andric     Size = 4;
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric     // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add
9860b57cec5SDimitry Andric     // the VPT predicate.
9870b57cec5SDimitry Andric     if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock())
9880b57cec5SDimitry Andric       Result = MCDisassembler::SoftFail;
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric     if (isVPTOpcode(MI.getOpcode())) {
9930b57cec5SDimitry Andric       unsigned Mask = MI.getOperand(0).getImm();
9940b57cec5SDimitry Andric       VPTBlock.setVPTState(Mask);
9950b57cec5SDimitry Andric     }
9960b57cec5SDimitry Andric 
9970b57cec5SDimitry Andric     return Result;
9980b57cec5SDimitry Andric   }
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric   Result =
10010b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
10020b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
10030b57cec5SDimitry Andric     Size = 4;
10040b57cec5SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
10050b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
10060b57cec5SDimitry Andric     AddThumb1SBit(MI, InITBlock);
10070b57cec5SDimitry Andric     return Result;
10080b57cec5SDimitry Andric   }
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric   Result =
10110b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
10120b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
10130b57cec5SDimitry Andric     Size = 4;
10140b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
1015480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn32, Result);
10160b57cec5SDimitry Andric   }
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
10190b57cec5SDimitry Andric     Result =
10200b57cec5SDimitry Andric         decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
10210b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
10220b57cec5SDimitry Andric       Size = 4;
10230b57cec5SDimitry Andric       UpdateThumbVFPPredicate(Result, MI);
10240b57cec5SDimitry Andric       return Result;
10250b57cec5SDimitry Andric     }
10260b57cec5SDimitry Andric   }
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric   Result =
10290b57cec5SDimitry Andric       decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
10300b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
10310b57cec5SDimitry Andric     Size = 4;
10320b57cec5SDimitry Andric     return Result;
10330b57cec5SDimitry Andric   }
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
10360b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
10370b57cec5SDimitry Andric                                STI);
10380b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
10390b57cec5SDimitry Andric       Size = 4;
10400b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
10410b57cec5SDimitry Andric       return Result;
10420b57cec5SDimitry Andric     }
10430b57cec5SDimitry Andric   }
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
10460b57cec5SDimitry Andric     uint32_t NEONLdStInsn = Insn32;
10470b57cec5SDimitry Andric     NEONLdStInsn &= 0xF0FFFFFF;
10480b57cec5SDimitry Andric     NEONLdStInsn |= 0x04000000;
10490b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
10500b57cec5SDimitry Andric                                Address, this, STI);
10510b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
10520b57cec5SDimitry Andric       Size = 4;
10530b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
10540b57cec5SDimitry Andric       return Result;
10550b57cec5SDimitry Andric     }
10560b57cec5SDimitry Andric   }
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
10590b57cec5SDimitry Andric     uint32_t NEONDataInsn = Insn32;
10600b57cec5SDimitry Andric     NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
10610b57cec5SDimitry Andric     NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
10620b57cec5SDimitry Andric     NEONDataInsn |= 0x12000000; // Set bits 28 and 25
10630b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
10640b57cec5SDimitry Andric                                Address, this, STI);
10650b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
10660b57cec5SDimitry Andric       Size = 4;
10670b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
10680b57cec5SDimitry Andric       return Result;
10690b57cec5SDimitry Andric     }
10700b57cec5SDimitry Andric 
10710b57cec5SDimitry Andric     uint32_t NEONCryptoInsn = Insn32;
10720b57cec5SDimitry Andric     NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
10730b57cec5SDimitry Andric     NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
10740b57cec5SDimitry Andric     NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
10750b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
10760b57cec5SDimitry Andric                                Address, this, STI);
10770b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
10780b57cec5SDimitry Andric       Size = 4;
10790b57cec5SDimitry Andric       return Result;
10800b57cec5SDimitry Andric     }
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric     uint32_t NEONv8Insn = Insn32;
10830b57cec5SDimitry Andric     NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
10840b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
10850b57cec5SDimitry Andric                                this, STI);
10860b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
10870b57cec5SDimitry Andric       Size = 4;
10880b57cec5SDimitry Andric       return Result;
10890b57cec5SDimitry Andric     }
10900b57cec5SDimitry Andric   }
10910b57cec5SDimitry Andric 
10925ffd83dbSDimitry Andric   uint32_t Coproc = fieldFromInstruction(Insn32, 8, 4);
10935ffd83dbSDimitry Andric   const uint8_t *DecoderTable = ARM::isCDECoproc(Coproc, STI)
10945ffd83dbSDimitry Andric                                     ? DecoderTableThumb2CDE32
10955ffd83dbSDimitry Andric                                     : DecoderTableThumb2CoProc32;
10960b57cec5SDimitry Andric   Result =
10975ffd83dbSDimitry Andric       decodeInstruction(DecoderTable, MI, Insn32, Address, this, STI);
10980b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
10990b57cec5SDimitry Andric     Size = 4;
11000b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11010b57cec5SDimitry Andric     return Result;
11020b57cec5SDimitry Andric   }
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric   Size = 0;
11050b57cec5SDimitry Andric   return MCDisassembler::Fail;
11060b57cec5SDimitry Andric }
11070b57cec5SDimitry Andric 
LLVMInitializeARMDisassembler()1108480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMDisassembler() {
11090b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(),
11100b57cec5SDimitry Andric                                          createARMDisassembler);
11110b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(),
11120b57cec5SDimitry Andric                                          createARMDisassembler);
11130b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(),
11140b57cec5SDimitry Andric                                          createARMDisassembler);
11150b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(),
11160b57cec5SDimitry Andric                                          createARMDisassembler);
11170b57cec5SDimitry Andric }
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric static const uint16_t GPRDecoderTable[] = {
11200b57cec5SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
11210b57cec5SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
11220b57cec5SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
11230b57cec5SDimitry Andric   ARM::R12, ARM::SP, ARM::LR, ARM::PC
11240b57cec5SDimitry Andric };
11250b57cec5SDimitry Andric 
11260b57cec5SDimitry Andric static const uint16_t CLRMGPRDecoderTable[] = {
11270b57cec5SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
11280b57cec5SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
11290b57cec5SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
11300b57cec5SDimitry Andric   ARM::R12, 0, ARM::LR, ARM::APSR
11310b57cec5SDimitry Andric };
11320b57cec5SDimitry Andric 
DecodeGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)11330b57cec5SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
11340b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
11350b57cec5SDimitry Andric   if (RegNo > 15)
11360b57cec5SDimitry Andric     return MCDisassembler::Fail;
11370b57cec5SDimitry Andric 
11380b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
11390b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
11400b57cec5SDimitry Andric   return MCDisassembler::Success;
11410b57cec5SDimitry Andric }
11420b57cec5SDimitry Andric 
DecodeCLRMGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)11430b57cec5SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
11440b57cec5SDimitry Andric                                                uint64_t Address,
11450b57cec5SDimitry Andric                                                const void *Decoder) {
11460b57cec5SDimitry Andric   if (RegNo > 15)
11470b57cec5SDimitry Andric     return MCDisassembler::Fail;
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric   unsigned Register = CLRMGPRDecoderTable[RegNo];
11500b57cec5SDimitry Andric   if (Register == 0)
11510b57cec5SDimitry Andric     return MCDisassembler::Fail;
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
11540b57cec5SDimitry Andric   return MCDisassembler::Success;
11550b57cec5SDimitry Andric }
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric static DecodeStatus
DecodeGPRnopcRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)11580b57cec5SDimitry Andric DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
11590b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
11600b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric   if (RegNo == 15)
11630b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric   return S;
11680b57cec5SDimitry Andric }
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric static DecodeStatus
DecodeGPRwithAPSRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)11710b57cec5SDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
11720b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
11730b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric   if (RegNo == 15)
11760b57cec5SDimitry Andric   {
11770b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
11780b57cec5SDimitry Andric     return MCDisassembler::Success;
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
11820b57cec5SDimitry Andric   return S;
11830b57cec5SDimitry Andric }
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric static DecodeStatus
DecodeGPRwithZRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)11860b57cec5SDimitry Andric DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo,
11870b57cec5SDimitry Andric                              uint64_t Address, const void *Decoder) {
11880b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric   if (RegNo == 15)
11910b57cec5SDimitry Andric   {
11920b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::ZR));
11930b57cec5SDimitry Andric     return MCDisassembler::Success;
11940b57cec5SDimitry Andric   }
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric   if (RegNo == 13)
11970b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
11980b57cec5SDimitry Andric 
11990b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
12000b57cec5SDimitry Andric   return S;
12010b57cec5SDimitry Andric }
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric static DecodeStatus
DecodeGPRwithZRnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)12040b57cec5SDimitry Andric DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo,
12050b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
12060b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
12070b57cec5SDimitry Andric   if (RegNo == 13)
12080b57cec5SDimitry Andric     return MCDisassembler::Fail;
12090b57cec5SDimitry Andric   Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder));
12100b57cec5SDimitry Andric   return S;
12110b57cec5SDimitry Andric }
12120b57cec5SDimitry Andric 
DecodetGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)12130b57cec5SDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
12140b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
12150b57cec5SDimitry Andric   if (RegNo > 7)
12160b57cec5SDimitry Andric     return MCDisassembler::Fail;
12170b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
12180b57cec5SDimitry Andric }
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
12210b57cec5SDimitry Andric   ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
12220b57cec5SDimitry Andric   ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
12230b57cec5SDimitry Andric };
12240b57cec5SDimitry Andric 
DecodeGPRPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)12250b57cec5SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
12260b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
12270b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
12280b57cec5SDimitry Andric 
12295ffd83dbSDimitry Andric   // According to the Arm ARM RegNo = 14 is undefined, but we return fail
12305ffd83dbSDimitry Andric   // rather than SoftFail as there is no GPRPair table entry for index 7.
12310b57cec5SDimitry Andric   if (RegNo > 13)
12320b57cec5SDimitry Andric     return MCDisassembler::Fail;
12330b57cec5SDimitry Andric 
12345ffd83dbSDimitry Andric   if (RegNo & 1)
12350b57cec5SDimitry Andric      S = MCDisassembler::SoftFail;
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
12380b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
12390b57cec5SDimitry Andric   return S;
12400b57cec5SDimitry Andric }
12410b57cec5SDimitry Andric 
DecodeGPRPairnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)12425ffd83dbSDimitry Andric static DecodeStatus DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo,
12435ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder) {
12445ffd83dbSDimitry Andric   if (RegNo > 13)
12455ffd83dbSDimitry Andric     return MCDisassembler::Fail;
12465ffd83dbSDimitry Andric 
12475ffd83dbSDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
12485ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
12495ffd83dbSDimitry Andric 
12505ffd83dbSDimitry Andric   if ((RegNo & 1) || RegNo > 10)
12515ffd83dbSDimitry Andric      return MCDisassembler::SoftFail;
12525ffd83dbSDimitry Andric   return MCDisassembler::Success;
12535ffd83dbSDimitry Andric }
12545ffd83dbSDimitry Andric 
DecodeGPRspRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1255480093f4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
1256480093f4SDimitry Andric                                              uint64_t Address,
1257480093f4SDimitry Andric                                              const void *Decoder) {
1258480093f4SDimitry Andric   if (RegNo != 13)
1259480093f4SDimitry Andric     return MCDisassembler::Fail;
1260480093f4SDimitry Andric 
1261480093f4SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
1262480093f4SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
1263480093f4SDimitry Andric   return MCDisassembler::Success;
1264480093f4SDimitry Andric }
1265480093f4SDimitry Andric 
DecodetcGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)12660b57cec5SDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
12670b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
12680b57cec5SDimitry Andric   unsigned Register = 0;
12690b57cec5SDimitry Andric   switch (RegNo) {
12700b57cec5SDimitry Andric     case 0:
12710b57cec5SDimitry Andric       Register = ARM::R0;
12720b57cec5SDimitry Andric       break;
12730b57cec5SDimitry Andric     case 1:
12740b57cec5SDimitry Andric       Register = ARM::R1;
12750b57cec5SDimitry Andric       break;
12760b57cec5SDimitry Andric     case 2:
12770b57cec5SDimitry Andric       Register = ARM::R2;
12780b57cec5SDimitry Andric       break;
12790b57cec5SDimitry Andric     case 3:
12800b57cec5SDimitry Andric       Register = ARM::R3;
12810b57cec5SDimitry Andric       break;
12820b57cec5SDimitry Andric     case 9:
12830b57cec5SDimitry Andric       Register = ARM::R9;
12840b57cec5SDimitry Andric       break;
12850b57cec5SDimitry Andric     case 12:
12860b57cec5SDimitry Andric       Register = ARM::R12;
12870b57cec5SDimitry Andric       break;
12880b57cec5SDimitry Andric     default:
12890b57cec5SDimitry Andric       return MCDisassembler::Fail;
12900b57cec5SDimitry Andric     }
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
12930b57cec5SDimitry Andric   return MCDisassembler::Success;
12940b57cec5SDimitry Andric }
12950b57cec5SDimitry Andric 
DecoderGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)12960b57cec5SDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
12970b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
12980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric   const FeatureBitset &featureBits =
13010b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
13020b57cec5SDimitry Andric 
13030b57cec5SDimitry Andric   if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15)
13040b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
13050b57cec5SDimitry Andric 
13060b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13070b57cec5SDimitry Andric   return S;
13080b57cec5SDimitry Andric }
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric static const uint16_t SPRDecoderTable[] = {
13110b57cec5SDimitry Andric      ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
13120b57cec5SDimitry Andric      ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
13130b57cec5SDimitry Andric      ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
13140b57cec5SDimitry Andric     ARM::S12, ARM::S13, ARM::S14, ARM::S15,
13150b57cec5SDimitry Andric     ARM::S16, ARM::S17, ARM::S18, ARM::S19,
13160b57cec5SDimitry Andric     ARM::S20, ARM::S21, ARM::S22, ARM::S23,
13170b57cec5SDimitry Andric     ARM::S24, ARM::S25, ARM::S26, ARM::S27,
13180b57cec5SDimitry Andric     ARM::S28, ARM::S29, ARM::S30, ARM::S31
13190b57cec5SDimitry Andric };
13200b57cec5SDimitry Andric 
DecodeSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13210b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
13220b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
13230b57cec5SDimitry Andric   if (RegNo > 31)
13240b57cec5SDimitry Andric     return MCDisassembler::Fail;
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   unsigned Register = SPRDecoderTable[RegNo];
13270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13280b57cec5SDimitry Andric   return MCDisassembler::Success;
13290b57cec5SDimitry Andric }
13300b57cec5SDimitry Andric 
DecodeHPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13310b57cec5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
13320b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
13330b57cec5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
13340b57cec5SDimitry Andric }
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric static const uint16_t DPRDecoderTable[] = {
13370b57cec5SDimitry Andric      ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
13380b57cec5SDimitry Andric      ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
13390b57cec5SDimitry Andric      ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
13400b57cec5SDimitry Andric     ARM::D12, ARM::D13, ARM::D14, ARM::D15,
13410b57cec5SDimitry Andric     ARM::D16, ARM::D17, ARM::D18, ARM::D19,
13420b57cec5SDimitry Andric     ARM::D20, ARM::D21, ARM::D22, ARM::D23,
13430b57cec5SDimitry Andric     ARM::D24, ARM::D25, ARM::D26, ARM::D27,
13440b57cec5SDimitry Andric     ARM::D28, ARM::D29, ARM::D30, ARM::D31
13450b57cec5SDimitry Andric };
13460b57cec5SDimitry Andric 
DecodeDPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13470b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
13480b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
13490b57cec5SDimitry Andric   const FeatureBitset &featureBits =
13500b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric   bool hasD32 = featureBits[ARM::FeatureD32];
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric   if (RegNo > 31 || (!hasD32 && RegNo > 15))
13550b57cec5SDimitry Andric     return MCDisassembler::Fail;
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   unsigned Register = DPRDecoderTable[RegNo];
13580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13590b57cec5SDimitry Andric   return MCDisassembler::Success;
13600b57cec5SDimitry Andric }
13610b57cec5SDimitry Andric 
DecodeDPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13620b57cec5SDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
13630b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
13640b57cec5SDimitry Andric   if (RegNo > 7)
13650b57cec5SDimitry Andric     return MCDisassembler::Fail;
13660b57cec5SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
13670b57cec5SDimitry Andric }
13680b57cec5SDimitry Andric 
DecodeSPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13690b57cec5SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
13700b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
13710b57cec5SDimitry Andric   if (RegNo > 15)
13720b57cec5SDimitry Andric     return MCDisassembler::Fail;
13730b57cec5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
13740b57cec5SDimitry Andric }
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric static DecodeStatus
DecodeDPR_VFP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13770b57cec5SDimitry Andric DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
13780b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
13790b57cec5SDimitry Andric   if (RegNo > 15)
13800b57cec5SDimitry Andric     return MCDisassembler::Fail;
13810b57cec5SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
13820b57cec5SDimitry Andric }
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric static const uint16_t QPRDecoderTable[] = {
13850b57cec5SDimitry Andric      ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
13860b57cec5SDimitry Andric      ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
13870b57cec5SDimitry Andric      ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
13880b57cec5SDimitry Andric     ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
13890b57cec5SDimitry Andric };
13900b57cec5SDimitry Andric 
DecodeQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)13910b57cec5SDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
13920b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
13930b57cec5SDimitry Andric   if (RegNo > 31 || (RegNo & 1) != 0)
13940b57cec5SDimitry Andric     return MCDisassembler::Fail;
13950b57cec5SDimitry Andric   RegNo >>= 1;
13960b57cec5SDimitry Andric 
13970b57cec5SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
13980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13990b57cec5SDimitry Andric   return MCDisassembler::Success;
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric static const uint16_t DPairDecoderTable[] = {
14030b57cec5SDimitry Andric   ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
14040b57cec5SDimitry Andric   ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
14050b57cec5SDimitry Andric   ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
14060b57cec5SDimitry Andric   ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
14070b57cec5SDimitry Andric   ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
14080b57cec5SDimitry Andric   ARM::Q15
14090b57cec5SDimitry Andric };
14100b57cec5SDimitry Andric 
DecodeDPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)14110b57cec5SDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
14120b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
14130b57cec5SDimitry Andric   if (RegNo > 30)
14140b57cec5SDimitry Andric     return MCDisassembler::Fail;
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric   unsigned Register = DPairDecoderTable[RegNo];
14170b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
14180b57cec5SDimitry Andric   return MCDisassembler::Success;
14190b57cec5SDimitry Andric }
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric static const uint16_t DPairSpacedDecoderTable[] = {
14220b57cec5SDimitry Andric   ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
14230b57cec5SDimitry Andric   ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
14240b57cec5SDimitry Andric   ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
14250b57cec5SDimitry Andric   ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
14260b57cec5SDimitry Andric   ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
14270b57cec5SDimitry Andric   ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
14280b57cec5SDimitry Andric   ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
14290b57cec5SDimitry Andric   ARM::D28_D30, ARM::D29_D31
14300b57cec5SDimitry Andric };
14310b57cec5SDimitry Andric 
DecodeDPairSpacedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)14320b57cec5SDimitry Andric static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
14330b57cec5SDimitry Andric                                                    unsigned RegNo,
14340b57cec5SDimitry Andric                                                    uint64_t Address,
14350b57cec5SDimitry Andric                                                    const void *Decoder) {
14360b57cec5SDimitry Andric   if (RegNo > 29)
14370b57cec5SDimitry Andric     return MCDisassembler::Fail;
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   unsigned Register = DPairSpacedDecoderTable[RegNo];
14400b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
14410b57cec5SDimitry Andric   return MCDisassembler::Success;
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric 
DecodePredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)14440b57cec5SDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
14450b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
14460b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14470b57cec5SDimitry Andric   if (Val == 0xF) return MCDisassembler::Fail;
14480b57cec5SDimitry Andric   // AL predicate is not allowed on Thumb1 branches.
14490b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
14500b57cec5SDimitry Andric     return MCDisassembler::Fail;
14510b57cec5SDimitry Andric   if (Val != ARMCC::AL && !ARMInsts[Inst.getOpcode()].isPredicable())
14520b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
14530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
14540b57cec5SDimitry Andric   if (Val == ARMCC::AL) {
14550b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
14560b57cec5SDimitry Andric   } else
14570b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
14580b57cec5SDimitry Andric   return S;
14590b57cec5SDimitry Andric }
14600b57cec5SDimitry Andric 
DecodeCCOutOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)14610b57cec5SDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
14620b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
14630b57cec5SDimitry Andric   if (Val)
14640b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
14650b57cec5SDimitry Andric   else
14660b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
14670b57cec5SDimitry Andric   return MCDisassembler::Success;
14680b57cec5SDimitry Andric }
14690b57cec5SDimitry Andric 
DecodeSORegImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)14700b57cec5SDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
14710b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
14720b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14730b57cec5SDimitry Andric 
14740b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
14750b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
14760b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
14770b57cec5SDimitry Andric 
14780b57cec5SDimitry Andric   // Register-immediate
14790b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
14800b57cec5SDimitry Andric     return MCDisassembler::Fail;
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
14830b57cec5SDimitry Andric   switch (type) {
14840b57cec5SDimitry Andric     case 0:
14850b57cec5SDimitry Andric       Shift = ARM_AM::lsl;
14860b57cec5SDimitry Andric       break;
14870b57cec5SDimitry Andric     case 1:
14880b57cec5SDimitry Andric       Shift = ARM_AM::lsr;
14890b57cec5SDimitry Andric       break;
14900b57cec5SDimitry Andric     case 2:
14910b57cec5SDimitry Andric       Shift = ARM_AM::asr;
14920b57cec5SDimitry Andric       break;
14930b57cec5SDimitry Andric     case 3:
14940b57cec5SDimitry Andric       Shift = ARM_AM::ror;
14950b57cec5SDimitry Andric       break;
14960b57cec5SDimitry Andric   }
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric   if (Shift == ARM_AM::ror && imm == 0)
14990b57cec5SDimitry Andric     Shift = ARM_AM::rrx;
15000b57cec5SDimitry Andric 
15010b57cec5SDimitry Andric   unsigned Op = Shift | (imm << 3);
15020b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Op));
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric   return S;
15050b57cec5SDimitry Andric }
15060b57cec5SDimitry Andric 
DecodeSORegRegOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)15070b57cec5SDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
15080b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
15090b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
15120b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
15130b57cec5SDimitry Andric   unsigned Rs = fieldFromInstruction(Val, 8, 4);
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric   // Register-register
15160b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
15170b57cec5SDimitry Andric     return MCDisassembler::Fail;
15180b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
15190b57cec5SDimitry Andric     return MCDisassembler::Fail;
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
15220b57cec5SDimitry Andric   switch (type) {
15230b57cec5SDimitry Andric     case 0:
15240b57cec5SDimitry Andric       Shift = ARM_AM::lsl;
15250b57cec5SDimitry Andric       break;
15260b57cec5SDimitry Andric     case 1:
15270b57cec5SDimitry Andric       Shift = ARM_AM::lsr;
15280b57cec5SDimitry Andric       break;
15290b57cec5SDimitry Andric     case 2:
15300b57cec5SDimitry Andric       Shift = ARM_AM::asr;
15310b57cec5SDimitry Andric       break;
15320b57cec5SDimitry Andric     case 3:
15330b57cec5SDimitry Andric       Shift = ARM_AM::ror;
15340b57cec5SDimitry Andric       break;
15350b57cec5SDimitry Andric   }
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Shift));
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric   return S;
15400b57cec5SDimitry Andric }
15410b57cec5SDimitry Andric 
DecodeRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)15420b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
15430b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
15440b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric   bool NeedDisjointWriteback = false;
15470b57cec5SDimitry Andric   unsigned WritebackReg = 0;
15480b57cec5SDimitry Andric   bool CLRM = false;
15490b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
15500b57cec5SDimitry Andric   default:
15510b57cec5SDimitry Andric     break;
15520b57cec5SDimitry Andric   case ARM::LDMIA_UPD:
15530b57cec5SDimitry Andric   case ARM::LDMDB_UPD:
15540b57cec5SDimitry Andric   case ARM::LDMIB_UPD:
15550b57cec5SDimitry Andric   case ARM::LDMDA_UPD:
15560b57cec5SDimitry Andric   case ARM::t2LDMIA_UPD:
15570b57cec5SDimitry Andric   case ARM::t2LDMDB_UPD:
15580b57cec5SDimitry Andric   case ARM::t2STMIA_UPD:
15590b57cec5SDimitry Andric   case ARM::t2STMDB_UPD:
15600b57cec5SDimitry Andric     NeedDisjointWriteback = true;
15610b57cec5SDimitry Andric     WritebackReg = Inst.getOperand(0).getReg();
15620b57cec5SDimitry Andric     break;
15630b57cec5SDimitry Andric   case ARM::t2CLRM:
15640b57cec5SDimitry Andric     CLRM = true;
15650b57cec5SDimitry Andric     break;
15660b57cec5SDimitry Andric   }
15670b57cec5SDimitry Andric 
15680b57cec5SDimitry Andric   // Empty register lists are not allowed.
15690b57cec5SDimitry Andric   if (Val == 0) return MCDisassembler::Fail;
15700b57cec5SDimitry Andric   for (unsigned i = 0; i < 16; ++i) {
15710b57cec5SDimitry Andric     if (Val & (1 << i)) {
15720b57cec5SDimitry Andric       if (CLRM) {
15730b57cec5SDimitry Andric         if (!Check(S, DecodeCLRMGPRRegisterClass(Inst, i, Address, Decoder))) {
15740b57cec5SDimitry Andric           return MCDisassembler::Fail;
15750b57cec5SDimitry Andric         }
15760b57cec5SDimitry Andric       } else {
15770b57cec5SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
15780b57cec5SDimitry Andric           return MCDisassembler::Fail;
15790b57cec5SDimitry Andric         // Writeback not allowed if Rn is in the target list.
15800b57cec5SDimitry Andric         if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
15810b57cec5SDimitry Andric           Check(S, MCDisassembler::SoftFail);
15820b57cec5SDimitry Andric       }
15830b57cec5SDimitry Andric     }
15840b57cec5SDimitry Andric   }
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric   return S;
15870b57cec5SDimitry Andric }
15880b57cec5SDimitry Andric 
DecodeSPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)15890b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
15900b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
15910b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
15940b57cec5SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 0, 8);
15950b57cec5SDimitry Andric 
15960b57cec5SDimitry Andric   // In case of unpredictable encoding, tweak the operands.
15970b57cec5SDimitry Andric   if (regs == 0 || (Vd + regs) > 32) {
15980b57cec5SDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
15990b57cec5SDimitry Andric     regs = std::max( 1u, regs);
16000b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
16010b57cec5SDimitry Andric   }
16020b57cec5SDimitry Andric 
16030b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
16040b57cec5SDimitry Andric     return MCDisassembler::Fail;
16050b57cec5SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
16060b57cec5SDimitry Andric     if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
16070b57cec5SDimitry Andric       return MCDisassembler::Fail;
16080b57cec5SDimitry Andric   }
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric   return S;
16110b57cec5SDimitry Andric }
16120b57cec5SDimitry Andric 
DecodeDPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)16130b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
16140b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
16150b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16160b57cec5SDimitry Andric 
16170b57cec5SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
16180b57cec5SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 1, 7);
16190b57cec5SDimitry Andric 
16200b57cec5SDimitry Andric   // In case of unpredictable encoding, tweak the operands.
16210b57cec5SDimitry Andric   if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
16220b57cec5SDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
16230b57cec5SDimitry Andric     regs = std::max( 1u, regs);
16240b57cec5SDimitry Andric     regs = std::min(16u, regs);
16250b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
16260b57cec5SDimitry Andric   }
16270b57cec5SDimitry Andric 
16280b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
16290b57cec5SDimitry Andric       return MCDisassembler::Fail;
16300b57cec5SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
16310b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
16320b57cec5SDimitry Andric       return MCDisassembler::Fail;
16330b57cec5SDimitry Andric   }
16340b57cec5SDimitry Andric 
16350b57cec5SDimitry Andric   return S;
16360b57cec5SDimitry Andric }
16370b57cec5SDimitry Andric 
DecodeBitfieldMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)16380b57cec5SDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
16390b57cec5SDimitry Andric                                       uint64_t Address, const void *Decoder) {
16400b57cec5SDimitry Andric   // This operand encodes a mask of contiguous zeros between a specified MSB
16410b57cec5SDimitry Andric   // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
16420b57cec5SDimitry Andric   // the mask of all bits LSB-and-lower, and then xor them to create
16430b57cec5SDimitry Andric   // the mask of that's all ones on [msb, lsb].  Finally we not it to
16440b57cec5SDimitry Andric   // create the final mask.
16450b57cec5SDimitry Andric   unsigned msb = fieldFromInstruction(Val, 5, 5);
16460b57cec5SDimitry Andric   unsigned lsb = fieldFromInstruction(Val, 0, 5);
16470b57cec5SDimitry Andric 
16480b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16490b57cec5SDimitry Andric   if (lsb > msb) {
16500b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
16510b57cec5SDimitry Andric     // The check above will cause the warning for the "potentially undefined
16520b57cec5SDimitry Andric     // instruction encoding" but we can't build a bad MCOperand value here
16530b57cec5SDimitry Andric     // with a lsb > msb or else printing the MCInst will cause a crash.
16540b57cec5SDimitry Andric     lsb = msb;
16550b57cec5SDimitry Andric   }
16560b57cec5SDimitry Andric 
16570b57cec5SDimitry Andric   uint32_t msb_mask = 0xFFFFFFFF;
16580b57cec5SDimitry Andric   if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
16590b57cec5SDimitry Andric   uint32_t lsb_mask = (1U << lsb) - 1;
16600b57cec5SDimitry Andric 
16610b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask)));
16620b57cec5SDimitry Andric   return S;
16630b57cec5SDimitry Andric }
16640b57cec5SDimitry Andric 
DecodeCopMemInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)16650b57cec5SDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
16660b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
16670b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
16700b57cec5SDimitry Andric   unsigned CRd = fieldFromInstruction(Insn, 12, 4);
16710b57cec5SDimitry Andric   unsigned coproc = fieldFromInstruction(Insn, 8, 4);
16720b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
16730b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
16740b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
16750b57cec5SDimitry Andric   const FeatureBitset &featureBits =
16760b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
16770b57cec5SDimitry Andric 
16780b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
16790b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
16800b57cec5SDimitry Andric     case ARM::LDC_PRE:
16810b57cec5SDimitry Andric     case ARM::LDC_POST:
16820b57cec5SDimitry Andric     case ARM::LDC_OPTION:
16830b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
16840b57cec5SDimitry Andric     case ARM::LDCL_PRE:
16850b57cec5SDimitry Andric     case ARM::LDCL_POST:
16860b57cec5SDimitry Andric     case ARM::LDCL_OPTION:
16870b57cec5SDimitry Andric     case ARM::STC_OFFSET:
16880b57cec5SDimitry Andric     case ARM::STC_PRE:
16890b57cec5SDimitry Andric     case ARM::STC_POST:
16900b57cec5SDimitry Andric     case ARM::STC_OPTION:
16910b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
16920b57cec5SDimitry Andric     case ARM::STCL_PRE:
16930b57cec5SDimitry Andric     case ARM::STCL_POST:
16940b57cec5SDimitry Andric     case ARM::STCL_OPTION:
16950b57cec5SDimitry Andric     case ARM::t2LDC_OFFSET:
16960b57cec5SDimitry Andric     case ARM::t2LDC_PRE:
16970b57cec5SDimitry Andric     case ARM::t2LDC_POST:
16980b57cec5SDimitry Andric     case ARM::t2LDC_OPTION:
16990b57cec5SDimitry Andric     case ARM::t2LDCL_OFFSET:
17000b57cec5SDimitry Andric     case ARM::t2LDCL_PRE:
17010b57cec5SDimitry Andric     case ARM::t2LDCL_POST:
17020b57cec5SDimitry Andric     case ARM::t2LDCL_OPTION:
17030b57cec5SDimitry Andric     case ARM::t2STC_OFFSET:
17040b57cec5SDimitry Andric     case ARM::t2STC_PRE:
17050b57cec5SDimitry Andric     case ARM::t2STC_POST:
17060b57cec5SDimitry Andric     case ARM::t2STC_OPTION:
17070b57cec5SDimitry Andric     case ARM::t2STCL_OFFSET:
17080b57cec5SDimitry Andric     case ARM::t2STCL_PRE:
17090b57cec5SDimitry Andric     case ARM::t2STCL_POST:
17100b57cec5SDimitry Andric     case ARM::t2STCL_OPTION:
17110b57cec5SDimitry Andric     case ARM::t2LDC2_OFFSET:
17120b57cec5SDimitry Andric     case ARM::t2LDC2L_OFFSET:
17130b57cec5SDimitry Andric     case ARM::t2LDC2_PRE:
17140b57cec5SDimitry Andric     case ARM::t2LDC2L_PRE:
17150b57cec5SDimitry Andric     case ARM::t2STC2_OFFSET:
17160b57cec5SDimitry Andric     case ARM::t2STC2L_OFFSET:
17170b57cec5SDimitry Andric     case ARM::t2STC2_PRE:
17180b57cec5SDimitry Andric     case ARM::t2STC2L_PRE:
17190b57cec5SDimitry Andric     case ARM::LDC2_OFFSET:
17200b57cec5SDimitry Andric     case ARM::LDC2L_OFFSET:
17210b57cec5SDimitry Andric     case ARM::LDC2_PRE:
17220b57cec5SDimitry Andric     case ARM::LDC2L_PRE:
17230b57cec5SDimitry Andric     case ARM::STC2_OFFSET:
17240b57cec5SDimitry Andric     case ARM::STC2L_OFFSET:
17250b57cec5SDimitry Andric     case ARM::STC2_PRE:
17260b57cec5SDimitry Andric     case ARM::STC2L_PRE:
17270b57cec5SDimitry Andric     case ARM::t2LDC2_OPTION:
17280b57cec5SDimitry Andric     case ARM::t2STC2_OPTION:
17290b57cec5SDimitry Andric     case ARM::t2LDC2_POST:
17300b57cec5SDimitry Andric     case ARM::t2LDC2L_POST:
17310b57cec5SDimitry Andric     case ARM::t2STC2_POST:
17320b57cec5SDimitry Andric     case ARM::t2STC2L_POST:
17330b57cec5SDimitry Andric     case ARM::LDC2_POST:
17340b57cec5SDimitry Andric     case ARM::LDC2L_POST:
17350b57cec5SDimitry Andric     case ARM::STC2_POST:
17360b57cec5SDimitry Andric     case ARM::STC2L_POST:
17370b57cec5SDimitry Andric       if (coproc == 0xA || coproc == 0xB ||
17380b57cec5SDimitry Andric           (featureBits[ARM::HasV8_1MMainlineOps] &&
17390b57cec5SDimitry Andric            (coproc == 0x8 || coproc == 0x9 || coproc == 0xA || coproc == 0xB ||
17400b57cec5SDimitry Andric             coproc == 0xE || coproc == 0xF)))
17410b57cec5SDimitry Andric         return MCDisassembler::Fail;
17420b57cec5SDimitry Andric       break;
17430b57cec5SDimitry Andric     default:
17440b57cec5SDimitry Andric       break;
17450b57cec5SDimitry Andric   }
17460b57cec5SDimitry Andric 
17470b57cec5SDimitry Andric   if (featureBits[ARM::HasV8Ops] && (coproc != 14))
17480b57cec5SDimitry Andric     return MCDisassembler::Fail;
17490b57cec5SDimitry Andric 
17500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(coproc));
17510b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRd));
17520b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
17530b57cec5SDimitry Andric     return MCDisassembler::Fail;
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
17560b57cec5SDimitry Andric     case ARM::t2LDC2_OFFSET:
17570b57cec5SDimitry Andric     case ARM::t2LDC2L_OFFSET:
17580b57cec5SDimitry Andric     case ARM::t2LDC2_PRE:
17590b57cec5SDimitry Andric     case ARM::t2LDC2L_PRE:
17600b57cec5SDimitry Andric     case ARM::t2STC2_OFFSET:
17610b57cec5SDimitry Andric     case ARM::t2STC2L_OFFSET:
17620b57cec5SDimitry Andric     case ARM::t2STC2_PRE:
17630b57cec5SDimitry Andric     case ARM::t2STC2L_PRE:
17640b57cec5SDimitry Andric     case ARM::LDC2_OFFSET:
17650b57cec5SDimitry Andric     case ARM::LDC2L_OFFSET:
17660b57cec5SDimitry Andric     case ARM::LDC2_PRE:
17670b57cec5SDimitry Andric     case ARM::LDC2L_PRE:
17680b57cec5SDimitry Andric     case ARM::STC2_OFFSET:
17690b57cec5SDimitry Andric     case ARM::STC2L_OFFSET:
17700b57cec5SDimitry Andric     case ARM::STC2_PRE:
17710b57cec5SDimitry Andric     case ARM::STC2L_PRE:
17720b57cec5SDimitry Andric     case ARM::t2LDC_OFFSET:
17730b57cec5SDimitry Andric     case ARM::t2LDCL_OFFSET:
17740b57cec5SDimitry Andric     case ARM::t2LDC_PRE:
17750b57cec5SDimitry Andric     case ARM::t2LDCL_PRE:
17760b57cec5SDimitry Andric     case ARM::t2STC_OFFSET:
17770b57cec5SDimitry Andric     case ARM::t2STCL_OFFSET:
17780b57cec5SDimitry Andric     case ARM::t2STC_PRE:
17790b57cec5SDimitry Andric     case ARM::t2STCL_PRE:
17800b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
17810b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
17820b57cec5SDimitry Andric     case ARM::LDC_PRE:
17830b57cec5SDimitry Andric     case ARM::LDCL_PRE:
17840b57cec5SDimitry Andric     case ARM::STC_OFFSET:
17850b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
17860b57cec5SDimitry Andric     case ARM::STC_PRE:
17870b57cec5SDimitry Andric     case ARM::STCL_PRE:
17880b57cec5SDimitry Andric       imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
17890b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
17900b57cec5SDimitry Andric       break;
17910b57cec5SDimitry Andric     case ARM::t2LDC2_POST:
17920b57cec5SDimitry Andric     case ARM::t2LDC2L_POST:
17930b57cec5SDimitry Andric     case ARM::t2STC2_POST:
17940b57cec5SDimitry Andric     case ARM::t2STC2L_POST:
17950b57cec5SDimitry Andric     case ARM::LDC2_POST:
17960b57cec5SDimitry Andric     case ARM::LDC2L_POST:
17970b57cec5SDimitry Andric     case ARM::STC2_POST:
17980b57cec5SDimitry Andric     case ARM::STC2L_POST:
17990b57cec5SDimitry Andric     case ARM::t2LDC_POST:
18000b57cec5SDimitry Andric     case ARM::t2LDCL_POST:
18010b57cec5SDimitry Andric     case ARM::t2STC_POST:
18020b57cec5SDimitry Andric     case ARM::t2STCL_POST:
18030b57cec5SDimitry Andric     case ARM::LDC_POST:
18040b57cec5SDimitry Andric     case ARM::LDCL_POST:
18050b57cec5SDimitry Andric     case ARM::STC_POST:
18060b57cec5SDimitry Andric     case ARM::STCL_POST:
18070b57cec5SDimitry Andric       imm |= U << 8;
18080b57cec5SDimitry Andric       LLVM_FALLTHROUGH;
18090b57cec5SDimitry Andric     default:
18100b57cec5SDimitry Andric       // The 'option' variant doesn't encode 'U' in the immediate since
18110b57cec5SDimitry Andric       // the immediate is unsigned [0,255].
18120b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
18130b57cec5SDimitry Andric       break;
18140b57cec5SDimitry Andric   }
18150b57cec5SDimitry Andric 
18160b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
18170b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
18180b57cec5SDimitry Andric     case ARM::LDC_PRE:
18190b57cec5SDimitry Andric     case ARM::LDC_POST:
18200b57cec5SDimitry Andric     case ARM::LDC_OPTION:
18210b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
18220b57cec5SDimitry Andric     case ARM::LDCL_PRE:
18230b57cec5SDimitry Andric     case ARM::LDCL_POST:
18240b57cec5SDimitry Andric     case ARM::LDCL_OPTION:
18250b57cec5SDimitry Andric     case ARM::STC_OFFSET:
18260b57cec5SDimitry Andric     case ARM::STC_PRE:
18270b57cec5SDimitry Andric     case ARM::STC_POST:
18280b57cec5SDimitry Andric     case ARM::STC_OPTION:
18290b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
18300b57cec5SDimitry Andric     case ARM::STCL_PRE:
18310b57cec5SDimitry Andric     case ARM::STCL_POST:
18320b57cec5SDimitry Andric     case ARM::STCL_OPTION:
18330b57cec5SDimitry Andric       if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
18340b57cec5SDimitry Andric         return MCDisassembler::Fail;
18350b57cec5SDimitry Andric       break;
18360b57cec5SDimitry Andric     default:
18370b57cec5SDimitry Andric       break;
18380b57cec5SDimitry Andric   }
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric   return S;
18410b57cec5SDimitry Andric }
18420b57cec5SDimitry Andric 
18430b57cec5SDimitry Andric static DecodeStatus
DecodeAddrMode2IdxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)18440b57cec5SDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
18450b57cec5SDimitry Andric                               uint64_t Address, const void *Decoder) {
18460b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
18490b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
18500b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
18510b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
18520b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
18530b57cec5SDimitry Andric   unsigned reg = fieldFromInstruction(Insn, 25, 1);
18540b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
18550b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
18560b57cec5SDimitry Andric 
18570b57cec5SDimitry Andric   // On stores, the writeback operand precedes Rt.
18580b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
18590b57cec5SDimitry Andric     case ARM::STR_POST_IMM:
18600b57cec5SDimitry Andric     case ARM::STR_POST_REG:
18610b57cec5SDimitry Andric     case ARM::STRB_POST_IMM:
18620b57cec5SDimitry Andric     case ARM::STRB_POST_REG:
18630b57cec5SDimitry Andric     case ARM::STRT_POST_REG:
18640b57cec5SDimitry Andric     case ARM::STRT_POST_IMM:
18650b57cec5SDimitry Andric     case ARM::STRBT_POST_REG:
18660b57cec5SDimitry Andric     case ARM::STRBT_POST_IMM:
18670b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
18680b57cec5SDimitry Andric         return MCDisassembler::Fail;
18690b57cec5SDimitry Andric       break;
18700b57cec5SDimitry Andric     default:
18710b57cec5SDimitry Andric       break;
18720b57cec5SDimitry Andric   }
18730b57cec5SDimitry Andric 
18740b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
18750b57cec5SDimitry Andric     return MCDisassembler::Fail;
18760b57cec5SDimitry Andric 
18770b57cec5SDimitry Andric   // On loads, the writeback operand comes after Rt.
18780b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
18790b57cec5SDimitry Andric     case ARM::LDR_POST_IMM:
18800b57cec5SDimitry Andric     case ARM::LDR_POST_REG:
18810b57cec5SDimitry Andric     case ARM::LDRB_POST_IMM:
18820b57cec5SDimitry Andric     case ARM::LDRB_POST_REG:
18830b57cec5SDimitry Andric     case ARM::LDRBT_POST_REG:
18840b57cec5SDimitry Andric     case ARM::LDRBT_POST_IMM:
18850b57cec5SDimitry Andric     case ARM::LDRT_POST_REG:
18860b57cec5SDimitry Andric     case ARM::LDRT_POST_IMM:
18870b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
18880b57cec5SDimitry Andric         return MCDisassembler::Fail;
18890b57cec5SDimitry Andric       break;
18900b57cec5SDimitry Andric     default:
18910b57cec5SDimitry Andric       break;
18920b57cec5SDimitry Andric   }
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
18950b57cec5SDimitry Andric     return MCDisassembler::Fail;
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::add;
18980b57cec5SDimitry Andric   if (!fieldFromInstruction(Insn, 23, 1))
18990b57cec5SDimitry Andric     Op = ARM_AM::sub;
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric   bool writeback = (P == 0) || (W == 1);
19020b57cec5SDimitry Andric   unsigned idx_mode = 0;
19030b57cec5SDimitry Andric   if (P && writeback)
19040b57cec5SDimitry Andric     idx_mode = ARMII::IndexModePre;
19050b57cec5SDimitry Andric   else if (!P && writeback)
19060b57cec5SDimitry Andric     idx_mode = ARMII::IndexModePost;
19070b57cec5SDimitry Andric 
19080b57cec5SDimitry Andric   if (writeback && (Rn == 15 || Rn == Rt))
19090b57cec5SDimitry Andric     S = MCDisassembler::SoftFail; // UNPREDICTABLE
19100b57cec5SDimitry Andric 
19110b57cec5SDimitry Andric   if (reg) {
19120b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
19130b57cec5SDimitry Andric       return MCDisassembler::Fail;
19140b57cec5SDimitry Andric     ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
19150b57cec5SDimitry Andric     switch( fieldFromInstruction(Insn, 5, 2)) {
19160b57cec5SDimitry Andric       case 0:
19170b57cec5SDimitry Andric         Opc = ARM_AM::lsl;
19180b57cec5SDimitry Andric         break;
19190b57cec5SDimitry Andric       case 1:
19200b57cec5SDimitry Andric         Opc = ARM_AM::lsr;
19210b57cec5SDimitry Andric         break;
19220b57cec5SDimitry Andric       case 2:
19230b57cec5SDimitry Andric         Opc = ARM_AM::asr;
19240b57cec5SDimitry Andric         break;
19250b57cec5SDimitry Andric       case 3:
19260b57cec5SDimitry Andric         Opc = ARM_AM::ror;
19270b57cec5SDimitry Andric         break;
19280b57cec5SDimitry Andric       default:
19290b57cec5SDimitry Andric         return MCDisassembler::Fail;
19300b57cec5SDimitry Andric     }
19310b57cec5SDimitry Andric     unsigned amt = fieldFromInstruction(Insn, 7, 5);
19320b57cec5SDimitry Andric     if (Opc == ARM_AM::ror && amt == 0)
19330b57cec5SDimitry Andric       Opc = ARM_AM::rrx;
19340b57cec5SDimitry Andric     unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
19370b57cec5SDimitry Andric   } else {
19380b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
19390b57cec5SDimitry Andric     unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
19400b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(tmp));
19410b57cec5SDimitry Andric   }
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
19440b57cec5SDimitry Andric     return MCDisassembler::Fail;
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   return S;
19470b57cec5SDimitry Andric }
19480b57cec5SDimitry Andric 
DecodeSORegMemOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)19490b57cec5SDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
19500b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
19510b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
19520b57cec5SDimitry Andric 
19530b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
19540b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val,  0, 4);
19550b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
19560b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
19570b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 12, 1);
19580b57cec5SDimitry Andric 
19590b57cec5SDimitry Andric   ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
19600b57cec5SDimitry Andric   switch (type) {
19610b57cec5SDimitry Andric     case 0:
19620b57cec5SDimitry Andric       ShOp = ARM_AM::lsl;
19630b57cec5SDimitry Andric       break;
19640b57cec5SDimitry Andric     case 1:
19650b57cec5SDimitry Andric       ShOp = ARM_AM::lsr;
19660b57cec5SDimitry Andric       break;
19670b57cec5SDimitry Andric     case 2:
19680b57cec5SDimitry Andric       ShOp = ARM_AM::asr;
19690b57cec5SDimitry Andric       break;
19700b57cec5SDimitry Andric     case 3:
19710b57cec5SDimitry Andric       ShOp = ARM_AM::ror;
19720b57cec5SDimitry Andric       break;
19730b57cec5SDimitry Andric   }
19740b57cec5SDimitry Andric 
19750b57cec5SDimitry Andric   if (ShOp == ARM_AM::ror && imm == 0)
19760b57cec5SDimitry Andric     ShOp = ARM_AM::rrx;
19770b57cec5SDimitry Andric 
19780b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
19790b57cec5SDimitry Andric     return MCDisassembler::Fail;
19800b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
19810b57cec5SDimitry Andric     return MCDisassembler::Fail;
19820b57cec5SDimitry Andric   unsigned shift;
19830b57cec5SDimitry Andric   if (U)
19840b57cec5SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
19850b57cec5SDimitry Andric   else
19860b57cec5SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
19870b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric   return S;
19900b57cec5SDimitry Andric }
19910b57cec5SDimitry Andric 
19920b57cec5SDimitry Andric static DecodeStatus
DecodeAddrMode3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)19930b57cec5SDimitry Andric DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
19940b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
19950b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
19960b57cec5SDimitry Andric 
19970b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
19980b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
19990b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
20000b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 22, 1);
20010b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 8, 4);
20020b57cec5SDimitry Andric   unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
20030b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
20040b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
20050b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
20060b57cec5SDimitry Andric   unsigned Rt2 = Rt + 1;
20070b57cec5SDimitry Andric 
20080b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
20090b57cec5SDimitry Andric 
20100b57cec5SDimitry Andric   // For {LD,ST}RD, Rt must be even, else undefined.
20110b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20120b57cec5SDimitry Andric     case ARM::STRD:
20130b57cec5SDimitry Andric     case ARM::STRD_PRE:
20140b57cec5SDimitry Andric     case ARM::STRD_POST:
20150b57cec5SDimitry Andric     case ARM::LDRD:
20160b57cec5SDimitry Andric     case ARM::LDRD_PRE:
20170b57cec5SDimitry Andric     case ARM::LDRD_POST:
20180b57cec5SDimitry Andric       if (Rt & 0x1) S = MCDisassembler::SoftFail;
20190b57cec5SDimitry Andric       break;
20200b57cec5SDimitry Andric     default:
20210b57cec5SDimitry Andric       break;
20220b57cec5SDimitry Andric   }
20230b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20240b57cec5SDimitry Andric     case ARM::STRD:
20250b57cec5SDimitry Andric     case ARM::STRD_PRE:
20260b57cec5SDimitry Andric     case ARM::STRD_POST:
20270b57cec5SDimitry Andric       if (P == 0 && W == 1)
20280b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20290b57cec5SDimitry Andric 
20300b57cec5SDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
20310b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20320b57cec5SDimitry Andric       if (type && Rm == 15)
20330b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20340b57cec5SDimitry Andric       if (Rt2 == 15)
20350b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20360b57cec5SDimitry Andric       if (!type && fieldFromInstruction(Insn, 8, 4))
20370b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20380b57cec5SDimitry Andric       break;
20390b57cec5SDimitry Andric     case ARM::STRH:
20400b57cec5SDimitry Andric     case ARM::STRH_PRE:
20410b57cec5SDimitry Andric     case ARM::STRH_POST:
20420b57cec5SDimitry Andric       if (Rt == 15)
20430b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20440b57cec5SDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt))
20450b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20460b57cec5SDimitry Andric       if (!type && Rm == 15)
20470b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20480b57cec5SDimitry Andric       break;
20490b57cec5SDimitry Andric     case ARM::LDRD:
20500b57cec5SDimitry Andric     case ARM::LDRD_PRE:
20510b57cec5SDimitry Andric     case ARM::LDRD_POST:
20520b57cec5SDimitry Andric       if (type && Rn == 15) {
20530b57cec5SDimitry Andric         if (Rt2 == 15)
20540b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
20550b57cec5SDimitry Andric         break;
20560b57cec5SDimitry Andric       }
20570b57cec5SDimitry Andric       if (P == 0 && W == 1)
20580b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20590b57cec5SDimitry Andric       if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
20600b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20610b57cec5SDimitry Andric       if (!type && writeback && Rn == 15)
20620b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20630b57cec5SDimitry Andric       if (writeback && (Rn == Rt || Rn == Rt2))
20640b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20650b57cec5SDimitry Andric       break;
20660b57cec5SDimitry Andric     case ARM::LDRH:
20670b57cec5SDimitry Andric     case ARM::LDRH_PRE:
20680b57cec5SDimitry Andric     case ARM::LDRH_POST:
20690b57cec5SDimitry Andric       if (type && Rn == 15) {
20700b57cec5SDimitry Andric         if (Rt == 15)
20710b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
20720b57cec5SDimitry Andric         break;
20730b57cec5SDimitry Andric       }
20740b57cec5SDimitry Andric       if (Rt == 15)
20750b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20760b57cec5SDimitry Andric       if (!type && Rm == 15)
20770b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20780b57cec5SDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
20790b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20800b57cec5SDimitry Andric       break;
20810b57cec5SDimitry Andric     case ARM::LDRSH:
20820b57cec5SDimitry Andric     case ARM::LDRSH_PRE:
20830b57cec5SDimitry Andric     case ARM::LDRSH_POST:
20840b57cec5SDimitry Andric     case ARM::LDRSB:
20850b57cec5SDimitry Andric     case ARM::LDRSB_PRE:
20860b57cec5SDimitry Andric     case ARM::LDRSB_POST:
20870b57cec5SDimitry Andric       if (type && Rn == 15) {
20880b57cec5SDimitry Andric         if (Rt == 15)
20890b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
20900b57cec5SDimitry Andric         break;
20910b57cec5SDimitry Andric       }
20920b57cec5SDimitry Andric       if (type && (Rt == 15 || (writeback && Rn == Rt)))
20930b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20940b57cec5SDimitry Andric       if (!type && (Rt == 15 || Rm == 15))
20950b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20960b57cec5SDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
20970b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
20980b57cec5SDimitry Andric       break;
20990b57cec5SDimitry Andric     default:
21000b57cec5SDimitry Andric       break;
21010b57cec5SDimitry Andric   }
21020b57cec5SDimitry Andric 
21030b57cec5SDimitry Andric   if (writeback) { // Writeback
21040b57cec5SDimitry Andric     if (P)
21050b57cec5SDimitry Andric       U |= ARMII::IndexModePre << 9;
21060b57cec5SDimitry Andric     else
21070b57cec5SDimitry Andric       U |= ARMII::IndexModePost << 9;
21080b57cec5SDimitry Andric 
21090b57cec5SDimitry Andric     // On stores, the writeback operand precedes Rt.
21100b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
21110b57cec5SDimitry Andric     case ARM::STRD:
21120b57cec5SDimitry Andric     case ARM::STRD_PRE:
21130b57cec5SDimitry Andric     case ARM::STRD_POST:
21140b57cec5SDimitry Andric     case ARM::STRH:
21150b57cec5SDimitry Andric     case ARM::STRH_PRE:
21160b57cec5SDimitry Andric     case ARM::STRH_POST:
21170b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
21180b57cec5SDimitry Andric         return MCDisassembler::Fail;
21190b57cec5SDimitry Andric       break;
21200b57cec5SDimitry Andric     default:
21210b57cec5SDimitry Andric       break;
21220b57cec5SDimitry Andric     }
21230b57cec5SDimitry Andric   }
21240b57cec5SDimitry Andric 
21250b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
21260b57cec5SDimitry Andric     return MCDisassembler::Fail;
21270b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
21280b57cec5SDimitry Andric     case ARM::STRD:
21290b57cec5SDimitry Andric     case ARM::STRD_PRE:
21300b57cec5SDimitry Andric     case ARM::STRD_POST:
21310b57cec5SDimitry Andric     case ARM::LDRD:
21320b57cec5SDimitry Andric     case ARM::LDRD_PRE:
21330b57cec5SDimitry Andric     case ARM::LDRD_POST:
21340b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
21350b57cec5SDimitry Andric         return MCDisassembler::Fail;
21360b57cec5SDimitry Andric       break;
21370b57cec5SDimitry Andric     default:
21380b57cec5SDimitry Andric       break;
21390b57cec5SDimitry Andric   }
21400b57cec5SDimitry Andric 
21410b57cec5SDimitry Andric   if (writeback) {
21420b57cec5SDimitry Andric     // On loads, the writeback operand comes after Rt.
21430b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
21440b57cec5SDimitry Andric     case ARM::LDRD:
21450b57cec5SDimitry Andric     case ARM::LDRD_PRE:
21460b57cec5SDimitry Andric     case ARM::LDRD_POST:
21470b57cec5SDimitry Andric     case ARM::LDRH:
21480b57cec5SDimitry Andric     case ARM::LDRH_PRE:
21490b57cec5SDimitry Andric     case ARM::LDRH_POST:
21500b57cec5SDimitry Andric     case ARM::LDRSH:
21510b57cec5SDimitry Andric     case ARM::LDRSH_PRE:
21520b57cec5SDimitry Andric     case ARM::LDRSH_POST:
21530b57cec5SDimitry Andric     case ARM::LDRSB:
21540b57cec5SDimitry Andric     case ARM::LDRSB_PRE:
21550b57cec5SDimitry Andric     case ARM::LDRSB_POST:
21560b57cec5SDimitry Andric     case ARM::LDRHTr:
21570b57cec5SDimitry Andric     case ARM::LDRSBTr:
21580b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
21590b57cec5SDimitry Andric         return MCDisassembler::Fail;
21600b57cec5SDimitry Andric       break;
21610b57cec5SDimitry Andric     default:
21620b57cec5SDimitry Andric       break;
21630b57cec5SDimitry Andric     }
21640b57cec5SDimitry Andric   }
21650b57cec5SDimitry Andric 
21660b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
21670b57cec5SDimitry Andric     return MCDisassembler::Fail;
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric   if (type) {
21700b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
21710b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm));
21720b57cec5SDimitry Andric   } else {
21730b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
21740b57cec5SDimitry Andric     return MCDisassembler::Fail;
21750b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(U));
21760b57cec5SDimitry Andric   }
21770b57cec5SDimitry Andric 
21780b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
21790b57cec5SDimitry Andric     return MCDisassembler::Fail;
21800b57cec5SDimitry Andric 
21810b57cec5SDimitry Andric   return S;
21820b57cec5SDimitry Andric }
21830b57cec5SDimitry Andric 
DecodeRFEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)21840b57cec5SDimitry Andric static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
21850b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
21860b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
21870b57cec5SDimitry Andric 
21880b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
21890b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 23, 2);
21900b57cec5SDimitry Andric 
21910b57cec5SDimitry Andric   switch (mode) {
21920b57cec5SDimitry Andric     case 0:
21930b57cec5SDimitry Andric       mode = ARM_AM::da;
21940b57cec5SDimitry Andric       break;
21950b57cec5SDimitry Andric     case 1:
21960b57cec5SDimitry Andric       mode = ARM_AM::ia;
21970b57cec5SDimitry Andric       break;
21980b57cec5SDimitry Andric     case 2:
21990b57cec5SDimitry Andric       mode = ARM_AM::db;
22000b57cec5SDimitry Andric       break;
22010b57cec5SDimitry Andric     case 3:
22020b57cec5SDimitry Andric       mode = ARM_AM::ib;
22030b57cec5SDimitry Andric       break;
22040b57cec5SDimitry Andric   }
22050b57cec5SDimitry Andric 
22060b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(mode));
22070b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
22080b57cec5SDimitry Andric     return MCDisassembler::Fail;
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric   return S;
22110b57cec5SDimitry Andric }
22120b57cec5SDimitry Andric 
DecodeQADDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)22130b57cec5SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
22140b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
22150b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
22180b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
22190b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
22200b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
22210b57cec5SDimitry Andric 
22220b57cec5SDimitry Andric   if (pred == 0xF)
22230b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
22240b57cec5SDimitry Andric 
22250b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
22260b57cec5SDimitry Andric     return MCDisassembler::Fail;
22270b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
22280b57cec5SDimitry Andric     return MCDisassembler::Fail;
22290b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
22300b57cec5SDimitry Andric     return MCDisassembler::Fail;
22310b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
22320b57cec5SDimitry Andric     return MCDisassembler::Fail;
22330b57cec5SDimitry Andric   return S;
22340b57cec5SDimitry Andric }
22350b57cec5SDimitry Andric 
DecodeMemMultipleWritebackInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)22360b57cec5SDimitry Andric static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
22370b57cec5SDimitry Andric                                   unsigned Insn,
22380b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
22390b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22400b57cec5SDimitry Andric 
22410b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
22420b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
22430b57cec5SDimitry Andric   unsigned reglist = fieldFromInstruction(Insn, 0, 16);
22440b57cec5SDimitry Andric 
22450b57cec5SDimitry Andric   if (pred == 0xF) {
22460b57cec5SDimitry Andric     // Ambiguous with RFE and SRS
22470b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
22480b57cec5SDimitry Andric       case ARM::LDMDA:
22490b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDA);
22500b57cec5SDimitry Andric         break;
22510b57cec5SDimitry Andric       case ARM::LDMDA_UPD:
22520b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDA_UPD);
22530b57cec5SDimitry Andric         break;
22540b57cec5SDimitry Andric       case ARM::LDMDB:
22550b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDB);
22560b57cec5SDimitry Andric         break;
22570b57cec5SDimitry Andric       case ARM::LDMDB_UPD:
22580b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDB_UPD);
22590b57cec5SDimitry Andric         break;
22600b57cec5SDimitry Andric       case ARM::LDMIA:
22610b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIA);
22620b57cec5SDimitry Andric         break;
22630b57cec5SDimitry Andric       case ARM::LDMIA_UPD:
22640b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIA_UPD);
22650b57cec5SDimitry Andric         break;
22660b57cec5SDimitry Andric       case ARM::LDMIB:
22670b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIB);
22680b57cec5SDimitry Andric         break;
22690b57cec5SDimitry Andric       case ARM::LDMIB_UPD:
22700b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIB_UPD);
22710b57cec5SDimitry Andric         break;
22720b57cec5SDimitry Andric       case ARM::STMDA:
22730b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDA);
22740b57cec5SDimitry Andric         break;
22750b57cec5SDimitry Andric       case ARM::STMDA_UPD:
22760b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDA_UPD);
22770b57cec5SDimitry Andric         break;
22780b57cec5SDimitry Andric       case ARM::STMDB:
22790b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDB);
22800b57cec5SDimitry Andric         break;
22810b57cec5SDimitry Andric       case ARM::STMDB_UPD:
22820b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDB_UPD);
22830b57cec5SDimitry Andric         break;
22840b57cec5SDimitry Andric       case ARM::STMIA:
22850b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIA);
22860b57cec5SDimitry Andric         break;
22870b57cec5SDimitry Andric       case ARM::STMIA_UPD:
22880b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIA_UPD);
22890b57cec5SDimitry Andric         break;
22900b57cec5SDimitry Andric       case ARM::STMIB:
22910b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIB);
22920b57cec5SDimitry Andric         break;
22930b57cec5SDimitry Andric       case ARM::STMIB_UPD:
22940b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIB_UPD);
22950b57cec5SDimitry Andric         break;
22960b57cec5SDimitry Andric       default:
22970b57cec5SDimitry Andric         return MCDisassembler::Fail;
22980b57cec5SDimitry Andric     }
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric     // For stores (which become SRS's, the only operand is the mode.
23010b57cec5SDimitry Andric     if (fieldFromInstruction(Insn, 20, 1) == 0) {
23020b57cec5SDimitry Andric       // Check SRS encoding constraints
23030b57cec5SDimitry Andric       if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
23040b57cec5SDimitry Andric             fieldFromInstruction(Insn, 20, 1) == 0))
23050b57cec5SDimitry Andric         return MCDisassembler::Fail;
23060b57cec5SDimitry Andric 
23070b57cec5SDimitry Andric       Inst.addOperand(
23080b57cec5SDimitry Andric           MCOperand::createImm(fieldFromInstruction(Insn, 0, 4)));
23090b57cec5SDimitry Andric       return S;
23100b57cec5SDimitry Andric     }
23110b57cec5SDimitry Andric 
23120b57cec5SDimitry Andric     return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
23130b57cec5SDimitry Andric   }
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23160b57cec5SDimitry Andric     return MCDisassembler::Fail;
23170b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23180b57cec5SDimitry Andric     return MCDisassembler::Fail; // Tied
23190b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
23200b57cec5SDimitry Andric     return MCDisassembler::Fail;
23210b57cec5SDimitry Andric   if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
23220b57cec5SDimitry Andric     return MCDisassembler::Fail;
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric   return S;
23250b57cec5SDimitry Andric }
23260b57cec5SDimitry Andric 
23270b57cec5SDimitry Andric // Check for UNPREDICTABLE predicated ESB instruction
DecodeHINTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)23280b57cec5SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
23290b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
23300b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
23310b57cec5SDimitry Andric   unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
23320b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
23330b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
23360b57cec5SDimitry Andric 
23370b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm8));
23380b57cec5SDimitry Andric 
23390b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
23400b57cec5SDimitry Andric     return MCDisassembler::Fail;
23410b57cec5SDimitry Andric 
23420b57cec5SDimitry Andric   // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
23430b57cec5SDimitry Andric   // so all predicates should be allowed.
23440b57cec5SDimitry Andric   if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
23450b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
23460b57cec5SDimitry Andric 
23470b57cec5SDimitry Andric   return S;
23480b57cec5SDimitry Andric }
23490b57cec5SDimitry Andric 
DecodeCPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)23500b57cec5SDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
23510b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
23520b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 18, 2);
23530b57cec5SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 17, 1);
23540b57cec5SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 6, 3);
23550b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
23580b57cec5SDimitry Andric 
23590b57cec5SDimitry Andric   // This decoder is called from multiple location that do not check
23600b57cec5SDimitry Andric   // the full encoding is valid before they do.
23610b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 5, 1) != 0 ||
23620b57cec5SDimitry Andric       fieldFromInstruction(Insn, 16, 1) != 0 ||
23630b57cec5SDimitry Andric       fieldFromInstruction(Insn, 20, 8) != 0x10)
23640b57cec5SDimitry Andric     return MCDisassembler::Fail;
23650b57cec5SDimitry Andric 
23660b57cec5SDimitry Andric   // imod == '01' --> UNPREDICTABLE
23670b57cec5SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
23680b57cec5SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
23690b57cec5SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
23720b57cec5SDimitry Andric 
23730b57cec5SDimitry Andric   if (imod && M) {
23740b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS3p);
23750b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
23760b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
23770b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
23780b57cec5SDimitry Andric   } else if (imod && !M) {
23790b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS2p);
23800b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
23810b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
23820b57cec5SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
23830b57cec5SDimitry Andric   } else if (!imod && M) {
23840b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
23850b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
23860b57cec5SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
23870b57cec5SDimitry Andric   } else {
23880b57cec5SDimitry Andric     // imod == '00' && M == '0' --> UNPREDICTABLE
23890b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
23900b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
23910b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
23920b57cec5SDimitry Andric   }
23930b57cec5SDimitry Andric 
23940b57cec5SDimitry Andric   return S;
23950b57cec5SDimitry Andric }
23960b57cec5SDimitry Andric 
DecodeT2CPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)23970b57cec5SDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
23980b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
23990b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 9, 2);
24000b57cec5SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 8, 1);
24010b57cec5SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 5, 3);
24020b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
24030b57cec5SDimitry Andric 
24040b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24050b57cec5SDimitry Andric 
24060b57cec5SDimitry Andric   // imod == '01' --> UNPREDICTABLE
24070b57cec5SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
24080b57cec5SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
24090b57cec5SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
24100b57cec5SDimitry Andric 
24110b57cec5SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
24120b57cec5SDimitry Andric 
24130b57cec5SDimitry Andric   if (imod && M) {
24140b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS3p);
24150b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
24160b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
24170b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
24180b57cec5SDimitry Andric   } else if (imod && !M) {
24190b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS2p);
24200b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
24210b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
24220b57cec5SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
24230b57cec5SDimitry Andric   } else if (!imod && M) {
24240b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS1p);
24250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
24260b57cec5SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
24270b57cec5SDimitry Andric   } else {
24280b57cec5SDimitry Andric     // imod == '00' && M == '0' --> this is a HINT instruction
24290b57cec5SDimitry Andric     int imm = fieldFromInstruction(Insn, 0, 8);
24300b57cec5SDimitry Andric     // HINT are defined only for immediate in [0..4]
24310b57cec5SDimitry Andric     if(imm > 4) return MCDisassembler::Fail;
24320b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2HINT);
24330b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
24340b57cec5SDimitry Andric   }
24350b57cec5SDimitry Andric 
24360b57cec5SDimitry Andric   return S;
24370b57cec5SDimitry Andric }
24380b57cec5SDimitry Andric 
DecodeT2MOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)24390b57cec5SDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
24400b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
24410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24420b57cec5SDimitry Andric 
24430b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 8, 4);
24440b57cec5SDimitry Andric   unsigned imm = 0;
24450b57cec5SDimitry Andric 
24460b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
24470b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
24480b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
24490b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
24500b57cec5SDimitry Andric 
24510b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::t2MOVTi16)
24520b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
24530b57cec5SDimitry Andric       return MCDisassembler::Fail;
24540b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
24550b57cec5SDimitry Andric     return MCDisassembler::Fail;
24560b57cec5SDimitry Andric 
24570b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
24580b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
24590b57cec5SDimitry Andric 
24600b57cec5SDimitry Andric   return S;
24610b57cec5SDimitry Andric }
24620b57cec5SDimitry Andric 
DecodeArmMOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)24630b57cec5SDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
24640b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
24650b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24660b57cec5SDimitry Andric 
24670b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
24680b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
24690b57cec5SDimitry Andric   unsigned imm = 0;
24700b57cec5SDimitry Andric 
24710b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
24720b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
24730b57cec5SDimitry Andric 
24740b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MOVTi16)
24750b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
24760b57cec5SDimitry Andric       return MCDisassembler::Fail;
24770b57cec5SDimitry Andric 
24780b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
24790b57cec5SDimitry Andric     return MCDisassembler::Fail;
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
24820b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
24830b57cec5SDimitry Andric 
24840b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
24850b57cec5SDimitry Andric     return MCDisassembler::Fail;
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric   return S;
24880b57cec5SDimitry Andric }
24890b57cec5SDimitry Andric 
DecodeSMLAInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)24900b57cec5SDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
24910b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
24920b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24930b57cec5SDimitry Andric 
24940b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 16, 4);
24950b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 0, 4);
24960b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 8, 4);
24970b57cec5SDimitry Andric   unsigned Ra = fieldFromInstruction(Insn, 12, 4);
24980b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
24990b57cec5SDimitry Andric 
25000b57cec5SDimitry Andric   if (pred == 0xF)
25010b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
25020b57cec5SDimitry Andric 
25030b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
25040b57cec5SDimitry Andric     return MCDisassembler::Fail;
25050b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
25060b57cec5SDimitry Andric     return MCDisassembler::Fail;
25070b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
25080b57cec5SDimitry Andric     return MCDisassembler::Fail;
25090b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
25100b57cec5SDimitry Andric     return MCDisassembler::Fail;
25110b57cec5SDimitry Andric 
25120b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
25130b57cec5SDimitry Andric     return MCDisassembler::Fail;
25140b57cec5SDimitry Andric 
25150b57cec5SDimitry Andric   return S;
25160b57cec5SDimitry Andric }
25170b57cec5SDimitry Andric 
DecodeTSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)25180b57cec5SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
25190b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
25200b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25210b57cec5SDimitry Andric 
25220b57cec5SDimitry Andric   unsigned Pred = fieldFromInstruction(Insn, 28, 4);
25230b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
25240b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
25250b57cec5SDimitry Andric 
25260b57cec5SDimitry Andric   if (Pred == 0xF)
25270b57cec5SDimitry Andric     return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
25280b57cec5SDimitry Andric 
25290b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25300b57cec5SDimitry Andric     return MCDisassembler::Fail;
25310b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
25320b57cec5SDimitry Andric     return MCDisassembler::Fail;
25330b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
25340b57cec5SDimitry Andric     return MCDisassembler::Fail;
25350b57cec5SDimitry Andric 
25360b57cec5SDimitry Andric   return S;
25370b57cec5SDimitry Andric }
25380b57cec5SDimitry Andric 
DecodeSETPANInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)25390b57cec5SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
25400b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
25410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25420b57cec5SDimitry Andric 
25430b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 9, 1);
25440b57cec5SDimitry Andric 
25450b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
25460b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
25470b57cec5SDimitry Andric 
25480b57cec5SDimitry Andric   if (!FeatureBits[ARM::HasV8_1aOps] ||
25490b57cec5SDimitry Andric       !FeatureBits[ARM::HasV8Ops])
25500b57cec5SDimitry Andric     return MCDisassembler::Fail;
25510b57cec5SDimitry Andric 
25520b57cec5SDimitry Andric   // Decoder can be called from DecodeTST, which does not check the full
25530b57cec5SDimitry Andric   // encoding is valid.
25540b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
25550b57cec5SDimitry Andric       fieldFromInstruction(Insn, 4,4) != 0)
25560b57cec5SDimitry Andric     return MCDisassembler::Fail;
25570b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 10,10) != 0 ||
25580b57cec5SDimitry Andric       fieldFromInstruction(Insn, 0,4) != 0)
25590b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
25600b57cec5SDimitry Andric 
25610b57cec5SDimitry Andric   Inst.setOpcode(ARM::SETPAN);
25620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
25630b57cec5SDimitry Andric 
25640b57cec5SDimitry Andric   return S;
25650b57cec5SDimitry Andric }
25660b57cec5SDimitry Andric 
DecodeAddrModeImm12Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)25670b57cec5SDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
25680b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
25690b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25700b57cec5SDimitry Andric 
25710b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Val, 12, 1);
25720b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
25730b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
25740b57cec5SDimitry Andric 
25750b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25760b57cec5SDimitry Andric     return MCDisassembler::Fail;
25770b57cec5SDimitry Andric 
25780b57cec5SDimitry Andric   if (!add) imm *= -1;
25790b57cec5SDimitry Andric   if (imm == 0 && !add) imm = INT32_MIN;
25800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
25810b57cec5SDimitry Andric   if (Rn == 15)
25820b57cec5SDimitry Andric     tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   return S;
25850b57cec5SDimitry Andric }
25860b57cec5SDimitry Andric 
DecodeAddrMode5Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)25870b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
25880b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
25890b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25900b57cec5SDimitry Andric 
25910b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
25920b57cec5SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
25930b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
25940b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
25950b57cec5SDimitry Andric 
25960b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25970b57cec5SDimitry Andric     return MCDisassembler::Fail;
25980b57cec5SDimitry Andric 
25990b57cec5SDimitry Andric   if (U)
26000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
26010b57cec5SDimitry Andric   else
26020b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
26030b57cec5SDimitry Andric 
26040b57cec5SDimitry Andric   return S;
26050b57cec5SDimitry Andric }
26060b57cec5SDimitry Andric 
DecodeAddrMode5FP16Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)26070b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
26080b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
26090b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26100b57cec5SDimitry Andric 
26110b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
26120b57cec5SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
26130b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
26140b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
26150b57cec5SDimitry Andric 
26160b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
26170b57cec5SDimitry Andric     return MCDisassembler::Fail;
26180b57cec5SDimitry Andric 
26190b57cec5SDimitry Andric   if (U)
26200b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm)));
26210b57cec5SDimitry Andric   else
26220b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm)));
26230b57cec5SDimitry Andric 
26240b57cec5SDimitry Andric   return S;
26250b57cec5SDimitry Andric }
26260b57cec5SDimitry Andric 
DecodeAddrMode7Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)26270b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
26280b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
26290b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
26300b57cec5SDimitry Andric }
26310b57cec5SDimitry Andric 
26320b57cec5SDimitry Andric static DecodeStatus
DecodeT2BInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)26330b57cec5SDimitry Andric DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
26340b57cec5SDimitry Andric                      uint64_t Address, const void *Decoder) {
26350b57cec5SDimitry Andric   DecodeStatus Status = MCDisassembler::Success;
26360b57cec5SDimitry Andric 
26370b57cec5SDimitry Andric   // Note the J1 and J2 values are from the encoded instruction.  So here
26380b57cec5SDimitry Andric   // change them to I1 and I2 values via as documented:
26390b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
26400b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
26410b57cec5SDimitry Andric   // and build the imm32 with one trailing zero as documented:
26420b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
26430b57cec5SDimitry Andric   unsigned S = fieldFromInstruction(Insn, 26, 1);
26440b57cec5SDimitry Andric   unsigned J1 = fieldFromInstruction(Insn, 13, 1);
26450b57cec5SDimitry Andric   unsigned J2 = fieldFromInstruction(Insn, 11, 1);
26460b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
26470b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
26480b57cec5SDimitry Andric   unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
26490b57cec5SDimitry Andric   unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
26500b57cec5SDimitry Andric   unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
26510b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
26520b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
26530b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
26540b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
26550b57cec5SDimitry Andric 
26560b57cec5SDimitry Andric   return Status;
26570b57cec5SDimitry Andric }
26580b57cec5SDimitry Andric 
26590b57cec5SDimitry Andric static DecodeStatus
DecodeBranchImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)26600b57cec5SDimitry Andric DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
26610b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
26620b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26630b57cec5SDimitry Andric 
26640b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
26650b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
26660b57cec5SDimitry Andric 
26670b57cec5SDimitry Andric   if (pred == 0xF) {
26680b57cec5SDimitry Andric     Inst.setOpcode(ARM::BLXi);
26690b57cec5SDimitry Andric     imm |= fieldFromInstruction(Insn, 24, 1) << 1;
26700b57cec5SDimitry Andric     if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
26710b57cec5SDimitry Andric                                   true, 4, Inst, Decoder))
26720b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
26730b57cec5SDimitry Andric     return S;
26740b57cec5SDimitry Andric   }
26750b57cec5SDimitry Andric 
26760b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
26770b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
26780b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
2679*5f7ddb14SDimitry Andric 
2680*5f7ddb14SDimitry Andric   // We already have BL_pred for BL w/ predicate, no need to add addition
2681*5f7ddb14SDimitry Andric   // predicate opreands for BL
2682*5f7ddb14SDimitry Andric   if (Inst.getOpcode() != ARM::BL)
26830b57cec5SDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
26840b57cec5SDimitry Andric       return MCDisassembler::Fail;
26850b57cec5SDimitry Andric 
26860b57cec5SDimitry Andric   return S;
26870b57cec5SDimitry Andric }
26880b57cec5SDimitry Andric 
DecodeAddrMode6Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)26890b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
26900b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
26910b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26920b57cec5SDimitry Andric 
26930b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
26940b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Val, 4, 2);
26950b57cec5SDimitry Andric 
26960b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
26970b57cec5SDimitry Andric     return MCDisassembler::Fail;
26980b57cec5SDimitry Andric   if (!align)
26990b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
27000b57cec5SDimitry Andric   else
27010b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(4 << align));
27020b57cec5SDimitry Andric 
27030b57cec5SDimitry Andric   return S;
27040b57cec5SDimitry Andric }
27050b57cec5SDimitry Andric 
DecodeVLDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)27060b57cec5SDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
27070b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
27080b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27090b57cec5SDimitry Andric 
27100b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
27110b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
27120b57cec5SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
27130b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
27140b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
27150b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
27160b57cec5SDimitry Andric 
27170b57cec5SDimitry Andric   // First output register
27180b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
27190b57cec5SDimitry Andric   case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
27200b57cec5SDimitry Andric   case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
27210b57cec5SDimitry Andric   case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
27220b57cec5SDimitry Andric   case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
27230b57cec5SDimitry Andric   case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
27240b57cec5SDimitry Andric   case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
27250b57cec5SDimitry Andric   case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
27260b57cec5SDimitry Andric   case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
27270b57cec5SDimitry Andric   case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
27280b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
27290b57cec5SDimitry Andric       return MCDisassembler::Fail;
27300b57cec5SDimitry Andric     break;
27310b57cec5SDimitry Andric   case ARM::VLD2b16:
27320b57cec5SDimitry Andric   case ARM::VLD2b32:
27330b57cec5SDimitry Andric   case ARM::VLD2b8:
27340b57cec5SDimitry Andric   case ARM::VLD2b16wb_fixed:
27350b57cec5SDimitry Andric   case ARM::VLD2b16wb_register:
27360b57cec5SDimitry Andric   case ARM::VLD2b32wb_fixed:
27370b57cec5SDimitry Andric   case ARM::VLD2b32wb_register:
27380b57cec5SDimitry Andric   case ARM::VLD2b8wb_fixed:
27390b57cec5SDimitry Andric   case ARM::VLD2b8wb_register:
27400b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
27410b57cec5SDimitry Andric       return MCDisassembler::Fail;
27420b57cec5SDimitry Andric     break;
27430b57cec5SDimitry Andric   default:
27440b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
27450b57cec5SDimitry Andric       return MCDisassembler::Fail;
27460b57cec5SDimitry Andric   }
27470b57cec5SDimitry Andric 
27480b57cec5SDimitry Andric   // Second output register
27490b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
27500b57cec5SDimitry Andric     case ARM::VLD3d8:
27510b57cec5SDimitry Andric     case ARM::VLD3d16:
27520b57cec5SDimitry Andric     case ARM::VLD3d32:
27530b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
27540b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
27550b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
27560b57cec5SDimitry Andric     case ARM::VLD4d8:
27570b57cec5SDimitry Andric     case ARM::VLD4d16:
27580b57cec5SDimitry Andric     case ARM::VLD4d32:
27590b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
27600b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
27610b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
27620b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
27630b57cec5SDimitry Andric         return MCDisassembler::Fail;
27640b57cec5SDimitry Andric       break;
27650b57cec5SDimitry Andric     case ARM::VLD3q8:
27660b57cec5SDimitry Andric     case ARM::VLD3q16:
27670b57cec5SDimitry Andric     case ARM::VLD3q32:
27680b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
27690b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
27700b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
27710b57cec5SDimitry Andric     case ARM::VLD4q8:
27720b57cec5SDimitry Andric     case ARM::VLD4q16:
27730b57cec5SDimitry Andric     case ARM::VLD4q32:
27740b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
27750b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
27760b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
27770b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
27780b57cec5SDimitry Andric         return MCDisassembler::Fail;
27790b57cec5SDimitry Andric       break;
27800b57cec5SDimitry Andric     default:
27810b57cec5SDimitry Andric       break;
27820b57cec5SDimitry Andric   }
27830b57cec5SDimitry Andric 
27840b57cec5SDimitry Andric   // Third output register
27850b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
27860b57cec5SDimitry Andric     case ARM::VLD3d8:
27870b57cec5SDimitry Andric     case ARM::VLD3d16:
27880b57cec5SDimitry Andric     case ARM::VLD3d32:
27890b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
27900b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
27910b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
27920b57cec5SDimitry Andric     case ARM::VLD4d8:
27930b57cec5SDimitry Andric     case ARM::VLD4d16:
27940b57cec5SDimitry Andric     case ARM::VLD4d32:
27950b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
27960b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
27970b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
27980b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
27990b57cec5SDimitry Andric         return MCDisassembler::Fail;
28000b57cec5SDimitry Andric       break;
28010b57cec5SDimitry Andric     case ARM::VLD3q8:
28020b57cec5SDimitry Andric     case ARM::VLD3q16:
28030b57cec5SDimitry Andric     case ARM::VLD3q32:
28040b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
28050b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
28060b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
28070b57cec5SDimitry Andric     case ARM::VLD4q8:
28080b57cec5SDimitry Andric     case ARM::VLD4q16:
28090b57cec5SDimitry Andric     case ARM::VLD4q32:
28100b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
28110b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
28120b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
28130b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
28140b57cec5SDimitry Andric         return MCDisassembler::Fail;
28150b57cec5SDimitry Andric       break;
28160b57cec5SDimitry Andric     default:
28170b57cec5SDimitry Andric       break;
28180b57cec5SDimitry Andric   }
28190b57cec5SDimitry Andric 
28200b57cec5SDimitry Andric   // Fourth output register
28210b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
28220b57cec5SDimitry Andric     case ARM::VLD4d8:
28230b57cec5SDimitry Andric     case ARM::VLD4d16:
28240b57cec5SDimitry Andric     case ARM::VLD4d32:
28250b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
28260b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
28270b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
28280b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
28290b57cec5SDimitry Andric         return MCDisassembler::Fail;
28300b57cec5SDimitry Andric       break;
28310b57cec5SDimitry Andric     case ARM::VLD4q8:
28320b57cec5SDimitry Andric     case ARM::VLD4q16:
28330b57cec5SDimitry Andric     case ARM::VLD4q32:
28340b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
28350b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
28360b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
28370b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
28380b57cec5SDimitry Andric         return MCDisassembler::Fail;
28390b57cec5SDimitry Andric       break;
28400b57cec5SDimitry Andric     default:
28410b57cec5SDimitry Andric       break;
28420b57cec5SDimitry Andric   }
28430b57cec5SDimitry Andric 
28440b57cec5SDimitry Andric   // Writeback operand
28450b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
28460b57cec5SDimitry Andric     case ARM::VLD1d8wb_fixed:
28470b57cec5SDimitry Andric     case ARM::VLD1d16wb_fixed:
28480b57cec5SDimitry Andric     case ARM::VLD1d32wb_fixed:
28490b57cec5SDimitry Andric     case ARM::VLD1d64wb_fixed:
28500b57cec5SDimitry Andric     case ARM::VLD1d8wb_register:
28510b57cec5SDimitry Andric     case ARM::VLD1d16wb_register:
28520b57cec5SDimitry Andric     case ARM::VLD1d32wb_register:
28530b57cec5SDimitry Andric     case ARM::VLD1d64wb_register:
28540b57cec5SDimitry Andric     case ARM::VLD1q8wb_fixed:
28550b57cec5SDimitry Andric     case ARM::VLD1q16wb_fixed:
28560b57cec5SDimitry Andric     case ARM::VLD1q32wb_fixed:
28570b57cec5SDimitry Andric     case ARM::VLD1q64wb_fixed:
28580b57cec5SDimitry Andric     case ARM::VLD1q8wb_register:
28590b57cec5SDimitry Andric     case ARM::VLD1q16wb_register:
28600b57cec5SDimitry Andric     case ARM::VLD1q32wb_register:
28610b57cec5SDimitry Andric     case ARM::VLD1q64wb_register:
28620b57cec5SDimitry Andric     case ARM::VLD1d8Twb_fixed:
28630b57cec5SDimitry Andric     case ARM::VLD1d8Twb_register:
28640b57cec5SDimitry Andric     case ARM::VLD1d16Twb_fixed:
28650b57cec5SDimitry Andric     case ARM::VLD1d16Twb_register:
28660b57cec5SDimitry Andric     case ARM::VLD1d32Twb_fixed:
28670b57cec5SDimitry Andric     case ARM::VLD1d32Twb_register:
28680b57cec5SDimitry Andric     case ARM::VLD1d64Twb_fixed:
28690b57cec5SDimitry Andric     case ARM::VLD1d64Twb_register:
28700b57cec5SDimitry Andric     case ARM::VLD1d8Qwb_fixed:
28710b57cec5SDimitry Andric     case ARM::VLD1d8Qwb_register:
28720b57cec5SDimitry Andric     case ARM::VLD1d16Qwb_fixed:
28730b57cec5SDimitry Andric     case ARM::VLD1d16Qwb_register:
28740b57cec5SDimitry Andric     case ARM::VLD1d32Qwb_fixed:
28750b57cec5SDimitry Andric     case ARM::VLD1d32Qwb_register:
28760b57cec5SDimitry Andric     case ARM::VLD1d64Qwb_fixed:
28770b57cec5SDimitry Andric     case ARM::VLD1d64Qwb_register:
28780b57cec5SDimitry Andric     case ARM::VLD2d8wb_fixed:
28790b57cec5SDimitry Andric     case ARM::VLD2d16wb_fixed:
28800b57cec5SDimitry Andric     case ARM::VLD2d32wb_fixed:
28810b57cec5SDimitry Andric     case ARM::VLD2q8wb_fixed:
28820b57cec5SDimitry Andric     case ARM::VLD2q16wb_fixed:
28830b57cec5SDimitry Andric     case ARM::VLD2q32wb_fixed:
28840b57cec5SDimitry Andric     case ARM::VLD2d8wb_register:
28850b57cec5SDimitry Andric     case ARM::VLD2d16wb_register:
28860b57cec5SDimitry Andric     case ARM::VLD2d32wb_register:
28870b57cec5SDimitry Andric     case ARM::VLD2q8wb_register:
28880b57cec5SDimitry Andric     case ARM::VLD2q16wb_register:
28890b57cec5SDimitry Andric     case ARM::VLD2q32wb_register:
28900b57cec5SDimitry Andric     case ARM::VLD2b8wb_fixed:
28910b57cec5SDimitry Andric     case ARM::VLD2b16wb_fixed:
28920b57cec5SDimitry Andric     case ARM::VLD2b32wb_fixed:
28930b57cec5SDimitry Andric     case ARM::VLD2b8wb_register:
28940b57cec5SDimitry Andric     case ARM::VLD2b16wb_register:
28950b57cec5SDimitry Andric     case ARM::VLD2b32wb_register:
28960b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
28970b57cec5SDimitry Andric       break;
28980b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
28990b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
29000b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
29010b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
29020b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
29030b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
29040b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
29050b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
29060b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
29070b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
29080b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
29090b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
29100b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
29110b57cec5SDimitry Andric         return MCDisassembler::Fail;
29120b57cec5SDimitry Andric       break;
29130b57cec5SDimitry Andric     default:
29140b57cec5SDimitry Andric       break;
29150b57cec5SDimitry Andric   }
29160b57cec5SDimitry Andric 
29170b57cec5SDimitry Andric   // AddrMode6 Base (register+alignment)
29180b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
29190b57cec5SDimitry Andric     return MCDisassembler::Fail;
29200b57cec5SDimitry Andric 
29210b57cec5SDimitry Andric   // AddrMode6 Offset (register)
29220b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
29230b57cec5SDimitry Andric   default:
29240b57cec5SDimitry Andric     // The below have been updated to have explicit am6offset split
29250b57cec5SDimitry Andric     // between fixed and register offset. For those instructions not
29260b57cec5SDimitry Andric     // yet updated, we need to add an additional reg0 operand for the
29270b57cec5SDimitry Andric     // fixed variant.
29280b57cec5SDimitry Andric     //
29290b57cec5SDimitry Andric     // The fixed offset encodes as Rm == 0xd, so we check for that.
29300b57cec5SDimitry Andric     if (Rm == 0xd) {
29310b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
29320b57cec5SDimitry Andric       break;
29330b57cec5SDimitry Andric     }
29340b57cec5SDimitry Andric     // Fall through to handle the register offset variant.
29350b57cec5SDimitry Andric     LLVM_FALLTHROUGH;
29360b57cec5SDimitry Andric   case ARM::VLD1d8wb_fixed:
29370b57cec5SDimitry Andric   case ARM::VLD1d16wb_fixed:
29380b57cec5SDimitry Andric   case ARM::VLD1d32wb_fixed:
29390b57cec5SDimitry Andric   case ARM::VLD1d64wb_fixed:
29400b57cec5SDimitry Andric   case ARM::VLD1d8Twb_fixed:
29410b57cec5SDimitry Andric   case ARM::VLD1d16Twb_fixed:
29420b57cec5SDimitry Andric   case ARM::VLD1d32Twb_fixed:
29430b57cec5SDimitry Andric   case ARM::VLD1d64Twb_fixed:
29440b57cec5SDimitry Andric   case ARM::VLD1d8Qwb_fixed:
29450b57cec5SDimitry Andric   case ARM::VLD1d16Qwb_fixed:
29460b57cec5SDimitry Andric   case ARM::VLD1d32Qwb_fixed:
29470b57cec5SDimitry Andric   case ARM::VLD1d64Qwb_fixed:
29480b57cec5SDimitry Andric   case ARM::VLD1d8wb_register:
29490b57cec5SDimitry Andric   case ARM::VLD1d16wb_register:
29500b57cec5SDimitry Andric   case ARM::VLD1d32wb_register:
29510b57cec5SDimitry Andric   case ARM::VLD1d64wb_register:
29520b57cec5SDimitry Andric   case ARM::VLD1q8wb_fixed:
29530b57cec5SDimitry Andric   case ARM::VLD1q16wb_fixed:
29540b57cec5SDimitry Andric   case ARM::VLD1q32wb_fixed:
29550b57cec5SDimitry Andric   case ARM::VLD1q64wb_fixed:
29560b57cec5SDimitry Andric   case ARM::VLD1q8wb_register:
29570b57cec5SDimitry Andric   case ARM::VLD1q16wb_register:
29580b57cec5SDimitry Andric   case ARM::VLD1q32wb_register:
29590b57cec5SDimitry Andric   case ARM::VLD1q64wb_register:
29600b57cec5SDimitry Andric     // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
29610b57cec5SDimitry Andric     // variant encodes Rm == 0xf. Anything else is a register offset post-
29620b57cec5SDimitry Andric     // increment and we need to add the register operand to the instruction.
29630b57cec5SDimitry Andric     if (Rm != 0xD && Rm != 0xF &&
29640b57cec5SDimitry Andric         !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
29650b57cec5SDimitry Andric       return MCDisassembler::Fail;
29660b57cec5SDimitry Andric     break;
29670b57cec5SDimitry Andric   case ARM::VLD2d8wb_fixed:
29680b57cec5SDimitry Andric   case ARM::VLD2d16wb_fixed:
29690b57cec5SDimitry Andric   case ARM::VLD2d32wb_fixed:
29700b57cec5SDimitry Andric   case ARM::VLD2b8wb_fixed:
29710b57cec5SDimitry Andric   case ARM::VLD2b16wb_fixed:
29720b57cec5SDimitry Andric   case ARM::VLD2b32wb_fixed:
29730b57cec5SDimitry Andric   case ARM::VLD2q8wb_fixed:
29740b57cec5SDimitry Andric   case ARM::VLD2q16wb_fixed:
29750b57cec5SDimitry Andric   case ARM::VLD2q32wb_fixed:
29760b57cec5SDimitry Andric     break;
29770b57cec5SDimitry Andric   }
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric   return S;
29800b57cec5SDimitry Andric }
29810b57cec5SDimitry Andric 
DecodeVLDST1Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)29820b57cec5SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
29830b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
29840b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
29850b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
29860b57cec5SDimitry Andric   if (type == 6 && (align & 2)) return MCDisassembler::Fail;
29870b57cec5SDimitry Andric   if (type == 7 && (align & 2)) return MCDisassembler::Fail;
29880b57cec5SDimitry Andric   if (type == 10 && align == 3) return MCDisassembler::Fail;
29890b57cec5SDimitry Andric 
29900b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
29910b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
29920b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
29930b57cec5SDimitry Andric }
29940b57cec5SDimitry Andric 
DecodeVLDST2Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)29950b57cec5SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
29960b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
29970b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
29980b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
29990b57cec5SDimitry Andric 
30000b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
30010b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
30020b57cec5SDimitry Andric   if (type == 8 && align == 3) return MCDisassembler::Fail;
30030b57cec5SDimitry Andric   if (type == 9 && align == 3) return MCDisassembler::Fail;
30040b57cec5SDimitry Andric 
30050b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
30060b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
30070b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
30080b57cec5SDimitry Andric }
30090b57cec5SDimitry Andric 
DecodeVLDST3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)30100b57cec5SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
30110b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
30120b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
30130b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
30140b57cec5SDimitry Andric 
30150b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
30160b57cec5SDimitry Andric   if (align & 2) return MCDisassembler::Fail;
30170b57cec5SDimitry Andric 
30180b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
30190b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
30200b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
30210b57cec5SDimitry Andric }
30220b57cec5SDimitry Andric 
DecodeVLDST4Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)30230b57cec5SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
30240b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
30250b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
30260b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
30270b57cec5SDimitry Andric 
30280b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
30290b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
30300b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
30310b57cec5SDimitry Andric }
30320b57cec5SDimitry Andric 
DecodeVSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)30330b57cec5SDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
30340b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
30350b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
30380b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
30390b57cec5SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
30400b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
30410b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
30420b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
30430b57cec5SDimitry Andric 
30440b57cec5SDimitry Andric   // Writeback Operand
30450b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
30460b57cec5SDimitry Andric     case ARM::VST1d8wb_fixed:
30470b57cec5SDimitry Andric     case ARM::VST1d16wb_fixed:
30480b57cec5SDimitry Andric     case ARM::VST1d32wb_fixed:
30490b57cec5SDimitry Andric     case ARM::VST1d64wb_fixed:
30500b57cec5SDimitry Andric     case ARM::VST1d8wb_register:
30510b57cec5SDimitry Andric     case ARM::VST1d16wb_register:
30520b57cec5SDimitry Andric     case ARM::VST1d32wb_register:
30530b57cec5SDimitry Andric     case ARM::VST1d64wb_register:
30540b57cec5SDimitry Andric     case ARM::VST1q8wb_fixed:
30550b57cec5SDimitry Andric     case ARM::VST1q16wb_fixed:
30560b57cec5SDimitry Andric     case ARM::VST1q32wb_fixed:
30570b57cec5SDimitry Andric     case ARM::VST1q64wb_fixed:
30580b57cec5SDimitry Andric     case ARM::VST1q8wb_register:
30590b57cec5SDimitry Andric     case ARM::VST1q16wb_register:
30600b57cec5SDimitry Andric     case ARM::VST1q32wb_register:
30610b57cec5SDimitry Andric     case ARM::VST1q64wb_register:
30620b57cec5SDimitry Andric     case ARM::VST1d8Twb_fixed:
30630b57cec5SDimitry Andric     case ARM::VST1d16Twb_fixed:
30640b57cec5SDimitry Andric     case ARM::VST1d32Twb_fixed:
30650b57cec5SDimitry Andric     case ARM::VST1d64Twb_fixed:
30660b57cec5SDimitry Andric     case ARM::VST1d8Twb_register:
30670b57cec5SDimitry Andric     case ARM::VST1d16Twb_register:
30680b57cec5SDimitry Andric     case ARM::VST1d32Twb_register:
30690b57cec5SDimitry Andric     case ARM::VST1d64Twb_register:
30700b57cec5SDimitry Andric     case ARM::VST1d8Qwb_fixed:
30710b57cec5SDimitry Andric     case ARM::VST1d16Qwb_fixed:
30720b57cec5SDimitry Andric     case ARM::VST1d32Qwb_fixed:
30730b57cec5SDimitry Andric     case ARM::VST1d64Qwb_fixed:
30740b57cec5SDimitry Andric     case ARM::VST1d8Qwb_register:
30750b57cec5SDimitry Andric     case ARM::VST1d16Qwb_register:
30760b57cec5SDimitry Andric     case ARM::VST1d32Qwb_register:
30770b57cec5SDimitry Andric     case ARM::VST1d64Qwb_register:
30780b57cec5SDimitry Andric     case ARM::VST2d8wb_fixed:
30790b57cec5SDimitry Andric     case ARM::VST2d16wb_fixed:
30800b57cec5SDimitry Andric     case ARM::VST2d32wb_fixed:
30810b57cec5SDimitry Andric     case ARM::VST2d8wb_register:
30820b57cec5SDimitry Andric     case ARM::VST2d16wb_register:
30830b57cec5SDimitry Andric     case ARM::VST2d32wb_register:
30840b57cec5SDimitry Andric     case ARM::VST2q8wb_fixed:
30850b57cec5SDimitry Andric     case ARM::VST2q16wb_fixed:
30860b57cec5SDimitry Andric     case ARM::VST2q32wb_fixed:
30870b57cec5SDimitry Andric     case ARM::VST2q8wb_register:
30880b57cec5SDimitry Andric     case ARM::VST2q16wb_register:
30890b57cec5SDimitry Andric     case ARM::VST2q32wb_register:
30900b57cec5SDimitry Andric     case ARM::VST2b8wb_fixed:
30910b57cec5SDimitry Andric     case ARM::VST2b16wb_fixed:
30920b57cec5SDimitry Andric     case ARM::VST2b32wb_fixed:
30930b57cec5SDimitry Andric     case ARM::VST2b8wb_register:
30940b57cec5SDimitry Andric     case ARM::VST2b16wb_register:
30950b57cec5SDimitry Andric     case ARM::VST2b32wb_register:
30960b57cec5SDimitry Andric       if (Rm == 0xF)
30970b57cec5SDimitry Andric         return MCDisassembler::Fail;
30980b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
30990b57cec5SDimitry Andric       break;
31000b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
31010b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
31020b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
31030b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
31040b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
31050b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
31060b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
31070b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
31080b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
31090b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
31100b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
31110b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
31120b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
31130b57cec5SDimitry Andric         return MCDisassembler::Fail;
31140b57cec5SDimitry Andric       break;
31150b57cec5SDimitry Andric     default:
31160b57cec5SDimitry Andric       break;
31170b57cec5SDimitry Andric   }
31180b57cec5SDimitry Andric 
31190b57cec5SDimitry Andric   // AddrMode6 Base (register+alignment)
31200b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
31210b57cec5SDimitry Andric     return MCDisassembler::Fail;
31220b57cec5SDimitry Andric 
31230b57cec5SDimitry Andric   // AddrMode6 Offset (register)
31240b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
31250b57cec5SDimitry Andric     default:
31260b57cec5SDimitry Andric       if (Rm == 0xD)
31270b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createReg(0));
31280b57cec5SDimitry Andric       else if (Rm != 0xF) {
31290b57cec5SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
31300b57cec5SDimitry Andric           return MCDisassembler::Fail;
31310b57cec5SDimitry Andric       }
31320b57cec5SDimitry Andric       break;
31330b57cec5SDimitry Andric     case ARM::VST1d8wb_fixed:
31340b57cec5SDimitry Andric     case ARM::VST1d16wb_fixed:
31350b57cec5SDimitry Andric     case ARM::VST1d32wb_fixed:
31360b57cec5SDimitry Andric     case ARM::VST1d64wb_fixed:
31370b57cec5SDimitry Andric     case ARM::VST1q8wb_fixed:
31380b57cec5SDimitry Andric     case ARM::VST1q16wb_fixed:
31390b57cec5SDimitry Andric     case ARM::VST1q32wb_fixed:
31400b57cec5SDimitry Andric     case ARM::VST1q64wb_fixed:
31410b57cec5SDimitry Andric     case ARM::VST1d8Twb_fixed:
31420b57cec5SDimitry Andric     case ARM::VST1d16Twb_fixed:
31430b57cec5SDimitry Andric     case ARM::VST1d32Twb_fixed:
31440b57cec5SDimitry Andric     case ARM::VST1d64Twb_fixed:
31450b57cec5SDimitry Andric     case ARM::VST1d8Qwb_fixed:
31460b57cec5SDimitry Andric     case ARM::VST1d16Qwb_fixed:
31470b57cec5SDimitry Andric     case ARM::VST1d32Qwb_fixed:
31480b57cec5SDimitry Andric     case ARM::VST1d64Qwb_fixed:
31490b57cec5SDimitry Andric     case ARM::VST2d8wb_fixed:
31500b57cec5SDimitry Andric     case ARM::VST2d16wb_fixed:
31510b57cec5SDimitry Andric     case ARM::VST2d32wb_fixed:
31520b57cec5SDimitry Andric     case ARM::VST2q8wb_fixed:
31530b57cec5SDimitry Andric     case ARM::VST2q16wb_fixed:
31540b57cec5SDimitry Andric     case ARM::VST2q32wb_fixed:
31550b57cec5SDimitry Andric     case ARM::VST2b8wb_fixed:
31560b57cec5SDimitry Andric     case ARM::VST2b16wb_fixed:
31570b57cec5SDimitry Andric     case ARM::VST2b32wb_fixed:
31580b57cec5SDimitry Andric       break;
31590b57cec5SDimitry Andric   }
31600b57cec5SDimitry Andric 
31610b57cec5SDimitry Andric   // First input register
31620b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
31630b57cec5SDimitry Andric   case ARM::VST1q16:
31640b57cec5SDimitry Andric   case ARM::VST1q32:
31650b57cec5SDimitry Andric   case ARM::VST1q64:
31660b57cec5SDimitry Andric   case ARM::VST1q8:
31670b57cec5SDimitry Andric   case ARM::VST1q16wb_fixed:
31680b57cec5SDimitry Andric   case ARM::VST1q16wb_register:
31690b57cec5SDimitry Andric   case ARM::VST1q32wb_fixed:
31700b57cec5SDimitry Andric   case ARM::VST1q32wb_register:
31710b57cec5SDimitry Andric   case ARM::VST1q64wb_fixed:
31720b57cec5SDimitry Andric   case ARM::VST1q64wb_register:
31730b57cec5SDimitry Andric   case ARM::VST1q8wb_fixed:
31740b57cec5SDimitry Andric   case ARM::VST1q8wb_register:
31750b57cec5SDimitry Andric   case ARM::VST2d16:
31760b57cec5SDimitry Andric   case ARM::VST2d32:
31770b57cec5SDimitry Andric   case ARM::VST2d8:
31780b57cec5SDimitry Andric   case ARM::VST2d16wb_fixed:
31790b57cec5SDimitry Andric   case ARM::VST2d16wb_register:
31800b57cec5SDimitry Andric   case ARM::VST2d32wb_fixed:
31810b57cec5SDimitry Andric   case ARM::VST2d32wb_register:
31820b57cec5SDimitry Andric   case ARM::VST2d8wb_fixed:
31830b57cec5SDimitry Andric   case ARM::VST2d8wb_register:
31840b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
31850b57cec5SDimitry Andric       return MCDisassembler::Fail;
31860b57cec5SDimitry Andric     break;
31870b57cec5SDimitry Andric   case ARM::VST2b16:
31880b57cec5SDimitry Andric   case ARM::VST2b32:
31890b57cec5SDimitry Andric   case ARM::VST2b8:
31900b57cec5SDimitry Andric   case ARM::VST2b16wb_fixed:
31910b57cec5SDimitry Andric   case ARM::VST2b16wb_register:
31920b57cec5SDimitry Andric   case ARM::VST2b32wb_fixed:
31930b57cec5SDimitry Andric   case ARM::VST2b32wb_register:
31940b57cec5SDimitry Andric   case ARM::VST2b8wb_fixed:
31950b57cec5SDimitry Andric   case ARM::VST2b8wb_register:
31960b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
31970b57cec5SDimitry Andric       return MCDisassembler::Fail;
31980b57cec5SDimitry Andric     break;
31990b57cec5SDimitry Andric   default:
32000b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
32010b57cec5SDimitry Andric       return MCDisassembler::Fail;
32020b57cec5SDimitry Andric   }
32030b57cec5SDimitry Andric 
32040b57cec5SDimitry Andric   // Second input register
32050b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
32060b57cec5SDimitry Andric     case ARM::VST3d8:
32070b57cec5SDimitry Andric     case ARM::VST3d16:
32080b57cec5SDimitry Andric     case ARM::VST3d32:
32090b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
32100b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
32110b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
32120b57cec5SDimitry Andric     case ARM::VST4d8:
32130b57cec5SDimitry Andric     case ARM::VST4d16:
32140b57cec5SDimitry Andric     case ARM::VST4d32:
32150b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
32160b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
32170b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
32180b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
32190b57cec5SDimitry Andric         return MCDisassembler::Fail;
32200b57cec5SDimitry Andric       break;
32210b57cec5SDimitry Andric     case ARM::VST3q8:
32220b57cec5SDimitry Andric     case ARM::VST3q16:
32230b57cec5SDimitry Andric     case ARM::VST3q32:
32240b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
32250b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
32260b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
32270b57cec5SDimitry Andric     case ARM::VST4q8:
32280b57cec5SDimitry Andric     case ARM::VST4q16:
32290b57cec5SDimitry Andric     case ARM::VST4q32:
32300b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
32310b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
32320b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
32330b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
32340b57cec5SDimitry Andric         return MCDisassembler::Fail;
32350b57cec5SDimitry Andric       break;
32360b57cec5SDimitry Andric     default:
32370b57cec5SDimitry Andric       break;
32380b57cec5SDimitry Andric   }
32390b57cec5SDimitry Andric 
32400b57cec5SDimitry Andric   // Third input register
32410b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
32420b57cec5SDimitry Andric     case ARM::VST3d8:
32430b57cec5SDimitry Andric     case ARM::VST3d16:
32440b57cec5SDimitry Andric     case ARM::VST3d32:
32450b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
32460b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
32470b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
32480b57cec5SDimitry Andric     case ARM::VST4d8:
32490b57cec5SDimitry Andric     case ARM::VST4d16:
32500b57cec5SDimitry Andric     case ARM::VST4d32:
32510b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
32520b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
32530b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
32540b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
32550b57cec5SDimitry Andric         return MCDisassembler::Fail;
32560b57cec5SDimitry Andric       break;
32570b57cec5SDimitry Andric     case ARM::VST3q8:
32580b57cec5SDimitry Andric     case ARM::VST3q16:
32590b57cec5SDimitry Andric     case ARM::VST3q32:
32600b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
32610b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
32620b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
32630b57cec5SDimitry Andric     case ARM::VST4q8:
32640b57cec5SDimitry Andric     case ARM::VST4q16:
32650b57cec5SDimitry Andric     case ARM::VST4q32:
32660b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
32670b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
32680b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
32690b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
32700b57cec5SDimitry Andric         return MCDisassembler::Fail;
32710b57cec5SDimitry Andric       break;
32720b57cec5SDimitry Andric     default:
32730b57cec5SDimitry Andric       break;
32740b57cec5SDimitry Andric   }
32750b57cec5SDimitry Andric 
32760b57cec5SDimitry Andric   // Fourth input register
32770b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
32780b57cec5SDimitry Andric     case ARM::VST4d8:
32790b57cec5SDimitry Andric     case ARM::VST4d16:
32800b57cec5SDimitry Andric     case ARM::VST4d32:
32810b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
32820b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
32830b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
32840b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
32850b57cec5SDimitry Andric         return MCDisassembler::Fail;
32860b57cec5SDimitry Andric       break;
32870b57cec5SDimitry Andric     case ARM::VST4q8:
32880b57cec5SDimitry Andric     case ARM::VST4q16:
32890b57cec5SDimitry Andric     case ARM::VST4q32:
32900b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
32910b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
32920b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
32930b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
32940b57cec5SDimitry Andric         return MCDisassembler::Fail;
32950b57cec5SDimitry Andric       break;
32960b57cec5SDimitry Andric     default:
32970b57cec5SDimitry Andric       break;
32980b57cec5SDimitry Andric   }
32990b57cec5SDimitry Andric 
33000b57cec5SDimitry Andric   return S;
33010b57cec5SDimitry Andric }
33020b57cec5SDimitry Andric 
DecodeVLD1DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)33030b57cec5SDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
33040b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
33050b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
33060b57cec5SDimitry Andric 
33070b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
33080b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
33090b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
33100b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
33110b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
33120b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
33130b57cec5SDimitry Andric 
33140b57cec5SDimitry Andric   if (size == 0 && align == 1)
33150b57cec5SDimitry Andric     return MCDisassembler::Fail;
33160b57cec5SDimitry Andric   align *= (1 << size);
33170b57cec5SDimitry Andric 
33180b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
33190b57cec5SDimitry Andric   case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
33200b57cec5SDimitry Andric   case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
33210b57cec5SDimitry Andric   case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
33220b57cec5SDimitry Andric   case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
33230b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
33240b57cec5SDimitry Andric       return MCDisassembler::Fail;
33250b57cec5SDimitry Andric     break;
33260b57cec5SDimitry Andric   default:
33270b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
33280b57cec5SDimitry Andric       return MCDisassembler::Fail;
33290b57cec5SDimitry Andric     break;
33300b57cec5SDimitry Andric   }
33310b57cec5SDimitry Andric   if (Rm != 0xF) {
33320b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
33330b57cec5SDimitry Andric       return MCDisassembler::Fail;
33340b57cec5SDimitry Andric   }
33350b57cec5SDimitry Andric 
33360b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
33370b57cec5SDimitry Andric     return MCDisassembler::Fail;
33380b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
33390b57cec5SDimitry Andric 
33400b57cec5SDimitry Andric   // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
33410b57cec5SDimitry Andric   // variant encodes Rm == 0xf. Anything else is a register offset post-
33420b57cec5SDimitry Andric   // increment and we need to add the register operand to the instruction.
33430b57cec5SDimitry Andric   if (Rm != 0xD && Rm != 0xF &&
33440b57cec5SDimitry Andric       !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
33450b57cec5SDimitry Andric     return MCDisassembler::Fail;
33460b57cec5SDimitry Andric 
33470b57cec5SDimitry Andric   return S;
33480b57cec5SDimitry Andric }
33490b57cec5SDimitry Andric 
DecodeVLD2DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)33500b57cec5SDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
33510b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
33520b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
33530b57cec5SDimitry Andric 
33540b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
33550b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
33560b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
33570b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
33580b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
33590b57cec5SDimitry Andric   unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
33600b57cec5SDimitry Andric   align *= 2*size;
33610b57cec5SDimitry Andric 
33620b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
33630b57cec5SDimitry Andric   case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
33640b57cec5SDimitry Andric   case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
33650b57cec5SDimitry Andric   case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
33660b57cec5SDimitry Andric   case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
33670b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
33680b57cec5SDimitry Andric       return MCDisassembler::Fail;
33690b57cec5SDimitry Andric     break;
33700b57cec5SDimitry Andric   case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
33710b57cec5SDimitry Andric   case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
33720b57cec5SDimitry Andric   case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
33730b57cec5SDimitry Andric   case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
33740b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
33750b57cec5SDimitry Andric       return MCDisassembler::Fail;
33760b57cec5SDimitry Andric     break;
33770b57cec5SDimitry Andric   default:
33780b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
33790b57cec5SDimitry Andric       return MCDisassembler::Fail;
33800b57cec5SDimitry Andric     break;
33810b57cec5SDimitry Andric   }
33820b57cec5SDimitry Andric 
33830b57cec5SDimitry Andric   if (Rm != 0xF)
33840b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
33850b57cec5SDimitry Andric 
33860b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
33870b57cec5SDimitry Andric     return MCDisassembler::Fail;
33880b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
33890b57cec5SDimitry Andric 
33900b57cec5SDimitry Andric   if (Rm != 0xD && Rm != 0xF) {
33910b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
33920b57cec5SDimitry Andric       return MCDisassembler::Fail;
33930b57cec5SDimitry Andric   }
33940b57cec5SDimitry Andric 
33950b57cec5SDimitry Andric   return S;
33960b57cec5SDimitry Andric }
33970b57cec5SDimitry Andric 
DecodeVLD3DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)33980b57cec5SDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
33990b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
34000b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
34010b57cec5SDimitry Andric 
34020b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
34030b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
34040b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
34050b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
34060b57cec5SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
34070b57cec5SDimitry Andric 
34080b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
34090b57cec5SDimitry Andric     return MCDisassembler::Fail;
34100b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
34110b57cec5SDimitry Andric     return MCDisassembler::Fail;
34120b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
34130b57cec5SDimitry Andric     return MCDisassembler::Fail;
34140b57cec5SDimitry Andric   if (Rm != 0xF) {
34150b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
34160b57cec5SDimitry Andric       return MCDisassembler::Fail;
34170b57cec5SDimitry Andric   }
34180b57cec5SDimitry Andric 
34190b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
34200b57cec5SDimitry Andric     return MCDisassembler::Fail;
34210b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
34220b57cec5SDimitry Andric 
34230b57cec5SDimitry Andric   if (Rm == 0xD)
34240b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
34250b57cec5SDimitry Andric   else if (Rm != 0xF) {
34260b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
34270b57cec5SDimitry Andric       return MCDisassembler::Fail;
34280b57cec5SDimitry Andric   }
34290b57cec5SDimitry Andric 
34300b57cec5SDimitry Andric   return S;
34310b57cec5SDimitry Andric }
34320b57cec5SDimitry Andric 
DecodeVLD4DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)34330b57cec5SDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
34340b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
34350b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
34360b57cec5SDimitry Andric 
34370b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
34380b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
34390b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
34400b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
34410b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
34420b57cec5SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
34430b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
34440b57cec5SDimitry Andric 
34450b57cec5SDimitry Andric   if (size == 0x3) {
34460b57cec5SDimitry Andric     if (align == 0)
34470b57cec5SDimitry Andric       return MCDisassembler::Fail;
34480b57cec5SDimitry Andric     align = 16;
34490b57cec5SDimitry Andric   } else {
34500b57cec5SDimitry Andric     if (size == 2) {
34510b57cec5SDimitry Andric       align *= 8;
34520b57cec5SDimitry Andric     } else {
34530b57cec5SDimitry Andric       size = 1 << size;
34540b57cec5SDimitry Andric       align *= 4*size;
34550b57cec5SDimitry Andric     }
34560b57cec5SDimitry Andric   }
34570b57cec5SDimitry Andric 
34580b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
34590b57cec5SDimitry Andric     return MCDisassembler::Fail;
34600b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
34610b57cec5SDimitry Andric     return MCDisassembler::Fail;
34620b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
34630b57cec5SDimitry Andric     return MCDisassembler::Fail;
34640b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
34650b57cec5SDimitry Andric     return MCDisassembler::Fail;
34660b57cec5SDimitry Andric   if (Rm != 0xF) {
34670b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
34680b57cec5SDimitry Andric       return MCDisassembler::Fail;
34690b57cec5SDimitry Andric   }
34700b57cec5SDimitry Andric 
34710b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
34720b57cec5SDimitry Andric     return MCDisassembler::Fail;
34730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
34740b57cec5SDimitry Andric 
34750b57cec5SDimitry Andric   if (Rm == 0xD)
34760b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
34770b57cec5SDimitry Andric   else if (Rm != 0xF) {
34780b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
34790b57cec5SDimitry Andric       return MCDisassembler::Fail;
34800b57cec5SDimitry Andric   }
34810b57cec5SDimitry Andric 
34820b57cec5SDimitry Andric   return S;
34830b57cec5SDimitry Andric }
34840b57cec5SDimitry Andric 
34850b57cec5SDimitry Andric static DecodeStatus
DecodeVMOVModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)34868bcb0991SDimitry Andric DecodeVMOVModImmInstruction(MCInst &Inst, unsigned Insn,
34870b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
34880b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
34890b57cec5SDimitry Andric 
34900b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
34910b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
34920b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
34930b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
34940b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 24, 1) << 7;
34950b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 8, 4) << 8;
34960b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1) << 12;
34970b57cec5SDimitry Andric   unsigned Q = fieldFromInstruction(Insn, 6, 1);
34980b57cec5SDimitry Andric 
34990b57cec5SDimitry Andric   if (Q) {
35000b57cec5SDimitry Andric     if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
35010b57cec5SDimitry Andric     return MCDisassembler::Fail;
35020b57cec5SDimitry Andric   } else {
35030b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
35040b57cec5SDimitry Andric     return MCDisassembler::Fail;
35050b57cec5SDimitry Andric   }
35060b57cec5SDimitry Andric 
35070b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
35080b57cec5SDimitry Andric 
35090b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
35100b57cec5SDimitry Andric     case ARM::VORRiv4i16:
35110b57cec5SDimitry Andric     case ARM::VORRiv2i32:
35120b57cec5SDimitry Andric     case ARM::VBICiv4i16:
35130b57cec5SDimitry Andric     case ARM::VBICiv2i32:
35140b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
35150b57cec5SDimitry Andric         return MCDisassembler::Fail;
35160b57cec5SDimitry Andric       break;
35170b57cec5SDimitry Andric     case ARM::VORRiv8i16:
35180b57cec5SDimitry Andric     case ARM::VORRiv4i32:
35190b57cec5SDimitry Andric     case ARM::VBICiv8i16:
35200b57cec5SDimitry Andric     case ARM::VBICiv4i32:
35210b57cec5SDimitry Andric       if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
35220b57cec5SDimitry Andric         return MCDisassembler::Fail;
35230b57cec5SDimitry Andric       break;
35240b57cec5SDimitry Andric     default:
35250b57cec5SDimitry Andric       break;
35260b57cec5SDimitry Andric   }
35270b57cec5SDimitry Andric 
35280b57cec5SDimitry Andric   return S;
35290b57cec5SDimitry Andric }
35300b57cec5SDimitry Andric 
35310b57cec5SDimitry Andric static DecodeStatus
DecodeMVEModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)35320b57cec5SDimitry Andric DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
35330b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
35340b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
35350b57cec5SDimitry Andric 
35360b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
35370b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
35380b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
35390b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
35400b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
35410b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 28, 1) << 7;
35420b57cec5SDimitry Andric   imm |= cmode                             << 8;
35430b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1)  << 12;
35440b57cec5SDimitry Andric 
35450b57cec5SDimitry Andric   if (cmode == 0xF && Inst.getOpcode() == ARM::MVE_VMVNimmi32)
35460b57cec5SDimitry Andric     return MCDisassembler::Fail;
35470b57cec5SDimitry Andric 
35480b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
35490b57cec5SDimitry Andric     return MCDisassembler::Fail;
35500b57cec5SDimitry Andric 
35510b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
35520b57cec5SDimitry Andric 
35530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
35540b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
35550b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
35560b57cec5SDimitry Andric 
35570b57cec5SDimitry Andric   return S;
35580b57cec5SDimitry Andric }
35590b57cec5SDimitry Andric 
DecodeMVEVADCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)35600b57cec5SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
35610b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
35620b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
35630b57cec5SDimitry Andric 
35640b57cec5SDimitry Andric   unsigned Qd = fieldFromInstruction(Insn, 13, 3);
35650b57cec5SDimitry Andric   Qd |= fieldFromInstruction(Insn, 22, 1) << 3;
35660b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
35670b57cec5SDimitry Andric     return MCDisassembler::Fail;
35680b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
35690b57cec5SDimitry Andric 
35700b57cec5SDimitry Andric   unsigned Qn = fieldFromInstruction(Insn, 17, 3);
35710b57cec5SDimitry Andric   Qn |= fieldFromInstruction(Insn, 7, 1) << 3;
35720b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
35730b57cec5SDimitry Andric     return MCDisassembler::Fail;
35740b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 1, 3);
35750b57cec5SDimitry Andric   Qm |= fieldFromInstruction(Insn, 5, 1) << 3;
35760b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
35770b57cec5SDimitry Andric     return MCDisassembler::Fail;
35780b57cec5SDimitry Andric   if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
35790b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
35800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Qd));
35810b57cec5SDimitry Andric 
35820b57cec5SDimitry Andric   return S;
35830b57cec5SDimitry Andric }
35840b57cec5SDimitry Andric 
DecodeVSHLMaxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)35850b57cec5SDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
35860b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
35870b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
35880b57cec5SDimitry Andric 
35890b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
35900b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
35910b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
35920b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
35930b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 18, 2);
35940b57cec5SDimitry Andric 
35950b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
35960b57cec5SDimitry Andric     return MCDisassembler::Fail;
35970b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
35980b57cec5SDimitry Andric     return MCDisassembler::Fail;
35990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 << size));
36000b57cec5SDimitry Andric 
36010b57cec5SDimitry Andric   return S;
36020b57cec5SDimitry Andric }
36030b57cec5SDimitry Andric 
DecodeShiftRight8Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)36040b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
36050b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
36060b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 - Val));
36070b57cec5SDimitry Andric   return MCDisassembler::Success;
36080b57cec5SDimitry Andric }
36090b57cec5SDimitry Andric 
DecodeShiftRight16Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)36100b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
36110b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
36120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(16 - Val));
36130b57cec5SDimitry Andric   return MCDisassembler::Success;
36140b57cec5SDimitry Andric }
36150b57cec5SDimitry Andric 
DecodeShiftRight32Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)36160b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
36170b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
36180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(32 - Val));
36190b57cec5SDimitry Andric   return MCDisassembler::Success;
36200b57cec5SDimitry Andric }
36210b57cec5SDimitry Andric 
DecodeShiftRight64Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)36220b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
36230b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
36240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
36250b57cec5SDimitry Andric   return MCDisassembler::Success;
36260b57cec5SDimitry Andric }
36270b57cec5SDimitry Andric 
DecodeTBLInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)36280b57cec5SDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
36290b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
36300b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36310b57cec5SDimitry Andric 
36320b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
36330b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
36340b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
36350b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
36360b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
36370b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
36380b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 6, 1);
36390b57cec5SDimitry Andric 
36400b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
36410b57cec5SDimitry Andric     return MCDisassembler::Fail;
36420b57cec5SDimitry Andric   if (op) {
36430b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
36440b57cec5SDimitry Andric     return MCDisassembler::Fail; // Writeback
36450b57cec5SDimitry Andric   }
36460b57cec5SDimitry Andric 
36470b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
36480b57cec5SDimitry Andric   case ARM::VTBL2:
36490b57cec5SDimitry Andric   case ARM::VTBX2:
36500b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
36510b57cec5SDimitry Andric       return MCDisassembler::Fail;
36520b57cec5SDimitry Andric     break;
36530b57cec5SDimitry Andric   default:
36540b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
36550b57cec5SDimitry Andric       return MCDisassembler::Fail;
36560b57cec5SDimitry Andric   }
36570b57cec5SDimitry Andric 
36580b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
36590b57cec5SDimitry Andric     return MCDisassembler::Fail;
36600b57cec5SDimitry Andric 
36610b57cec5SDimitry Andric   return S;
36620b57cec5SDimitry Andric }
36630b57cec5SDimitry Andric 
DecodeThumbAddSpecialReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)36640b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
36650b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder) {
36660b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36670b57cec5SDimitry Andric 
36680b57cec5SDimitry Andric   unsigned dst = fieldFromInstruction(Insn, 8, 3);
36690b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
36700b57cec5SDimitry Andric 
36710b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
36720b57cec5SDimitry Andric     return MCDisassembler::Fail;
36730b57cec5SDimitry Andric 
36740b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
36750b57cec5SDimitry Andric     default:
36760b57cec5SDimitry Andric       return MCDisassembler::Fail;
36770b57cec5SDimitry Andric     case ARM::tADR:
36780b57cec5SDimitry Andric       break; // tADR does not explicitly represent the PC as an operand.
36790b57cec5SDimitry Andric     case ARM::tADDrSPi:
36800b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::SP));
36810b57cec5SDimitry Andric       break;
36820b57cec5SDimitry Andric   }
36830b57cec5SDimitry Andric 
36840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
36850b57cec5SDimitry Andric   return S;
36860b57cec5SDimitry Andric }
36870b57cec5SDimitry Andric 
DecodeThumbBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)36880b57cec5SDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
36890b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
36900b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
36910b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
36920b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1)));
36930b57cec5SDimitry Andric   return MCDisassembler::Success;
36940b57cec5SDimitry Andric }
36950b57cec5SDimitry Andric 
DecodeT2BROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)36960b57cec5SDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
36970b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
36980b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
36990b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
37000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val)));
37010b57cec5SDimitry Andric   return MCDisassembler::Success;
37020b57cec5SDimitry Andric }
37030b57cec5SDimitry Andric 
DecodeThumbCmpBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)37040b57cec5SDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
37050b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
37060b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
37070b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
37080b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val << 1));
37090b57cec5SDimitry Andric   return MCDisassembler::Success;
37100b57cec5SDimitry Andric }
37110b57cec5SDimitry Andric 
DecodeThumbAddrModeRR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)37120b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
37130b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
37140b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37150b57cec5SDimitry Andric 
37160b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
37170b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 3, 3);
37180b57cec5SDimitry Andric 
37190b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
37200b57cec5SDimitry Andric     return MCDisassembler::Fail;
37210b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
37220b57cec5SDimitry Andric     return MCDisassembler::Fail;
37230b57cec5SDimitry Andric 
37240b57cec5SDimitry Andric   return S;
37250b57cec5SDimitry Andric }
37260b57cec5SDimitry Andric 
DecodeThumbAddrModeIS(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)37270b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
37280b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
37290b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37300b57cec5SDimitry Andric 
37310b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
37320b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 3, 5);
37330b57cec5SDimitry Andric 
37340b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
37350b57cec5SDimitry Andric     return MCDisassembler::Fail;
37360b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37370b57cec5SDimitry Andric 
37380b57cec5SDimitry Andric   return S;
37390b57cec5SDimitry Andric }
37400b57cec5SDimitry Andric 
DecodeThumbAddrModePC(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)37410b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
37420b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
37430b57cec5SDimitry Andric   unsigned imm = Val << 2;
37440b57cec5SDimitry Andric 
37450b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37460b57cec5SDimitry Andric   tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
37470b57cec5SDimitry Andric 
37480b57cec5SDimitry Andric   return MCDisassembler::Success;
37490b57cec5SDimitry Andric }
37500b57cec5SDimitry Andric 
DecodeThumbAddrModeSP(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)37510b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
37520b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
37530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
37540b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
37550b57cec5SDimitry Andric 
37560b57cec5SDimitry Andric   return MCDisassembler::Success;
37570b57cec5SDimitry Andric }
37580b57cec5SDimitry Andric 
DecodeT2AddrModeSOReg(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)37590b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
37600b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
37610b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37620b57cec5SDimitry Andric 
37630b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 6, 4);
37640b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 2, 4);
37650b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 2);
37660b57cec5SDimitry Andric 
37670b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
37680b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
37690b57cec5SDimitry Andric   case ARM::t2STRHs:
37700b57cec5SDimitry Andric   case ARM::t2STRBs:
37710b57cec5SDimitry Andric   case ARM::t2STRs:
37720b57cec5SDimitry Andric     if (Rn == 15)
37730b57cec5SDimitry Andric       return MCDisassembler::Fail;
37740b57cec5SDimitry Andric     break;
37750b57cec5SDimitry Andric   default:
37760b57cec5SDimitry Andric     break;
37770b57cec5SDimitry Andric   }
37780b57cec5SDimitry Andric 
37790b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37800b57cec5SDimitry Andric     return MCDisassembler::Fail;
37810b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
37820b57cec5SDimitry Andric     return MCDisassembler::Fail;
37830b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37840b57cec5SDimitry Andric 
37850b57cec5SDimitry Andric   return S;
37860b57cec5SDimitry Andric }
37870b57cec5SDimitry Andric 
DecodeT2LoadShift(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)37880b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
37890b57cec5SDimitry Andric                               uint64_t Address, const void *Decoder) {
37900b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
37930b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
37940b57cec5SDimitry Andric 
37950b57cec5SDimitry Andric   const FeatureBitset &featureBits =
37960b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
37970b57cec5SDimitry Andric 
37980b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
37990b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
38000b57cec5SDimitry Andric 
38010b57cec5SDimitry Andric   if (Rn == 15) {
38020b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
38030b57cec5SDimitry Andric     case ARM::t2LDRBs:
38040b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
38050b57cec5SDimitry Andric       break;
38060b57cec5SDimitry Andric     case ARM::t2LDRHs:
38070b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
38080b57cec5SDimitry Andric       break;
38090b57cec5SDimitry Andric     case ARM::t2LDRSHs:
38100b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
38110b57cec5SDimitry Andric       break;
38120b57cec5SDimitry Andric     case ARM::t2LDRSBs:
38130b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
38140b57cec5SDimitry Andric       break;
38150b57cec5SDimitry Andric     case ARM::t2LDRs:
38160b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
38170b57cec5SDimitry Andric       break;
38180b57cec5SDimitry Andric     case ARM::t2PLDs:
38190b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
38200b57cec5SDimitry Andric       break;
38210b57cec5SDimitry Andric     case ARM::t2PLIs:
38220b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
38230b57cec5SDimitry Andric       break;
38240b57cec5SDimitry Andric     default:
38250b57cec5SDimitry Andric       return MCDisassembler::Fail;
38260b57cec5SDimitry Andric     }
38270b57cec5SDimitry Andric 
38280b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
38290b57cec5SDimitry Andric   }
38300b57cec5SDimitry Andric 
38310b57cec5SDimitry Andric   if (Rt == 15) {
38320b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
38330b57cec5SDimitry Andric     case ARM::t2LDRSHs:
38340b57cec5SDimitry Andric       return MCDisassembler::Fail;
38350b57cec5SDimitry Andric     case ARM::t2LDRHs:
38360b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDWs);
38370b57cec5SDimitry Andric       break;
38380b57cec5SDimitry Andric     case ARM::t2LDRSBs:
38390b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIs);
38400b57cec5SDimitry Andric       break;
38410b57cec5SDimitry Andric     default:
38420b57cec5SDimitry Andric       break;
38430b57cec5SDimitry Andric     }
38440b57cec5SDimitry Andric   }
38450b57cec5SDimitry Andric 
38460b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
38470b57cec5SDimitry Andric     case ARM::t2PLDs:
38480b57cec5SDimitry Andric       break;
38490b57cec5SDimitry Andric     case ARM::t2PLIs:
38500b57cec5SDimitry Andric       if (!hasV7Ops)
38510b57cec5SDimitry Andric         return MCDisassembler::Fail;
38520b57cec5SDimitry Andric       break;
38530b57cec5SDimitry Andric     case ARM::t2PLDWs:
38540b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
38550b57cec5SDimitry Andric         return MCDisassembler::Fail;
38560b57cec5SDimitry Andric       break;
38570b57cec5SDimitry Andric     default:
38580b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
38590b57cec5SDimitry Andric         return MCDisassembler::Fail;
38600b57cec5SDimitry Andric   }
38610b57cec5SDimitry Andric 
38620b57cec5SDimitry Andric   unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
38630b57cec5SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
38640b57cec5SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
38650b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
38660b57cec5SDimitry Andric     return MCDisassembler::Fail;
38670b57cec5SDimitry Andric 
38680b57cec5SDimitry Andric   return S;
38690b57cec5SDimitry Andric }
38700b57cec5SDimitry Andric 
DecodeT2LoadImm8(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)38710b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
38720b57cec5SDimitry Andric                                 uint64_t Address, const void* Decoder) {
38730b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38740b57cec5SDimitry Andric 
38750b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
38760b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
38770b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 9, 1);
38780b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
38790b57cec5SDimitry Andric   imm |= (U << 8);
38800b57cec5SDimitry Andric   imm |= (Rn << 9);
38810b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 9, 1);
38820b57cec5SDimitry Andric 
38830b57cec5SDimitry Andric   const FeatureBitset &featureBits =
38840b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
38850b57cec5SDimitry Andric 
38860b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
38870b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
38880b57cec5SDimitry Andric 
38890b57cec5SDimitry Andric   if (Rn == 15) {
38900b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
38910b57cec5SDimitry Andric     case ARM::t2LDRi8:
38920b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
38930b57cec5SDimitry Andric       break;
38940b57cec5SDimitry Andric     case ARM::t2LDRBi8:
38950b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
38960b57cec5SDimitry Andric       break;
38970b57cec5SDimitry Andric     case ARM::t2LDRSBi8:
38980b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
38990b57cec5SDimitry Andric       break;
39000b57cec5SDimitry Andric     case ARM::t2LDRHi8:
39010b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
39020b57cec5SDimitry Andric       break;
39030b57cec5SDimitry Andric     case ARM::t2LDRSHi8:
39040b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
39050b57cec5SDimitry Andric       break;
39060b57cec5SDimitry Andric     case ARM::t2PLDi8:
39070b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
39080b57cec5SDimitry Andric       break;
39090b57cec5SDimitry Andric     case ARM::t2PLIi8:
39100b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
39110b57cec5SDimitry Andric       break;
39120b57cec5SDimitry Andric     default:
39130b57cec5SDimitry Andric       return MCDisassembler::Fail;
39140b57cec5SDimitry Andric     }
39150b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
39160b57cec5SDimitry Andric   }
39170b57cec5SDimitry Andric 
39180b57cec5SDimitry Andric   if (Rt == 15) {
39190b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
39200b57cec5SDimitry Andric     case ARM::t2LDRSHi8:
39210b57cec5SDimitry Andric       return MCDisassembler::Fail;
39220b57cec5SDimitry Andric     case ARM::t2LDRHi8:
39230b57cec5SDimitry Andric       if (!add)
39240b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLDWi8);
39250b57cec5SDimitry Andric       break;
39260b57cec5SDimitry Andric     case ARM::t2LDRSBi8:
39270b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIi8);
39280b57cec5SDimitry Andric       break;
39290b57cec5SDimitry Andric     default:
39300b57cec5SDimitry Andric       break;
39310b57cec5SDimitry Andric     }
39320b57cec5SDimitry Andric   }
39330b57cec5SDimitry Andric 
39340b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
39350b57cec5SDimitry Andric   case ARM::t2PLDi8:
39360b57cec5SDimitry Andric     break;
39370b57cec5SDimitry Andric   case ARM::t2PLIi8:
39380b57cec5SDimitry Andric     if (!hasV7Ops)
39390b57cec5SDimitry Andric       return MCDisassembler::Fail;
39400b57cec5SDimitry Andric     break;
39410b57cec5SDimitry Andric   case ARM::t2PLDWi8:
39420b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
39430b57cec5SDimitry Andric         return MCDisassembler::Fail;
39440b57cec5SDimitry Andric       break;
39450b57cec5SDimitry Andric   default:
39460b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
39470b57cec5SDimitry Andric       return MCDisassembler::Fail;
39480b57cec5SDimitry Andric   }
39490b57cec5SDimitry Andric 
39500b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
39510b57cec5SDimitry Andric     return MCDisassembler::Fail;
39520b57cec5SDimitry Andric   return S;
39530b57cec5SDimitry Andric }
39540b57cec5SDimitry Andric 
DecodeT2LoadImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)39550b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
39560b57cec5SDimitry Andric                                 uint64_t Address, const void* Decoder) {
39570b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39580b57cec5SDimitry Andric 
39590b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
39600b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
39610b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
39620b57cec5SDimitry Andric   imm |= (Rn << 13);
39630b57cec5SDimitry Andric 
39640b57cec5SDimitry Andric   const FeatureBitset &featureBits =
39650b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
39660b57cec5SDimitry Andric 
39670b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
39680b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
39690b57cec5SDimitry Andric 
39700b57cec5SDimitry Andric   if (Rn == 15) {
39710b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
39720b57cec5SDimitry Andric     case ARM::t2LDRi12:
39730b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
39740b57cec5SDimitry Andric       break;
39750b57cec5SDimitry Andric     case ARM::t2LDRHi12:
39760b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
39770b57cec5SDimitry Andric       break;
39780b57cec5SDimitry Andric     case ARM::t2LDRSHi12:
39790b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
39800b57cec5SDimitry Andric       break;
39810b57cec5SDimitry Andric     case ARM::t2LDRBi12:
39820b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
39830b57cec5SDimitry Andric       break;
39840b57cec5SDimitry Andric     case ARM::t2LDRSBi12:
39850b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
39860b57cec5SDimitry Andric       break;
39870b57cec5SDimitry Andric     case ARM::t2PLDi12:
39880b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
39890b57cec5SDimitry Andric       break;
39900b57cec5SDimitry Andric     case ARM::t2PLIi12:
39910b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
39920b57cec5SDimitry Andric       break;
39930b57cec5SDimitry Andric     default:
39940b57cec5SDimitry Andric       return MCDisassembler::Fail;
39950b57cec5SDimitry Andric     }
39960b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
39970b57cec5SDimitry Andric   }
39980b57cec5SDimitry Andric 
39990b57cec5SDimitry Andric   if (Rt == 15) {
40000b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
40010b57cec5SDimitry Andric     case ARM::t2LDRSHi12:
40020b57cec5SDimitry Andric       return MCDisassembler::Fail;
40030b57cec5SDimitry Andric     case ARM::t2LDRHi12:
40040b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDWi12);
40050b57cec5SDimitry Andric       break;
40060b57cec5SDimitry Andric     case ARM::t2LDRSBi12:
40070b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIi12);
40080b57cec5SDimitry Andric       break;
40090b57cec5SDimitry Andric     default:
40100b57cec5SDimitry Andric       break;
40110b57cec5SDimitry Andric     }
40120b57cec5SDimitry Andric   }
40130b57cec5SDimitry Andric 
40140b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
40150b57cec5SDimitry Andric   case ARM::t2PLDi12:
40160b57cec5SDimitry Andric     break;
40170b57cec5SDimitry Andric   case ARM::t2PLIi12:
40180b57cec5SDimitry Andric     if (!hasV7Ops)
40190b57cec5SDimitry Andric       return MCDisassembler::Fail;
40200b57cec5SDimitry Andric     break;
40210b57cec5SDimitry Andric   case ARM::t2PLDWi12:
40220b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
40230b57cec5SDimitry Andric         return MCDisassembler::Fail;
40240b57cec5SDimitry Andric       break;
40250b57cec5SDimitry Andric   default:
40260b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
40270b57cec5SDimitry Andric       return MCDisassembler::Fail;
40280b57cec5SDimitry Andric   }
40290b57cec5SDimitry Andric 
40300b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
40310b57cec5SDimitry Andric     return MCDisassembler::Fail;
40320b57cec5SDimitry Andric   return S;
40330b57cec5SDimitry Andric }
40340b57cec5SDimitry Andric 
DecodeT2LoadT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)40350b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
40360b57cec5SDimitry Andric                                 uint64_t Address, const void* Decoder) {
40370b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40380b57cec5SDimitry Andric 
40390b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
40400b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
40410b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
40420b57cec5SDimitry Andric   imm |= (Rn << 9);
40430b57cec5SDimitry Andric 
40440b57cec5SDimitry Andric   if (Rn == 15) {
40450b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
40460b57cec5SDimitry Andric     case ARM::t2LDRT:
40470b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
40480b57cec5SDimitry Andric       break;
40490b57cec5SDimitry Andric     case ARM::t2LDRBT:
40500b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
40510b57cec5SDimitry Andric       break;
40520b57cec5SDimitry Andric     case ARM::t2LDRHT:
40530b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
40540b57cec5SDimitry Andric       break;
40550b57cec5SDimitry Andric     case ARM::t2LDRSBT:
40560b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
40570b57cec5SDimitry Andric       break;
40580b57cec5SDimitry Andric     case ARM::t2LDRSHT:
40590b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
40600b57cec5SDimitry Andric       break;
40610b57cec5SDimitry Andric     default:
40620b57cec5SDimitry Andric       return MCDisassembler::Fail;
40630b57cec5SDimitry Andric     }
40640b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
40650b57cec5SDimitry Andric   }
40660b57cec5SDimitry Andric 
40670b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
40680b57cec5SDimitry Andric     return MCDisassembler::Fail;
40690b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
40700b57cec5SDimitry Andric     return MCDisassembler::Fail;
40710b57cec5SDimitry Andric   return S;
40720b57cec5SDimitry Andric }
40730b57cec5SDimitry Andric 
DecodeT2LoadLabel(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)40740b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
40750b57cec5SDimitry Andric                                 uint64_t Address, const void* Decoder) {
40760b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40770b57cec5SDimitry Andric 
40780b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
40790b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
40800b57cec5SDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 12);
40810b57cec5SDimitry Andric 
40820b57cec5SDimitry Andric   const FeatureBitset &featureBits =
40830b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
40840b57cec5SDimitry Andric 
40850b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
40860b57cec5SDimitry Andric 
40870b57cec5SDimitry Andric   if (Rt == 15) {
40880b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
40890b57cec5SDimitry Andric       case ARM::t2LDRBpci:
40900b57cec5SDimitry Andric       case ARM::t2LDRHpci:
40910b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLDpci);
40920b57cec5SDimitry Andric         break;
40930b57cec5SDimitry Andric       case ARM::t2LDRSBpci:
40940b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
40950b57cec5SDimitry Andric         break;
40960b57cec5SDimitry Andric       case ARM::t2LDRSHpci:
40970b57cec5SDimitry Andric         return MCDisassembler::Fail;
40980b57cec5SDimitry Andric       default:
40990b57cec5SDimitry Andric         break;
41000b57cec5SDimitry Andric     }
41010b57cec5SDimitry Andric   }
41020b57cec5SDimitry Andric 
41030b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
41040b57cec5SDimitry Andric   case ARM::t2PLDpci:
41050b57cec5SDimitry Andric     break;
41060b57cec5SDimitry Andric   case ARM::t2PLIpci:
41070b57cec5SDimitry Andric     if (!hasV7Ops)
41080b57cec5SDimitry Andric       return MCDisassembler::Fail;
41090b57cec5SDimitry Andric     break;
41100b57cec5SDimitry Andric   default:
41110b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
41120b57cec5SDimitry Andric       return MCDisassembler::Fail;
41130b57cec5SDimitry Andric   }
41140b57cec5SDimitry Andric 
41150b57cec5SDimitry Andric   if (!U) {
41160b57cec5SDimitry Andric     // Special case for #-0.
41170b57cec5SDimitry Andric     if (imm == 0)
41180b57cec5SDimitry Andric       imm = INT32_MIN;
41190b57cec5SDimitry Andric     else
41200b57cec5SDimitry Andric       imm = -imm;
41210b57cec5SDimitry Andric   }
41220b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
41230b57cec5SDimitry Andric 
41240b57cec5SDimitry Andric   return S;
41250b57cec5SDimitry Andric }
41260b57cec5SDimitry Andric 
DecodeT2Imm8S4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)41270b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
41280b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
41290b57cec5SDimitry Andric   if (Val == 0)
41300b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
41310b57cec5SDimitry Andric   else {
41320b57cec5SDimitry Andric     int imm = Val & 0xFF;
41330b57cec5SDimitry Andric 
41340b57cec5SDimitry Andric     if (!(Val & 0x100)) imm *= -1;
41350b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
41360b57cec5SDimitry Andric   }
41370b57cec5SDimitry Andric 
41380b57cec5SDimitry Andric   return MCDisassembler::Success;
41390b57cec5SDimitry Andric }
41400b57cec5SDimitry Andric 
DecodeT2Imm7S4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)41410b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
41420b57cec5SDimitry Andric                                    const void *Decoder) {
41430b57cec5SDimitry Andric   if (Val == 0)
41440b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
41450b57cec5SDimitry Andric   else {
41460b57cec5SDimitry Andric     int imm = Val & 0x7F;
41470b57cec5SDimitry Andric 
41480b57cec5SDimitry Andric     if (!(Val & 0x80))
41490b57cec5SDimitry Andric       imm *= -1;
41500b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
41510b57cec5SDimitry Andric   }
41520b57cec5SDimitry Andric 
41530b57cec5SDimitry Andric   return MCDisassembler::Success;
41540b57cec5SDimitry Andric }
41550b57cec5SDimitry Andric 
DecodeT2AddrModeImm8s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)41560b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
41570b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
41580b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
41590b57cec5SDimitry Andric 
41600b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
41610b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
41620b57cec5SDimitry Andric 
41630b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
41640b57cec5SDimitry Andric     return MCDisassembler::Fail;
41650b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
41660b57cec5SDimitry Andric     return MCDisassembler::Fail;
41670b57cec5SDimitry Andric 
41680b57cec5SDimitry Andric   return S;
41690b57cec5SDimitry Andric }
41700b57cec5SDimitry Andric 
DecodeT2AddrModeImm7s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)41710b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
41720b57cec5SDimitry Andric                                            uint64_t Address,
41730b57cec5SDimitry Andric                                            const void *Decoder) {
41740b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
41750b57cec5SDimitry Andric 
41760b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
41770b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
41780b57cec5SDimitry Andric 
41790b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
41800b57cec5SDimitry Andric     return MCDisassembler::Fail;
41810b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7S4(Inst, imm, Address, Decoder)))
41820b57cec5SDimitry Andric     return MCDisassembler::Fail;
41830b57cec5SDimitry Andric 
41840b57cec5SDimitry Andric   return S;
41850b57cec5SDimitry Andric }
41860b57cec5SDimitry Andric 
DecodeT2AddrModeImm0_1020s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)41870b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
41880b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
41890b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
41900b57cec5SDimitry Andric 
41910b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
41920b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
41930b57cec5SDimitry Andric 
41940b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
41950b57cec5SDimitry Andric     return MCDisassembler::Fail;
41960b57cec5SDimitry Andric 
41970b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
41980b57cec5SDimitry Andric 
41990b57cec5SDimitry Andric   return S;
42000b57cec5SDimitry Andric }
42010b57cec5SDimitry Andric 
DecodeT2Imm8(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)42020b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
42030b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
42040b57cec5SDimitry Andric   int imm = Val & 0xFF;
42050b57cec5SDimitry Andric   if (Val == 0)
42060b57cec5SDimitry Andric     imm = INT32_MIN;
42070b57cec5SDimitry Andric   else if (!(Val & 0x100))
42080b57cec5SDimitry Andric     imm *= -1;
42090b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
42100b57cec5SDimitry Andric 
42110b57cec5SDimitry Andric   return MCDisassembler::Success;
42120b57cec5SDimitry Andric }
42130b57cec5SDimitry Andric 
42140b57cec5SDimitry Andric template<int shift>
DecodeT2Imm7(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)42150b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val,
42160b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
42170b57cec5SDimitry Andric   int imm = Val & 0x7F;
42180b57cec5SDimitry Andric   if (Val == 0)
42190b57cec5SDimitry Andric     imm = INT32_MIN;
42200b57cec5SDimitry Andric   else if (!(Val & 0x80))
42210b57cec5SDimitry Andric     imm *= -1;
42220b57cec5SDimitry Andric   if (imm != INT32_MIN)
42230b57cec5SDimitry Andric     imm *= (1U << shift);
42240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
42250b57cec5SDimitry Andric 
42260b57cec5SDimitry Andric   return MCDisassembler::Success;
42270b57cec5SDimitry Andric }
42280b57cec5SDimitry Andric 
DecodeT2AddrModeImm8(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)42290b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
42300b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
42310b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42320b57cec5SDimitry Andric 
42330b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
42340b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
42350b57cec5SDimitry Andric 
42360b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
42370b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
42380b57cec5SDimitry Andric   case ARM::t2STRT:
42390b57cec5SDimitry Andric   case ARM::t2STRBT:
42400b57cec5SDimitry Andric   case ARM::t2STRHT:
42410b57cec5SDimitry Andric   case ARM::t2STRi8:
42420b57cec5SDimitry Andric   case ARM::t2STRHi8:
42430b57cec5SDimitry Andric   case ARM::t2STRBi8:
42440b57cec5SDimitry Andric     if (Rn == 15)
42450b57cec5SDimitry Andric       return MCDisassembler::Fail;
42460b57cec5SDimitry Andric     break;
42470b57cec5SDimitry Andric   default:
42480b57cec5SDimitry Andric     break;
42490b57cec5SDimitry Andric   }
42500b57cec5SDimitry Andric 
42510b57cec5SDimitry Andric   // Some instructions always use an additive offset.
42520b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
42530b57cec5SDimitry Andric     case ARM::t2LDRT:
42540b57cec5SDimitry Andric     case ARM::t2LDRBT:
42550b57cec5SDimitry Andric     case ARM::t2LDRHT:
42560b57cec5SDimitry Andric     case ARM::t2LDRSBT:
42570b57cec5SDimitry Andric     case ARM::t2LDRSHT:
42580b57cec5SDimitry Andric     case ARM::t2STRT:
42590b57cec5SDimitry Andric     case ARM::t2STRBT:
42600b57cec5SDimitry Andric     case ARM::t2STRHT:
42610b57cec5SDimitry Andric       imm |= 0x100;
42620b57cec5SDimitry Andric       break;
42630b57cec5SDimitry Andric     default:
42640b57cec5SDimitry Andric       break;
42650b57cec5SDimitry Andric   }
42660b57cec5SDimitry Andric 
42670b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
42680b57cec5SDimitry Andric     return MCDisassembler::Fail;
42690b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
42700b57cec5SDimitry Andric     return MCDisassembler::Fail;
42710b57cec5SDimitry Andric 
42720b57cec5SDimitry Andric   return S;
42730b57cec5SDimitry Andric }
42740b57cec5SDimitry Andric 
42750b57cec5SDimitry Andric template<int shift>
DecodeTAddrModeImm7(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)42760b57cec5SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
42770b57cec5SDimitry Andric                                          uint64_t Address,
42780b57cec5SDimitry Andric                                          const void *Decoder) {
42790b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42800b57cec5SDimitry Andric 
42810b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 3);
42820b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
42830b57cec5SDimitry Andric 
42840b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
42850b57cec5SDimitry Andric     return MCDisassembler::Fail;
42860b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
42870b57cec5SDimitry Andric     return MCDisassembler::Fail;
42880b57cec5SDimitry Andric 
42890b57cec5SDimitry Andric   return S;
42900b57cec5SDimitry Andric }
42910b57cec5SDimitry Andric 
42920b57cec5SDimitry Andric template<int shift, int WriteBack>
DecodeT2AddrModeImm7(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)42930b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
42940b57cec5SDimitry Andric                                          uint64_t Address,
42950b57cec5SDimitry Andric                                          const void *Decoder) {
42960b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42970b57cec5SDimitry Andric 
42980b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
42990b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
43000b57cec5SDimitry Andric   if (WriteBack) {
43010b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
43020b57cec5SDimitry Andric       return MCDisassembler::Fail;
43030b57cec5SDimitry Andric   } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
43040b57cec5SDimitry Andric     return MCDisassembler::Fail;
43050b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
43060b57cec5SDimitry Andric     return MCDisassembler::Fail;
43070b57cec5SDimitry Andric 
43080b57cec5SDimitry Andric   return S;
43090b57cec5SDimitry Andric }
43100b57cec5SDimitry Andric 
DecodeT2LdStPre(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)43110b57cec5SDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
43120b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
43130b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43140b57cec5SDimitry Andric 
43150b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43160b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
43170b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
43180b57cec5SDimitry Andric   addr |= fieldFromInstruction(Insn, 9, 1) << 8;
43190b57cec5SDimitry Andric   addr |= Rn << 9;
43200b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 20, 1);
43210b57cec5SDimitry Andric 
43220b57cec5SDimitry Andric   if (Rn == 15) {
43230b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
43240b57cec5SDimitry Andric     case ARM::t2LDR_PRE:
43250b57cec5SDimitry Andric     case ARM::t2LDR_POST:
43260b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
43270b57cec5SDimitry Andric       break;
43280b57cec5SDimitry Andric     case ARM::t2LDRB_PRE:
43290b57cec5SDimitry Andric     case ARM::t2LDRB_POST:
43300b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
43310b57cec5SDimitry Andric       break;
43320b57cec5SDimitry Andric     case ARM::t2LDRH_PRE:
43330b57cec5SDimitry Andric     case ARM::t2LDRH_POST:
43340b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
43350b57cec5SDimitry Andric       break;
43360b57cec5SDimitry Andric     case ARM::t2LDRSB_PRE:
43370b57cec5SDimitry Andric     case ARM::t2LDRSB_POST:
43380b57cec5SDimitry Andric       if (Rt == 15)
43390b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
43400b57cec5SDimitry Andric       else
43410b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2LDRSBpci);
43420b57cec5SDimitry Andric       break;
43430b57cec5SDimitry Andric     case ARM::t2LDRSH_PRE:
43440b57cec5SDimitry Andric     case ARM::t2LDRSH_POST:
43450b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
43460b57cec5SDimitry Andric       break;
43470b57cec5SDimitry Andric     default:
43480b57cec5SDimitry Andric       return MCDisassembler::Fail;
43490b57cec5SDimitry Andric     }
43500b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
43510b57cec5SDimitry Andric   }
43520b57cec5SDimitry Andric 
43530b57cec5SDimitry Andric   if (!load) {
43540b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
43550b57cec5SDimitry Andric       return MCDisassembler::Fail;
43560b57cec5SDimitry Andric   }
43570b57cec5SDimitry Andric 
43580b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43590b57cec5SDimitry Andric     return MCDisassembler::Fail;
43600b57cec5SDimitry Andric 
43610b57cec5SDimitry Andric   if (load) {
43620b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
43630b57cec5SDimitry Andric       return MCDisassembler::Fail;
43640b57cec5SDimitry Andric   }
43650b57cec5SDimitry Andric 
43660b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
43670b57cec5SDimitry Andric     return MCDisassembler::Fail;
43680b57cec5SDimitry Andric 
43690b57cec5SDimitry Andric   return S;
43700b57cec5SDimitry Andric }
43710b57cec5SDimitry Andric 
DecodeT2AddrModeImm12(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)43720b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
43730b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
43740b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43750b57cec5SDimitry Andric 
43760b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
43770b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
43780b57cec5SDimitry Andric 
43790b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
43800b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
43810b57cec5SDimitry Andric   case ARM::t2STRi12:
43820b57cec5SDimitry Andric   case ARM::t2STRBi12:
43830b57cec5SDimitry Andric   case ARM::t2STRHi12:
43840b57cec5SDimitry Andric     if (Rn == 15)
43850b57cec5SDimitry Andric       return MCDisassembler::Fail;
43860b57cec5SDimitry Andric     break;
43870b57cec5SDimitry Andric   default:
43880b57cec5SDimitry Andric     break;
43890b57cec5SDimitry Andric   }
43900b57cec5SDimitry Andric 
43910b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
43920b57cec5SDimitry Andric     return MCDisassembler::Fail;
43930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
43940b57cec5SDimitry Andric 
43950b57cec5SDimitry Andric   return S;
43960b57cec5SDimitry Andric }
43970b57cec5SDimitry Andric 
DecodeThumbAddSPImm(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)43980b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
43990b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder) {
44000b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 7);
44010b57cec5SDimitry Andric 
44020b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
44030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
44040b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44050b57cec5SDimitry Andric 
44060b57cec5SDimitry Andric   return MCDisassembler::Success;
44070b57cec5SDimitry Andric }
44080b57cec5SDimitry Andric 
DecodeThumbAddSPReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)44090b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
44100b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder) {
44110b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44120b57cec5SDimitry Andric 
44130b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::tADDrSP) {
44140b57cec5SDimitry Andric     unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
44150b57cec5SDimitry Andric     Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
44160b57cec5SDimitry Andric 
44170b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
44180b57cec5SDimitry Andric     return MCDisassembler::Fail;
44190b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
44200b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
44210b57cec5SDimitry Andric     return MCDisassembler::Fail;
44220b57cec5SDimitry Andric   } else if (Inst.getOpcode() == ARM::tADDspr) {
44230b57cec5SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 3, 4);
44240b57cec5SDimitry Andric 
44250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
44260b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
44270b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
44280b57cec5SDimitry Andric     return MCDisassembler::Fail;
44290b57cec5SDimitry Andric   }
44300b57cec5SDimitry Andric 
44310b57cec5SDimitry Andric   return S;
44320b57cec5SDimitry Andric }
44330b57cec5SDimitry Andric 
DecodeThumbCPS(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)44340b57cec5SDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
44350b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
44360b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
44370b57cec5SDimitry Andric   unsigned flags = fieldFromInstruction(Insn, 0, 3);
44380b57cec5SDimitry Andric 
44390b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imod));
44400b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(flags));
44410b57cec5SDimitry Andric 
44420b57cec5SDimitry Andric   return MCDisassembler::Success;
44430b57cec5SDimitry Andric }
44440b57cec5SDimitry Andric 
DecodePostIdxReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)44450b57cec5SDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
44460b57cec5SDimitry Andric                              uint64_t Address, const void *Decoder) {
44470b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44480b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
44490b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 4, 1);
44500b57cec5SDimitry Andric 
44510b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
44520b57cec5SDimitry Andric     return MCDisassembler::Fail;
44530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(add));
44540b57cec5SDimitry Andric 
44550b57cec5SDimitry Andric   return S;
44560b57cec5SDimitry Andric }
44570b57cec5SDimitry Andric 
DecodeMveAddrModeRQ(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)44580b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
44590b57cec5SDimitry Andric                              uint64_t Address, const void *Decoder) {
44600b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44610b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 3, 4);
44620b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 0, 3);
44630b57cec5SDimitry Andric 
44640b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
44650b57cec5SDimitry Andric     return MCDisassembler::Fail;
44660b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
44670b57cec5SDimitry Andric     return MCDisassembler::Fail;
44680b57cec5SDimitry Andric 
44690b57cec5SDimitry Andric   return S;
44700b57cec5SDimitry Andric }
44710b57cec5SDimitry Andric 
44720b57cec5SDimitry Andric template<int shift>
DecodeMveAddrModeQ(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)44730b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
44740b57cec5SDimitry Andric                              uint64_t Address, const void *Decoder) {
44750b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44760b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 8, 3);
44770b57cec5SDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 7);
44780b57cec5SDimitry Andric 
44790b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
44800b57cec5SDimitry Andric     return MCDisassembler::Fail;
44810b57cec5SDimitry Andric 
44820b57cec5SDimitry Andric   if(!fieldFromInstruction(Insn, 7, 1)) {
44830b57cec5SDimitry Andric     if (imm == 0)
44840b57cec5SDimitry Andric       imm = INT32_MIN;                 // indicate -0
44850b57cec5SDimitry Andric     else
44860b57cec5SDimitry Andric       imm *= -1;
44870b57cec5SDimitry Andric   }
44880b57cec5SDimitry Andric   if (imm != INT32_MIN)
44890b57cec5SDimitry Andric     imm *= (1U << shift);
44900b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44910b57cec5SDimitry Andric 
44920b57cec5SDimitry Andric   return S;
44930b57cec5SDimitry Andric }
44940b57cec5SDimitry Andric 
DecodeThumbBLXOffset(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)44950b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
44960b57cec5SDimitry Andric                                  uint64_t Address, const void *Decoder) {
44970b57cec5SDimitry Andric   // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
44980b57cec5SDimitry Andric   // Note only one trailing zero not two.  Also the J1 and J2 values are from
44990b57cec5SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
45000b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
45010b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
45020b57cec5SDimitry Andric   // and build the imm32 with two trailing zeros as documented:
45030b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
45040b57cec5SDimitry Andric   unsigned S = (Val >> 23) & 1;
45050b57cec5SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
45060b57cec5SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
45070b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
45080b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
45090b57cec5SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
45100b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
45110b57cec5SDimitry Andric 
45120b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address,
45130b57cec5SDimitry Andric                                 (Address & ~2u) + imm32 + 4,
45140b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
45150b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
45160b57cec5SDimitry Andric   return MCDisassembler::Success;
45170b57cec5SDimitry Andric }
45180b57cec5SDimitry Andric 
DecodeCoprocessor(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)45190b57cec5SDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
45200b57cec5SDimitry Andric                               uint64_t Address, const void *Decoder) {
45210b57cec5SDimitry Andric   if (Val == 0xA || Val == 0xB)
45220b57cec5SDimitry Andric     return MCDisassembler::Fail;
45230b57cec5SDimitry Andric 
45240b57cec5SDimitry Andric   const FeatureBitset &featureBits =
45250b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
45260b57cec5SDimitry Andric 
45270b57cec5SDimitry Andric   if (!isValidCoprocessorNumber(Val, featureBits))
45280b57cec5SDimitry Andric     return MCDisassembler::Fail;
45290b57cec5SDimitry Andric 
45300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
45310b57cec5SDimitry Andric   return MCDisassembler::Success;
45320b57cec5SDimitry Andric }
45330b57cec5SDimitry Andric 
45340b57cec5SDimitry Andric static DecodeStatus
DecodeThumbTableBranch(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)45350b57cec5SDimitry Andric DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
45360b57cec5SDimitry Andric                        uint64_t Address, const void *Decoder) {
4537af732203SDimitry Andric   const FeatureBitset &FeatureBits =
4538af732203SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
45390b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45400b57cec5SDimitry Andric 
45410b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
45420b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
45430b57cec5SDimitry Andric 
4544af732203SDimitry Andric   if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
45450b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
45460b57cec5SDimitry Andric     return MCDisassembler::Fail;
45470b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
45480b57cec5SDimitry Andric     return MCDisassembler::Fail;
45490b57cec5SDimitry Andric   return S;
45500b57cec5SDimitry Andric }
45510b57cec5SDimitry Andric 
45520b57cec5SDimitry Andric static DecodeStatus
DecodeThumb2BCCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)45530b57cec5SDimitry Andric DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
45540b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
45550b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45560b57cec5SDimitry Andric 
45570b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 22, 4);
45580b57cec5SDimitry Andric   if (pred == 0xE || pred == 0xF) {
45590b57cec5SDimitry Andric     unsigned opc = fieldFromInstruction(Insn, 4, 28);
45600b57cec5SDimitry Andric     switch (opc) {
45610b57cec5SDimitry Andric       default:
45620b57cec5SDimitry Andric         return MCDisassembler::Fail;
45630b57cec5SDimitry Andric       case 0xf3bf8f4:
45640b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2DSB);
45650b57cec5SDimitry Andric         break;
45660b57cec5SDimitry Andric       case 0xf3bf8f5:
45670b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2DMB);
45680b57cec5SDimitry Andric         break;
45690b57cec5SDimitry Andric       case 0xf3bf8f6:
45700b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2ISB);
45710b57cec5SDimitry Andric         break;
45720b57cec5SDimitry Andric     }
45730b57cec5SDimitry Andric 
45740b57cec5SDimitry Andric     unsigned imm = fieldFromInstruction(Insn, 0, 4);
45750b57cec5SDimitry Andric     return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
45760b57cec5SDimitry Andric   }
45770b57cec5SDimitry Andric 
45780b57cec5SDimitry Andric   unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
45790b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
45800b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
45810b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
45820b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
45830b57cec5SDimitry Andric 
45840b57cec5SDimitry Andric   if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
45850b57cec5SDimitry Andric     return MCDisassembler::Fail;
45860b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
45870b57cec5SDimitry Andric     return MCDisassembler::Fail;
45880b57cec5SDimitry Andric 
45890b57cec5SDimitry Andric   return S;
45900b57cec5SDimitry Andric }
45910b57cec5SDimitry Andric 
45920b57cec5SDimitry Andric // Decode a shifted immediate operand.  These basically consist
45930b57cec5SDimitry Andric // of an 8-bit value, and a 4-bit directive that specifies either
45940b57cec5SDimitry Andric // a splat operation or a rotation.
DecodeT2SOImm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)45950b57cec5SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
45960b57cec5SDimitry Andric                           uint64_t Address, const void *Decoder) {
45970b57cec5SDimitry Andric   unsigned ctrl = fieldFromInstruction(Val, 10, 2);
45980b57cec5SDimitry Andric   if (ctrl == 0) {
45990b57cec5SDimitry Andric     unsigned byte = fieldFromInstruction(Val, 8, 2);
46000b57cec5SDimitry Andric     unsigned imm = fieldFromInstruction(Val, 0, 8);
46010b57cec5SDimitry Andric     switch (byte) {
46020b57cec5SDimitry Andric       case 0:
46030b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(imm));
46040b57cec5SDimitry Andric         break;
46050b57cec5SDimitry Andric       case 1:
46060b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 16) | imm));
46070b57cec5SDimitry Andric         break;
46080b57cec5SDimitry Andric       case 2:
46090b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8)));
46100b57cec5SDimitry Andric         break;
46110b57cec5SDimitry Andric       case 3:
46120b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) |
46130b57cec5SDimitry Andric                                              (imm << 8)  |  imm));
46140b57cec5SDimitry Andric         break;
46150b57cec5SDimitry Andric     }
46160b57cec5SDimitry Andric   } else {
46170b57cec5SDimitry Andric     unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
46180b57cec5SDimitry Andric     unsigned rot = fieldFromInstruction(Val, 7, 5);
46190b57cec5SDimitry Andric     unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
46200b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
46210b57cec5SDimitry Andric   }
46220b57cec5SDimitry Andric 
46230b57cec5SDimitry Andric   return MCDisassembler::Success;
46240b57cec5SDimitry Andric }
46250b57cec5SDimitry Andric 
46260b57cec5SDimitry Andric static DecodeStatus
DecodeThumbBCCTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)46270b57cec5SDimitry Andric DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
46280b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
46290b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
46300b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
46310b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1)));
46320b57cec5SDimitry Andric   return MCDisassembler::Success;
46330b57cec5SDimitry Andric }
46340b57cec5SDimitry Andric 
DecodeThumbBLTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)46350b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
46360b57cec5SDimitry Andric                                                uint64_t Address,
46370b57cec5SDimitry Andric                                                const void *Decoder) {
46380b57cec5SDimitry Andric   // Val is passed in as S:J1:J2:imm10:imm11
46390b57cec5SDimitry Andric   // Note no trailing zero after imm11.  Also the J1 and J2 values are from
46400b57cec5SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
46410b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
46420b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
46430b57cec5SDimitry Andric   // and build the imm32 with one trailing zero as documented:
46440b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
46450b57cec5SDimitry Andric   unsigned S = (Val >> 23) & 1;
46460b57cec5SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
46470b57cec5SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
46480b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
46490b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
46500b57cec5SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
46510b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
46520b57cec5SDimitry Andric 
46530b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
46540b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
46550b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
46560b57cec5SDimitry Andric   return MCDisassembler::Success;
46570b57cec5SDimitry Andric }
46580b57cec5SDimitry Andric 
DecodeMemBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)46590b57cec5SDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
46600b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
46610b57cec5SDimitry Andric   if (Val & ~0xf)
46620b57cec5SDimitry Andric     return MCDisassembler::Fail;
46630b57cec5SDimitry Andric 
46640b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
46650b57cec5SDimitry Andric   return MCDisassembler::Success;
46660b57cec5SDimitry Andric }
46670b57cec5SDimitry Andric 
DecodeInstSyncBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)46680b57cec5SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
46690b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
46700b57cec5SDimitry Andric   if (Val & ~0xf)
46710b57cec5SDimitry Andric     return MCDisassembler::Fail;
46720b57cec5SDimitry Andric 
46730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
46740b57cec5SDimitry Andric   return MCDisassembler::Success;
46750b57cec5SDimitry Andric }
46760b57cec5SDimitry Andric 
DecodeMSRMask(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)46770b57cec5SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
46780b57cec5SDimitry Andric                           uint64_t Address, const void *Decoder) {
46790b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
46800b57cec5SDimitry Andric   const FeatureBitset &FeatureBits =
46810b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
46820b57cec5SDimitry Andric 
46830b57cec5SDimitry Andric   if (FeatureBits[ARM::FeatureMClass]) {
46840b57cec5SDimitry Andric     unsigned ValLow = Val & 0xff;
46850b57cec5SDimitry Andric 
46860b57cec5SDimitry Andric     // Validate the SYSm value first.
46870b57cec5SDimitry Andric     switch (ValLow) {
46880b57cec5SDimitry Andric     case  0: // apsr
46890b57cec5SDimitry Andric     case  1: // iapsr
46900b57cec5SDimitry Andric     case  2: // eapsr
46910b57cec5SDimitry Andric     case  3: // xpsr
46920b57cec5SDimitry Andric     case  5: // ipsr
46930b57cec5SDimitry Andric     case  6: // epsr
46940b57cec5SDimitry Andric     case  7: // iepsr
46950b57cec5SDimitry Andric     case  8: // msp
46960b57cec5SDimitry Andric     case  9: // psp
46970b57cec5SDimitry Andric     case 16: // primask
46980b57cec5SDimitry Andric     case 20: // control
46990b57cec5SDimitry Andric       break;
47000b57cec5SDimitry Andric     case 17: // basepri
47010b57cec5SDimitry Andric     case 18: // basepri_max
47020b57cec5SDimitry Andric     case 19: // faultmask
47030b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops]))
47040b57cec5SDimitry Andric         // Values basepri, basepri_max and faultmask are only valid for v7m.
47050b57cec5SDimitry Andric         return MCDisassembler::Fail;
47060b57cec5SDimitry Andric       break;
47070b57cec5SDimitry Andric     case 0x8a: // msplim_ns
47080b57cec5SDimitry Andric     case 0x8b: // psplim_ns
47090b57cec5SDimitry Andric     case 0x91: // basepri_ns
47100b57cec5SDimitry Andric     case 0x93: // faultmask_ns
47110b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV8MMainlineOps]))
47120b57cec5SDimitry Andric         return MCDisassembler::Fail;
47130b57cec5SDimitry Andric       LLVM_FALLTHROUGH;
47140b57cec5SDimitry Andric     case 10:   // msplim
47150b57cec5SDimitry Andric     case 11:   // psplim
47160b57cec5SDimitry Andric     case 0x88: // msp_ns
47170b57cec5SDimitry Andric     case 0x89: // psp_ns
47180b57cec5SDimitry Andric     case 0x90: // primask_ns
47190b57cec5SDimitry Andric     case 0x94: // control_ns
47200b57cec5SDimitry Andric     case 0x98: // sp_ns
47210b57cec5SDimitry Andric       if (!(FeatureBits[ARM::Feature8MSecExt]))
47220b57cec5SDimitry Andric         return MCDisassembler::Fail;
47230b57cec5SDimitry Andric       break;
47240b57cec5SDimitry Andric     default:
47250b57cec5SDimitry Andric       // Architecturally defined as unpredictable
47260b57cec5SDimitry Andric       S = MCDisassembler::SoftFail;
47270b57cec5SDimitry Andric       break;
47280b57cec5SDimitry Andric     }
47290b57cec5SDimitry Andric 
47300b57cec5SDimitry Andric     if (Inst.getOpcode() == ARM::t2MSR_M) {
47310b57cec5SDimitry Andric       unsigned Mask = fieldFromInstruction(Val, 10, 2);
47320b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops])) {
47330b57cec5SDimitry Andric         // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
47340b57cec5SDimitry Andric         // unpredictable.
47350b57cec5SDimitry Andric         if (Mask != 2)
47360b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
47370b57cec5SDimitry Andric       }
47380b57cec5SDimitry Andric       else {
47390b57cec5SDimitry Andric         // The ARMv7-M architecture stores an additional 2-bit mask value in
47400b57cec5SDimitry Andric         // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
47410b57cec5SDimitry Andric         // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
47420b57cec5SDimitry Andric         // the NZCVQ bits should be moved by the instruction. Bit mask{0}
47430b57cec5SDimitry Andric         // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
47440b57cec5SDimitry Andric         // only if the processor includes the DSP extension.
47450b57cec5SDimitry Andric         if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
47460b57cec5SDimitry Andric             (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1)))
47470b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
47480b57cec5SDimitry Andric       }
47490b57cec5SDimitry Andric     }
47500b57cec5SDimitry Andric   } else {
47510b57cec5SDimitry Andric     // A/R class
47520b57cec5SDimitry Andric     if (Val == 0)
47530b57cec5SDimitry Andric       return MCDisassembler::Fail;
47540b57cec5SDimitry Andric   }
47550b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
47560b57cec5SDimitry Andric   return S;
47570b57cec5SDimitry Andric }
47580b57cec5SDimitry Andric 
DecodeBankedReg(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)47590b57cec5SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
47600b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
47610b57cec5SDimitry Andric   unsigned R = fieldFromInstruction(Val, 5, 1);
47620b57cec5SDimitry Andric   unsigned SysM = fieldFromInstruction(Val, 0, 5);
47630b57cec5SDimitry Andric 
47640b57cec5SDimitry Andric   // The table of encodings for these banked registers comes from B9.2.3 of the
47650b57cec5SDimitry Andric   // ARM ARM. There are patterns, but nothing regular enough to make this logic
47660b57cec5SDimitry Andric   // neater. So by fiat, these values are UNPREDICTABLE:
47670b57cec5SDimitry Andric   if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM))
47680b57cec5SDimitry Andric     return MCDisassembler::Fail;
47690b57cec5SDimitry Andric 
47700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
47710b57cec5SDimitry Andric   return MCDisassembler::Success;
47720b57cec5SDimitry Andric }
47730b57cec5SDimitry Andric 
DecodeDoubleRegLoad(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)47740b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
47750b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
47760b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47770b57cec5SDimitry Andric 
47780b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
47790b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
47800b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
47810b57cec5SDimitry Andric 
47820b57cec5SDimitry Andric   if (Rn == 0xF)
47830b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
47840b57cec5SDimitry Andric 
47850b57cec5SDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
47860b57cec5SDimitry Andric     return MCDisassembler::Fail;
47870b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
47880b57cec5SDimitry Andric     return MCDisassembler::Fail;
47890b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
47900b57cec5SDimitry Andric     return MCDisassembler::Fail;
47910b57cec5SDimitry Andric 
47920b57cec5SDimitry Andric   return S;
47930b57cec5SDimitry Andric }
47940b57cec5SDimitry Andric 
DecodeDoubleRegStore(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)47950b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
47960b57cec5SDimitry Andric                                          uint64_t Address,
47970b57cec5SDimitry Andric                                          const void *Decoder) {
47980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47990b57cec5SDimitry Andric 
48000b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
48010b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
48020b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48030b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
48040b57cec5SDimitry Andric 
48050b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
48060b57cec5SDimitry Andric     return MCDisassembler::Fail;
48070b57cec5SDimitry Andric 
48080b57cec5SDimitry Andric   if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
48090b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
48100b57cec5SDimitry Andric 
48110b57cec5SDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
48120b57cec5SDimitry Andric     return MCDisassembler::Fail;
48130b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48140b57cec5SDimitry Andric     return MCDisassembler::Fail;
48150b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
48160b57cec5SDimitry Andric     return MCDisassembler::Fail;
48170b57cec5SDimitry Andric 
48180b57cec5SDimitry Andric   return S;
48190b57cec5SDimitry Andric }
48200b57cec5SDimitry Andric 
DecodeLDRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)48210b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
48220b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
48230b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48240b57cec5SDimitry Andric 
48250b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48260b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
48270b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
48280b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
48290b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
48300b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
48310b57cec5SDimitry Andric 
48320b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
48330b57cec5SDimitry Andric 
48340b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
48350b57cec5SDimitry Andric     return MCDisassembler::Fail;
48360b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48370b57cec5SDimitry Andric     return MCDisassembler::Fail;
48380b57cec5SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
48390b57cec5SDimitry Andric     return MCDisassembler::Fail;
48400b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
48410b57cec5SDimitry Andric     return MCDisassembler::Fail;
48420b57cec5SDimitry Andric 
48430b57cec5SDimitry Andric   return S;
48440b57cec5SDimitry Andric }
48450b57cec5SDimitry Andric 
DecodeLDRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)48460b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
48470b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
48480b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48490b57cec5SDimitry Andric 
48500b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48510b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
48520b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
48530b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
48540b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
48550b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
48560b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
48570b57cec5SDimitry Andric 
48580b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
48590b57cec5SDimitry Andric   if (Rm == 0xF) S = MCDisassembler::SoftFail;
48600b57cec5SDimitry Andric 
48610b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
48620b57cec5SDimitry Andric     return MCDisassembler::Fail;
48630b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48640b57cec5SDimitry Andric     return MCDisassembler::Fail;
48650b57cec5SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
48660b57cec5SDimitry Andric     return MCDisassembler::Fail;
48670b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
48680b57cec5SDimitry Andric     return MCDisassembler::Fail;
48690b57cec5SDimitry Andric 
48700b57cec5SDimitry Andric   return S;
48710b57cec5SDimitry Andric }
48720b57cec5SDimitry Andric 
DecodeSTRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)48730b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
48740b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
48750b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48760b57cec5SDimitry Andric 
48770b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48780b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
48790b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
48800b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
48810b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
48820b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
48830b57cec5SDimitry Andric 
48840b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
48850b57cec5SDimitry Andric 
48860b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48870b57cec5SDimitry Andric     return MCDisassembler::Fail;
48880b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
48890b57cec5SDimitry Andric     return MCDisassembler::Fail;
48900b57cec5SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
48910b57cec5SDimitry Andric     return MCDisassembler::Fail;
48920b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
48930b57cec5SDimitry Andric     return MCDisassembler::Fail;
48940b57cec5SDimitry Andric 
48950b57cec5SDimitry Andric   return S;
48960b57cec5SDimitry Andric }
48970b57cec5SDimitry Andric 
DecodeSTRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)48980b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
48990b57cec5SDimitry Andric                             uint64_t Address, const void *Decoder) {
49000b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49010b57cec5SDimitry Andric 
49020b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
49030b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
49040b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
49050b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
49060b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
49070b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
49080b57cec5SDimitry Andric 
49090b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
49100b57cec5SDimitry Andric 
49110b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
49120b57cec5SDimitry Andric     return MCDisassembler::Fail;
49130b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
49140b57cec5SDimitry Andric     return MCDisassembler::Fail;
49150b57cec5SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
49160b57cec5SDimitry Andric     return MCDisassembler::Fail;
49170b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
49180b57cec5SDimitry Andric     return MCDisassembler::Fail;
49190b57cec5SDimitry Andric 
49200b57cec5SDimitry Andric   return S;
49210b57cec5SDimitry Andric }
49220b57cec5SDimitry Andric 
DecodeVLD1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)49230b57cec5SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
49240b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
49250b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49260b57cec5SDimitry Andric 
49270b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
49280b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
49290b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
49300b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
49310b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
49320b57cec5SDimitry Andric 
49330b57cec5SDimitry Andric   unsigned align = 0;
49340b57cec5SDimitry Andric   unsigned index = 0;
49350b57cec5SDimitry Andric   switch (size) {
49360b57cec5SDimitry Andric     default:
49370b57cec5SDimitry Andric       return MCDisassembler::Fail;
49380b57cec5SDimitry Andric     case 0:
49390b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
49400b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
49410b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
49420b57cec5SDimitry Andric       break;
49430b57cec5SDimitry Andric     case 1:
49440b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
49450b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
49460b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
49470b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
49480b57cec5SDimitry Andric         align = 2;
49490b57cec5SDimitry Andric       break;
49500b57cec5SDimitry Andric     case 2:
49510b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
49520b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
49530b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
49540b57cec5SDimitry Andric 
49550b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
49560b57cec5SDimitry Andric         case 0 :
49570b57cec5SDimitry Andric           align = 0; break;
49580b57cec5SDimitry Andric         case 3:
49590b57cec5SDimitry Andric           align = 4; break;
49600b57cec5SDimitry Andric         default:
49610b57cec5SDimitry Andric           return MCDisassembler::Fail;
49620b57cec5SDimitry Andric       }
49630b57cec5SDimitry Andric       break;
49640b57cec5SDimitry Andric   }
49650b57cec5SDimitry Andric 
49660b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
49670b57cec5SDimitry Andric     return MCDisassembler::Fail;
49680b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
49690b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
49700b57cec5SDimitry Andric       return MCDisassembler::Fail;
49710b57cec5SDimitry Andric   }
49720b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
49730b57cec5SDimitry Andric     return MCDisassembler::Fail;
49740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
49750b57cec5SDimitry Andric   if (Rm != 0xF) {
49760b57cec5SDimitry Andric     if (Rm != 0xD) {
49770b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
49780b57cec5SDimitry Andric         return MCDisassembler::Fail;
49790b57cec5SDimitry Andric     } else
49800b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
49810b57cec5SDimitry Andric   }
49820b57cec5SDimitry Andric 
49830b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
49840b57cec5SDimitry Andric     return MCDisassembler::Fail;
49850b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
49860b57cec5SDimitry Andric 
49870b57cec5SDimitry Andric   return S;
49880b57cec5SDimitry Andric }
49890b57cec5SDimitry Andric 
DecodeVST1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)49900b57cec5SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
49910b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
49920b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49930b57cec5SDimitry Andric 
49940b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
49950b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
49960b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
49970b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
49980b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
49990b57cec5SDimitry Andric 
50000b57cec5SDimitry Andric   unsigned align = 0;
50010b57cec5SDimitry Andric   unsigned index = 0;
50020b57cec5SDimitry Andric   switch (size) {
50030b57cec5SDimitry Andric     default:
50040b57cec5SDimitry Andric       return MCDisassembler::Fail;
50050b57cec5SDimitry Andric     case 0:
50060b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
50070b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
50080b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
50090b57cec5SDimitry Andric       break;
50100b57cec5SDimitry Andric     case 1:
50110b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
50120b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
50130b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
50140b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
50150b57cec5SDimitry Andric         align = 2;
50160b57cec5SDimitry Andric       break;
50170b57cec5SDimitry Andric     case 2:
50180b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
50190b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
50200b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
50210b57cec5SDimitry Andric 
50220b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
50230b57cec5SDimitry Andric         case 0:
50240b57cec5SDimitry Andric           align = 0; break;
50250b57cec5SDimitry Andric         case 3:
50260b57cec5SDimitry Andric           align = 4; break;
50270b57cec5SDimitry Andric         default:
50280b57cec5SDimitry Andric           return MCDisassembler::Fail;
50290b57cec5SDimitry Andric       }
50300b57cec5SDimitry Andric       break;
50310b57cec5SDimitry Andric   }
50320b57cec5SDimitry Andric 
50330b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
50340b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
50350b57cec5SDimitry Andric     return MCDisassembler::Fail;
50360b57cec5SDimitry Andric   }
50370b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
50380b57cec5SDimitry Andric     return MCDisassembler::Fail;
50390b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
50400b57cec5SDimitry Andric   if (Rm != 0xF) {
50410b57cec5SDimitry Andric     if (Rm != 0xD) {
50420b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
50430b57cec5SDimitry Andric     return MCDisassembler::Fail;
50440b57cec5SDimitry Andric     } else
50450b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
50460b57cec5SDimitry Andric   }
50470b57cec5SDimitry Andric 
50480b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
50490b57cec5SDimitry Andric     return MCDisassembler::Fail;
50500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
50510b57cec5SDimitry Andric 
50520b57cec5SDimitry Andric   return S;
50530b57cec5SDimitry Andric }
50540b57cec5SDimitry Andric 
DecodeVLD2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)50550b57cec5SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
50560b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
50570b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
50580b57cec5SDimitry Andric 
50590b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
50600b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
50610b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
50620b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
50630b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
50640b57cec5SDimitry Andric 
50650b57cec5SDimitry Andric   unsigned align = 0;
50660b57cec5SDimitry Andric   unsigned index = 0;
50670b57cec5SDimitry Andric   unsigned inc = 1;
50680b57cec5SDimitry Andric   switch (size) {
50690b57cec5SDimitry Andric     default:
50700b57cec5SDimitry Andric       return MCDisassembler::Fail;
50710b57cec5SDimitry Andric     case 0:
50720b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
50730b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
50740b57cec5SDimitry Andric         align = 2;
50750b57cec5SDimitry Andric       break;
50760b57cec5SDimitry Andric     case 1:
50770b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
50780b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
50790b57cec5SDimitry Andric         align = 4;
50800b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
50810b57cec5SDimitry Andric         inc = 2;
50820b57cec5SDimitry Andric       break;
50830b57cec5SDimitry Andric     case 2:
50840b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
50850b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
50860b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
50870b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
50880b57cec5SDimitry Andric         align = 8;
50890b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
50900b57cec5SDimitry Andric         inc = 2;
50910b57cec5SDimitry Andric       break;
50920b57cec5SDimitry Andric   }
50930b57cec5SDimitry Andric 
50940b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
50950b57cec5SDimitry Andric     return MCDisassembler::Fail;
50960b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
50970b57cec5SDimitry Andric     return MCDisassembler::Fail;
50980b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
50990b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51000b57cec5SDimitry Andric       return MCDisassembler::Fail;
51010b57cec5SDimitry Andric   }
51020b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51030b57cec5SDimitry Andric     return MCDisassembler::Fail;
51040b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
51050b57cec5SDimitry Andric   if (Rm != 0xF) {
51060b57cec5SDimitry Andric     if (Rm != 0xD) {
51070b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
51080b57cec5SDimitry Andric         return MCDisassembler::Fail;
51090b57cec5SDimitry Andric     } else
51100b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
51110b57cec5SDimitry Andric   }
51120b57cec5SDimitry Andric 
51130b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
51140b57cec5SDimitry Andric     return MCDisassembler::Fail;
51150b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
51160b57cec5SDimitry Andric     return MCDisassembler::Fail;
51170b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
51180b57cec5SDimitry Andric 
51190b57cec5SDimitry Andric   return S;
51200b57cec5SDimitry Andric }
51210b57cec5SDimitry Andric 
DecodeVST2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)51220b57cec5SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
51230b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
51240b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51250b57cec5SDimitry Andric 
51260b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51270b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
51280b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
51290b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
51300b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
51310b57cec5SDimitry Andric 
51320b57cec5SDimitry Andric   unsigned align = 0;
51330b57cec5SDimitry Andric   unsigned index = 0;
51340b57cec5SDimitry Andric   unsigned inc = 1;
51350b57cec5SDimitry Andric   switch (size) {
51360b57cec5SDimitry Andric     default:
51370b57cec5SDimitry Andric       return MCDisassembler::Fail;
51380b57cec5SDimitry Andric     case 0:
51390b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
51400b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
51410b57cec5SDimitry Andric         align = 2;
51420b57cec5SDimitry Andric       break;
51430b57cec5SDimitry Andric     case 1:
51440b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
51450b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
51460b57cec5SDimitry Andric         align = 4;
51470b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
51480b57cec5SDimitry Andric         inc = 2;
51490b57cec5SDimitry Andric       break;
51500b57cec5SDimitry Andric     case 2:
51510b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
51520b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
51530b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
51540b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
51550b57cec5SDimitry Andric         align = 8;
51560b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
51570b57cec5SDimitry Andric         inc = 2;
51580b57cec5SDimitry Andric       break;
51590b57cec5SDimitry Andric   }
51600b57cec5SDimitry Andric 
51610b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
51620b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51630b57cec5SDimitry Andric       return MCDisassembler::Fail;
51640b57cec5SDimitry Andric   }
51650b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51660b57cec5SDimitry Andric     return MCDisassembler::Fail;
51670b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
51680b57cec5SDimitry Andric   if (Rm != 0xF) {
51690b57cec5SDimitry Andric     if (Rm != 0xD) {
51700b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
51710b57cec5SDimitry Andric         return MCDisassembler::Fail;
51720b57cec5SDimitry Andric     } else
51730b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
51740b57cec5SDimitry Andric   }
51750b57cec5SDimitry Andric 
51760b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
51770b57cec5SDimitry Andric     return MCDisassembler::Fail;
51780b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
51790b57cec5SDimitry Andric     return MCDisassembler::Fail;
51800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
51810b57cec5SDimitry Andric 
51820b57cec5SDimitry Andric   return S;
51830b57cec5SDimitry Andric }
51840b57cec5SDimitry Andric 
DecodeVLD3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)51850b57cec5SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
51860b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
51870b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51880b57cec5SDimitry Andric 
51890b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51900b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
51910b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
51920b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
51930b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
51940b57cec5SDimitry Andric 
51950b57cec5SDimitry Andric   unsigned align = 0;
51960b57cec5SDimitry Andric   unsigned index = 0;
51970b57cec5SDimitry Andric   unsigned inc = 1;
51980b57cec5SDimitry Andric   switch (size) {
51990b57cec5SDimitry Andric     default:
52000b57cec5SDimitry Andric       return MCDisassembler::Fail;
52010b57cec5SDimitry Andric     case 0:
52020b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52030b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52040b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
52050b57cec5SDimitry Andric       break;
52060b57cec5SDimitry Andric     case 1:
52070b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52080b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52090b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
52100b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
52110b57cec5SDimitry Andric         inc = 2;
52120b57cec5SDimitry Andric       break;
52130b57cec5SDimitry Andric     case 2:
52140b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
52150b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52160b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
52170b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
52180b57cec5SDimitry Andric         inc = 2;
52190b57cec5SDimitry Andric       break;
52200b57cec5SDimitry Andric   }
52210b57cec5SDimitry Andric 
52220b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
52230b57cec5SDimitry Andric     return MCDisassembler::Fail;
52240b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
52250b57cec5SDimitry Andric     return MCDisassembler::Fail;
52260b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
52270b57cec5SDimitry Andric     return MCDisassembler::Fail;
52280b57cec5SDimitry Andric 
52290b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
52300b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52310b57cec5SDimitry Andric     return MCDisassembler::Fail;
52320b57cec5SDimitry Andric   }
52330b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52340b57cec5SDimitry Andric     return MCDisassembler::Fail;
52350b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
52360b57cec5SDimitry Andric   if (Rm != 0xF) {
52370b57cec5SDimitry Andric     if (Rm != 0xD) {
52380b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
52390b57cec5SDimitry Andric     return MCDisassembler::Fail;
52400b57cec5SDimitry Andric     } else
52410b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
52420b57cec5SDimitry Andric   }
52430b57cec5SDimitry Andric 
52440b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
52450b57cec5SDimitry Andric     return MCDisassembler::Fail;
52460b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
52470b57cec5SDimitry Andric     return MCDisassembler::Fail;
52480b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
52490b57cec5SDimitry Andric     return MCDisassembler::Fail;
52500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
52510b57cec5SDimitry Andric 
52520b57cec5SDimitry Andric   return S;
52530b57cec5SDimitry Andric }
52540b57cec5SDimitry Andric 
DecodeVST3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)52550b57cec5SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
52560b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
52570b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
52580b57cec5SDimitry Andric 
52590b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
52600b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
52610b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
52620b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
52630b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
52640b57cec5SDimitry Andric 
52650b57cec5SDimitry Andric   unsigned align = 0;
52660b57cec5SDimitry Andric   unsigned index = 0;
52670b57cec5SDimitry Andric   unsigned inc = 1;
52680b57cec5SDimitry Andric   switch (size) {
52690b57cec5SDimitry Andric     default:
52700b57cec5SDimitry Andric       return MCDisassembler::Fail;
52710b57cec5SDimitry Andric     case 0:
52720b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52730b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52740b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
52750b57cec5SDimitry Andric       break;
52760b57cec5SDimitry Andric     case 1:
52770b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52780b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52790b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
52800b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
52810b57cec5SDimitry Andric         inc = 2;
52820b57cec5SDimitry Andric       break;
52830b57cec5SDimitry Andric     case 2:
52840b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
52850b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52860b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
52870b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
52880b57cec5SDimitry Andric         inc = 2;
52890b57cec5SDimitry Andric       break;
52900b57cec5SDimitry Andric   }
52910b57cec5SDimitry Andric 
52920b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
52930b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52940b57cec5SDimitry Andric     return MCDisassembler::Fail;
52950b57cec5SDimitry Andric   }
52960b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52970b57cec5SDimitry Andric     return MCDisassembler::Fail;
52980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
52990b57cec5SDimitry Andric   if (Rm != 0xF) {
53000b57cec5SDimitry Andric     if (Rm != 0xD) {
53010b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
53020b57cec5SDimitry Andric     return MCDisassembler::Fail;
53030b57cec5SDimitry Andric     } else
53040b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
53050b57cec5SDimitry Andric   }
53060b57cec5SDimitry Andric 
53070b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53080b57cec5SDimitry Andric     return MCDisassembler::Fail;
53090b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
53100b57cec5SDimitry Andric     return MCDisassembler::Fail;
53110b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
53120b57cec5SDimitry Andric     return MCDisassembler::Fail;
53130b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
53140b57cec5SDimitry Andric 
53150b57cec5SDimitry Andric   return S;
53160b57cec5SDimitry Andric }
53170b57cec5SDimitry Andric 
DecodeVLD4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)53180b57cec5SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
53190b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
53200b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
53210b57cec5SDimitry Andric 
53220b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
53230b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
53240b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
53250b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
53260b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
53270b57cec5SDimitry Andric 
53280b57cec5SDimitry Andric   unsigned align = 0;
53290b57cec5SDimitry Andric   unsigned index = 0;
53300b57cec5SDimitry Andric   unsigned inc = 1;
53310b57cec5SDimitry Andric   switch (size) {
53320b57cec5SDimitry Andric     default:
53330b57cec5SDimitry Andric       return MCDisassembler::Fail;
53340b57cec5SDimitry Andric     case 0:
53350b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53360b57cec5SDimitry Andric         align = 4;
53370b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
53380b57cec5SDimitry Andric       break;
53390b57cec5SDimitry Andric     case 1:
53400b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53410b57cec5SDimitry Andric         align = 8;
53420b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
53430b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
53440b57cec5SDimitry Andric         inc = 2;
53450b57cec5SDimitry Andric       break;
53460b57cec5SDimitry Andric     case 2:
53470b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
53480b57cec5SDimitry Andric         case 0:
53490b57cec5SDimitry Andric           align = 0; break;
53500b57cec5SDimitry Andric         case 3:
53510b57cec5SDimitry Andric           return MCDisassembler::Fail;
53520b57cec5SDimitry Andric         default:
53530b57cec5SDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
53540b57cec5SDimitry Andric       }
53550b57cec5SDimitry Andric 
53560b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
53570b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
53580b57cec5SDimitry Andric         inc = 2;
53590b57cec5SDimitry Andric       break;
53600b57cec5SDimitry Andric   }
53610b57cec5SDimitry Andric 
53620b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53630b57cec5SDimitry Andric     return MCDisassembler::Fail;
53640b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
53650b57cec5SDimitry Andric     return MCDisassembler::Fail;
53660b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
53670b57cec5SDimitry Andric     return MCDisassembler::Fail;
53680b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
53690b57cec5SDimitry Andric     return MCDisassembler::Fail;
53700b57cec5SDimitry Andric 
53710b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
53720b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
53730b57cec5SDimitry Andric       return MCDisassembler::Fail;
53740b57cec5SDimitry Andric   }
53750b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
53760b57cec5SDimitry Andric     return MCDisassembler::Fail;
53770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
53780b57cec5SDimitry Andric   if (Rm != 0xF) {
53790b57cec5SDimitry Andric     if (Rm != 0xD) {
53800b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
53810b57cec5SDimitry Andric         return MCDisassembler::Fail;
53820b57cec5SDimitry Andric     } else
53830b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
53840b57cec5SDimitry Andric   }
53850b57cec5SDimitry Andric 
53860b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53870b57cec5SDimitry Andric     return MCDisassembler::Fail;
53880b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
53890b57cec5SDimitry Andric     return MCDisassembler::Fail;
53900b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
53910b57cec5SDimitry Andric     return MCDisassembler::Fail;
53920b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
53930b57cec5SDimitry Andric     return MCDisassembler::Fail;
53940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
53950b57cec5SDimitry Andric 
53960b57cec5SDimitry Andric   return S;
53970b57cec5SDimitry Andric }
53980b57cec5SDimitry Andric 
DecodeVST4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)53990b57cec5SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
54000b57cec5SDimitry Andric                          uint64_t Address, const void *Decoder) {
54010b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
54020b57cec5SDimitry Andric 
54030b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
54040b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
54050b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
54060b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
54070b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
54080b57cec5SDimitry Andric 
54090b57cec5SDimitry Andric   unsigned align = 0;
54100b57cec5SDimitry Andric   unsigned index = 0;
54110b57cec5SDimitry Andric   unsigned inc = 1;
54120b57cec5SDimitry Andric   switch (size) {
54130b57cec5SDimitry Andric     default:
54140b57cec5SDimitry Andric       return MCDisassembler::Fail;
54150b57cec5SDimitry Andric     case 0:
54160b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54170b57cec5SDimitry Andric         align = 4;
54180b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
54190b57cec5SDimitry Andric       break;
54200b57cec5SDimitry Andric     case 1:
54210b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54220b57cec5SDimitry Andric         align = 8;
54230b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
54240b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54250b57cec5SDimitry Andric         inc = 2;
54260b57cec5SDimitry Andric       break;
54270b57cec5SDimitry Andric     case 2:
54280b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
54290b57cec5SDimitry Andric         case 0:
54300b57cec5SDimitry Andric           align = 0; break;
54310b57cec5SDimitry Andric         case 3:
54320b57cec5SDimitry Andric           return MCDisassembler::Fail;
54330b57cec5SDimitry Andric         default:
54340b57cec5SDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
54350b57cec5SDimitry Andric       }
54360b57cec5SDimitry Andric 
54370b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
54380b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
54390b57cec5SDimitry Andric         inc = 2;
54400b57cec5SDimitry Andric       break;
54410b57cec5SDimitry Andric   }
54420b57cec5SDimitry Andric 
54430b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
54440b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54450b57cec5SDimitry Andric     return MCDisassembler::Fail;
54460b57cec5SDimitry Andric   }
54470b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54480b57cec5SDimitry Andric     return MCDisassembler::Fail;
54490b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
54500b57cec5SDimitry Andric   if (Rm != 0xF) {
54510b57cec5SDimitry Andric     if (Rm != 0xD) {
54520b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
54530b57cec5SDimitry Andric     return MCDisassembler::Fail;
54540b57cec5SDimitry Andric     } else
54550b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
54560b57cec5SDimitry Andric   }
54570b57cec5SDimitry Andric 
54580b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
54590b57cec5SDimitry Andric     return MCDisassembler::Fail;
54600b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
54610b57cec5SDimitry Andric     return MCDisassembler::Fail;
54620b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
54630b57cec5SDimitry Andric     return MCDisassembler::Fail;
54640b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
54650b57cec5SDimitry Andric     return MCDisassembler::Fail;
54660b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
54670b57cec5SDimitry Andric 
54680b57cec5SDimitry Andric   return S;
54690b57cec5SDimitry Andric }
54700b57cec5SDimitry Andric 
DecodeVMOVSRR(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)54710b57cec5SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
54720b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
54730b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
54740b57cec5SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
54750b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
54760b57cec5SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
54770b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
54780b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
54790b57cec5SDimitry Andric 
54800b57cec5SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
54810b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
54820b57cec5SDimitry Andric 
54830b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
54840b57cec5SDimitry Andric     return MCDisassembler::Fail;
54850b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
54860b57cec5SDimitry Andric     return MCDisassembler::Fail;
54870b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
54880b57cec5SDimitry Andric     return MCDisassembler::Fail;
54890b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
54900b57cec5SDimitry Andric     return MCDisassembler::Fail;
54910b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
54920b57cec5SDimitry Andric     return MCDisassembler::Fail;
54930b57cec5SDimitry Andric 
54940b57cec5SDimitry Andric   return S;
54950b57cec5SDimitry Andric }
54960b57cec5SDimitry Andric 
DecodeVMOVRRS(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)54970b57cec5SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
54980b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
54990b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55000b57cec5SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
55010b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
55020b57cec5SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
55030b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
55040b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
55050b57cec5SDimitry Andric 
55060b57cec5SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
55070b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
55080b57cec5SDimitry Andric 
55090b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
55100b57cec5SDimitry Andric     return MCDisassembler::Fail;
55110b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
55120b57cec5SDimitry Andric     return MCDisassembler::Fail;
55130b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
55140b57cec5SDimitry Andric     return MCDisassembler::Fail;
55150b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
55160b57cec5SDimitry Andric     return MCDisassembler::Fail;
55170b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
55180b57cec5SDimitry Andric     return MCDisassembler::Fail;
55190b57cec5SDimitry Andric 
55200b57cec5SDimitry Andric   return S;
55210b57cec5SDimitry Andric }
55220b57cec5SDimitry Andric 
DecodeIT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)55230b57cec5SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
55240b57cec5SDimitry Andric                              uint64_t Address, const void *Decoder) {
55250b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55260b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 4, 4);
55270b57cec5SDimitry Andric   unsigned mask = fieldFromInstruction(Insn, 0, 4);
55280b57cec5SDimitry Andric 
55290b57cec5SDimitry Andric   if (pred == 0xF) {
55300b57cec5SDimitry Andric     pred = 0xE;
55310b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
55320b57cec5SDimitry Andric   }
55330b57cec5SDimitry Andric 
55340b57cec5SDimitry Andric   if (mask == 0x0)
55350b57cec5SDimitry Andric     return MCDisassembler::Fail;
55360b57cec5SDimitry Andric 
55370b57cec5SDimitry Andric   // IT masks are encoded as a sequence of replacement low-order bits
55380b57cec5SDimitry Andric   // for the condition code. So if the low bit of the starting
55390b57cec5SDimitry Andric   // condition code is 1, then we have to flip all the bits above the
55400b57cec5SDimitry Andric   // terminating bit (which is the lowest 1 bit).
55410b57cec5SDimitry Andric   if (pred & 1) {
55420b57cec5SDimitry Andric     unsigned LowBit = mask & -mask;
55430b57cec5SDimitry Andric     unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
55440b57cec5SDimitry Andric     mask ^= BitsAboveLowBit;
55450b57cec5SDimitry Andric   }
55460b57cec5SDimitry Andric 
55470b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(pred));
55480b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(mask));
55490b57cec5SDimitry Andric   return S;
55500b57cec5SDimitry Andric }
55510b57cec5SDimitry Andric 
55520b57cec5SDimitry Andric static DecodeStatus
DecodeT2LDRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)55530b57cec5SDimitry Andric DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
55540b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
55550b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55560b57cec5SDimitry Andric 
55570b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
55580b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
55590b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
55600b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
55610b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
55620b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
55630b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
55640b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
55650b57cec5SDimitry Andric 
55660b57cec5SDimitry Andric   addr |= (U << 8) | (Rn << 9);
55670b57cec5SDimitry Andric 
55680b57cec5SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
55690b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
55700b57cec5SDimitry Andric   if (Rt == Rt2)
55710b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
55720b57cec5SDimitry Andric 
55730b57cec5SDimitry Andric   // Rt
55740b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
55750b57cec5SDimitry Andric     return MCDisassembler::Fail;
55760b57cec5SDimitry Andric   // Rt2
55770b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
55780b57cec5SDimitry Andric     return MCDisassembler::Fail;
55790b57cec5SDimitry Andric   // Writeback operand
55800b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
55810b57cec5SDimitry Andric     return MCDisassembler::Fail;
55820b57cec5SDimitry Andric   // addr
55830b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
55840b57cec5SDimitry Andric     return MCDisassembler::Fail;
55850b57cec5SDimitry Andric 
55860b57cec5SDimitry Andric   return S;
55870b57cec5SDimitry Andric }
55880b57cec5SDimitry Andric 
55890b57cec5SDimitry Andric static DecodeStatus
DecodeT2STRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)55900b57cec5SDimitry Andric DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
55910b57cec5SDimitry Andric                            uint64_t Address, const void *Decoder) {
55920b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55930b57cec5SDimitry Andric 
55940b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
55950b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
55960b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
55970b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
55980b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
55990b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
56000b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
56010b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
56020b57cec5SDimitry Andric 
56030b57cec5SDimitry Andric   addr |= (U << 8) | (Rn << 9);
56040b57cec5SDimitry Andric 
56050b57cec5SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
56060b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
56070b57cec5SDimitry Andric 
56080b57cec5SDimitry Andric   // Writeback operand
56090b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
56100b57cec5SDimitry Andric     return MCDisassembler::Fail;
56110b57cec5SDimitry Andric   // Rt
56120b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
56130b57cec5SDimitry Andric     return MCDisassembler::Fail;
56140b57cec5SDimitry Andric   // Rt2
56150b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
56160b57cec5SDimitry Andric     return MCDisassembler::Fail;
56170b57cec5SDimitry Andric   // addr
56180b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
56190b57cec5SDimitry Andric     return MCDisassembler::Fail;
56200b57cec5SDimitry Andric 
56210b57cec5SDimitry Andric   return S;
56220b57cec5SDimitry Andric }
56230b57cec5SDimitry Andric 
DecodeT2Adr(MCInst & Inst,uint32_t Insn,uint64_t Address,const void * Decoder)56240b57cec5SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
56250b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder) {
56260b57cec5SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
56270b57cec5SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
56280b57cec5SDimitry Andric   if (sign1 != sign2) return MCDisassembler::Fail;
5629480093f4SDimitry Andric   const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
5630480093f4SDimitry Andric   assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst");
5631480093f4SDimitry Andric   DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder);
56320b57cec5SDimitry Andric 
56330b57cec5SDimitry Andric   unsigned Val = fieldFromInstruction(Insn, 0, 8);
56340b57cec5SDimitry Andric   Val |= fieldFromInstruction(Insn, 12, 3) << 8;
56350b57cec5SDimitry Andric   Val |= fieldFromInstruction(Insn, 26, 1) << 11;
5636480093f4SDimitry Andric   // If sign, then it is decreasing the address.
5637480093f4SDimitry Andric   if (sign1) {
5638480093f4SDimitry Andric     // Following ARMv7 Architecture Manual, when the offset
5639480093f4SDimitry Andric     // is zero, it is decoded as a subw, not as a adr.w
5640480093f4SDimitry Andric     if (!Val) {
5641480093f4SDimitry Andric       Inst.setOpcode(ARM::t2SUBri12);
5642480093f4SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::PC));
5643480093f4SDimitry Andric     } else
5644480093f4SDimitry Andric       Val = -Val;
5645480093f4SDimitry Andric   }
5646480093f4SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
5647480093f4SDimitry Andric   return S;
56480b57cec5SDimitry Andric }
56490b57cec5SDimitry Andric 
DecodeT2ShifterImmOperand(MCInst & Inst,uint32_t Val,uint64_t Address,const void * Decoder)56500b57cec5SDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
56510b57cec5SDimitry Andric                                               uint64_t Address,
56520b57cec5SDimitry Andric                                               const void *Decoder) {
56530b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
56540b57cec5SDimitry Andric 
56550b57cec5SDimitry Andric   // Shift of "asr #32" is not allowed in Thumb2 mode.
56560b57cec5SDimitry Andric   if (Val == 0x20) S = MCDisassembler::Fail;
56570b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
56580b57cec5SDimitry Andric   return S;
56590b57cec5SDimitry Andric }
56600b57cec5SDimitry Andric 
DecodeSwap(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)56610b57cec5SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
56620b57cec5SDimitry Andric                                uint64_t Address, const void *Decoder) {
56630b57cec5SDimitry Andric   unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
56640b57cec5SDimitry Andric   unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
56650b57cec5SDimitry Andric   unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
56660b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
56670b57cec5SDimitry Andric 
56680b57cec5SDimitry Andric   if (pred == 0xF)
56690b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
56700b57cec5SDimitry Andric 
56710b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
56720b57cec5SDimitry Andric 
56730b57cec5SDimitry Andric   if (Rt == Rn || Rn == Rt2)
56740b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
56750b57cec5SDimitry Andric 
56760b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
56770b57cec5SDimitry Andric     return MCDisassembler::Fail;
56780b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
56790b57cec5SDimitry Andric     return MCDisassembler::Fail;
56800b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
56810b57cec5SDimitry Andric     return MCDisassembler::Fail;
56820b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
56830b57cec5SDimitry Andric     return MCDisassembler::Fail;
56840b57cec5SDimitry Andric 
56850b57cec5SDimitry Andric   return S;
56860b57cec5SDimitry Andric }
56870b57cec5SDimitry Andric 
DecodeVCVTD(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)56880b57cec5SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
56890b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder) {
56900b57cec5SDimitry Andric   const FeatureBitset &featureBits =
56910b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
56920b57cec5SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
56930b57cec5SDimitry Andric 
56940b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
56950b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
56960b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
56970b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
56980b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
56990b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
57000b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
57010b57cec5SDimitry Andric 
57020b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
57030b57cec5SDimitry Andric 
57040b57cec5SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
57050b57cec5SDimitry Andric   if (!(imm & 0x38)) {
57060b57cec5SDimitry Andric     if (cmode == 0xF) {
57070b57cec5SDimitry Andric       if (op == 1) return MCDisassembler::Fail;
57080b57cec5SDimitry Andric       Inst.setOpcode(ARM::VMOVv2f32);
57090b57cec5SDimitry Andric     }
57100b57cec5SDimitry Andric     if (hasFullFP16) {
57110b57cec5SDimitry Andric       if (cmode == 0xE) {
57120b57cec5SDimitry Andric         if (op == 1) {
57130b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv1i64);
57140b57cec5SDimitry Andric         } else {
57150b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv8i8);
57160b57cec5SDimitry Andric         }
57170b57cec5SDimitry Andric       }
57180b57cec5SDimitry Andric       if (cmode == 0xD) {
57190b57cec5SDimitry Andric         if (op == 1) {
57200b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
57210b57cec5SDimitry Andric         } else {
57220b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
57230b57cec5SDimitry Andric         }
57240b57cec5SDimitry Andric       }
57250b57cec5SDimitry Andric       if (cmode == 0xC) {
57260b57cec5SDimitry Andric         if (op == 1) {
57270b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
57280b57cec5SDimitry Andric         } else {
57290b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
57300b57cec5SDimitry Andric         }
57310b57cec5SDimitry Andric       }
57320b57cec5SDimitry Andric     }
57338bcb0991SDimitry Andric     return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
57340b57cec5SDimitry Andric   }
57350b57cec5SDimitry Andric 
57360b57cec5SDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
57370b57cec5SDimitry Andric 
57380b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
57390b57cec5SDimitry Andric     return MCDisassembler::Fail;
57400b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
57410b57cec5SDimitry Andric     return MCDisassembler::Fail;
57420b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
57430b57cec5SDimitry Andric 
57440b57cec5SDimitry Andric   return S;
57450b57cec5SDimitry Andric }
57460b57cec5SDimitry Andric 
DecodeVCVTQ(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)57470b57cec5SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
57480b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder) {
57490b57cec5SDimitry Andric   const FeatureBitset &featureBits =
57500b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
57510b57cec5SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
57520b57cec5SDimitry Andric 
57530b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
57540b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
57550b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
57560b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
57570b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
57580b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
57590b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
57600b57cec5SDimitry Andric 
57610b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
57620b57cec5SDimitry Andric 
57630b57cec5SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
57640b57cec5SDimitry Andric   if (!(imm & 0x38)) {
57650b57cec5SDimitry Andric     if (cmode == 0xF) {
57660b57cec5SDimitry Andric       if (op == 1) return MCDisassembler::Fail;
57670b57cec5SDimitry Andric       Inst.setOpcode(ARM::VMOVv4f32);
57680b57cec5SDimitry Andric     }
57690b57cec5SDimitry Andric     if (hasFullFP16) {
57700b57cec5SDimitry Andric       if (cmode == 0xE) {
57710b57cec5SDimitry Andric         if (op == 1) {
57720b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i64);
57730b57cec5SDimitry Andric         } else {
57740b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv16i8);
57750b57cec5SDimitry Andric         }
57760b57cec5SDimitry Andric       }
57770b57cec5SDimitry Andric       if (cmode == 0xD) {
57780b57cec5SDimitry Andric         if (op == 1) {
57790b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
57800b57cec5SDimitry Andric         } else {
57810b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
57820b57cec5SDimitry Andric         }
57830b57cec5SDimitry Andric       }
57840b57cec5SDimitry Andric       if (cmode == 0xC) {
57850b57cec5SDimitry Andric         if (op == 1) {
57860b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
57870b57cec5SDimitry Andric         } else {
57880b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
57890b57cec5SDimitry Andric         }
57900b57cec5SDimitry Andric       }
57910b57cec5SDimitry Andric     }
57928bcb0991SDimitry Andric     return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
57930b57cec5SDimitry Andric   }
57940b57cec5SDimitry Andric 
57950b57cec5SDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
57960b57cec5SDimitry Andric 
57970b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
57980b57cec5SDimitry Andric     return MCDisassembler::Fail;
57990b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
58000b57cec5SDimitry Andric     return MCDisassembler::Fail;
58010b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
58020b57cec5SDimitry Andric 
58030b57cec5SDimitry Andric   return S;
58040b57cec5SDimitry Andric }
58050b57cec5SDimitry Andric 
DecodeNEONComplexLane64Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)58060b57cec5SDimitry Andric static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
58070b57cec5SDimitry Andric                                                        unsigned Insn,
58080b57cec5SDimitry Andric                                                        uint64_t Address,
58090b57cec5SDimitry Andric                                                        const void *Decoder) {
58100b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
58110b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
58120b57cec5SDimitry Andric   unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
58130b57cec5SDimitry Andric   Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
58140b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
58150b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
58160b57cec5SDimitry Andric   unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
58170b57cec5SDimitry Andric   unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
58180b57cec5SDimitry Andric 
58190b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58200b57cec5SDimitry Andric 
58210b57cec5SDimitry Andric   auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
58220b57cec5SDimitry Andric 
58230b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
58240b57cec5SDimitry Andric     return MCDisassembler::Fail;
58250b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
58260b57cec5SDimitry Andric     return MCDisassembler::Fail;
58270b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
58280b57cec5SDimitry Andric     return MCDisassembler::Fail;
58290b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
58300b57cec5SDimitry Andric     return MCDisassembler::Fail;
58310b57cec5SDimitry Andric   // The lane index does not have any bits in the encoding, because it can only
58320b57cec5SDimitry Andric   // be 0.
58330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
58340b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(rotate));
58350b57cec5SDimitry Andric 
58360b57cec5SDimitry Andric   return S;
58370b57cec5SDimitry Andric }
58380b57cec5SDimitry Andric 
DecodeLDR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)58390b57cec5SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
58400b57cec5SDimitry Andric                                 uint64_t Address, const void *Decoder) {
58410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58420b57cec5SDimitry Andric 
58430b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
58440b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
58450b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
58460b57cec5SDimitry Andric   Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
58470b57cec5SDimitry Andric   unsigned Cond = fieldFromInstruction(Val, 28, 4);
58480b57cec5SDimitry Andric 
58490b57cec5SDimitry Andric   if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
58500b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58510b57cec5SDimitry Andric 
58520b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
58530b57cec5SDimitry Andric     return MCDisassembler::Fail;
58540b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
58550b57cec5SDimitry Andric     return MCDisassembler::Fail;
58560b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
58570b57cec5SDimitry Andric     return MCDisassembler::Fail;
58580b57cec5SDimitry Andric   if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
58590b57cec5SDimitry Andric     return MCDisassembler::Fail;
58600b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
58610b57cec5SDimitry Andric     return MCDisassembler::Fail;
58620b57cec5SDimitry Andric 
58630b57cec5SDimitry Andric   return S;
58640b57cec5SDimitry Andric }
58650b57cec5SDimitry Andric 
DecoderForMRRC2AndMCRR2(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)58660b57cec5SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
58670b57cec5SDimitry Andric                                             uint64_t Address, const void *Decoder) {
58680b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58690b57cec5SDimitry Andric 
58700b57cec5SDimitry Andric   unsigned CRm = fieldFromInstruction(Val, 0, 4);
58710b57cec5SDimitry Andric   unsigned opc1 = fieldFromInstruction(Val, 4, 4);
58720b57cec5SDimitry Andric   unsigned cop = fieldFromInstruction(Val, 8, 4);
58730b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
58740b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
58750b57cec5SDimitry Andric 
58760b57cec5SDimitry Andric   if ((cop & ~0x1) == 0xa)
58770b57cec5SDimitry Andric     return MCDisassembler::Fail;
58780b57cec5SDimitry Andric 
58790b57cec5SDimitry Andric   if (Rt == Rt2)
58800b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58810b57cec5SDimitry Andric 
58820b57cec5SDimitry Andric   // We have to check if the instruction is MRRC2
58830b57cec5SDimitry Andric   // or MCRR2 when constructing the operands for
58840b57cec5SDimitry Andric   // Inst. Reason is because MRRC2 stores to two
58850b57cec5SDimitry Andric   // registers so it's tablegen desc has has two
58860b57cec5SDimitry Andric   // outputs whereas MCRR doesn't store to any
58870b57cec5SDimitry Andric   // registers so all of it's operands are listed
58880b57cec5SDimitry Andric   // as inputs, therefore the operand order for
58890b57cec5SDimitry Andric   // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
58900b57cec5SDimitry Andric   // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
58910b57cec5SDimitry Andric 
58920b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MRRC2) {
58930b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
58940b57cec5SDimitry Andric       return MCDisassembler::Fail;
58950b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
58960b57cec5SDimitry Andric       return MCDisassembler::Fail;
58970b57cec5SDimitry Andric   }
58980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(cop));
58990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(opc1));
59000b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MCRR2) {
59010b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
59020b57cec5SDimitry Andric       return MCDisassembler::Fail;
59030b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
59040b57cec5SDimitry Andric       return MCDisassembler::Fail;
59050b57cec5SDimitry Andric   }
59060b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRm));
59070b57cec5SDimitry Andric 
59080b57cec5SDimitry Andric   return S;
59090b57cec5SDimitry Andric }
59100b57cec5SDimitry Andric 
DecodeForVMRSandVMSR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)59110b57cec5SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
59120b57cec5SDimitry Andric                                          uint64_t Address,
59130b57cec5SDimitry Andric                                          const void *Decoder) {
59140b57cec5SDimitry Andric   const FeatureBitset &featureBits =
59150b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
59160b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59170b57cec5SDimitry Andric 
59180b57cec5SDimitry Andric   // Add explicit operand for the destination sysreg, for cases where
59190b57cec5SDimitry Andric   // we have to model it for code generation purposes.
59200b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
59210b57cec5SDimitry Andric   case ARM::VMSR_FPSCR_NZCVQC:
59220b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
59230b57cec5SDimitry Andric     break;
59240b57cec5SDimitry Andric   case ARM::VMSR_P0:
59250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::VPR));
59260b57cec5SDimitry Andric     break;
59270b57cec5SDimitry Andric   }
59280b57cec5SDimitry Andric 
59290b57cec5SDimitry Andric   if (Inst.getOpcode() != ARM::FMSTAT) {
59300b57cec5SDimitry Andric     unsigned Rt = fieldFromInstruction(Val, 12, 4);
59310b57cec5SDimitry Andric 
59320b57cec5SDimitry Andric     if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
59330b57cec5SDimitry Andric       if (Rt == 13 || Rt == 15)
59340b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
59350b57cec5SDimitry Andric       Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
59360b57cec5SDimitry Andric     } else
59370b57cec5SDimitry Andric       Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
59380b57cec5SDimitry Andric   }
59390b57cec5SDimitry Andric 
59400b57cec5SDimitry Andric   // Add explicit operand for the source sysreg, similarly to above.
59410b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
59420b57cec5SDimitry Andric   case ARM::VMRS_FPSCR_NZCVQC:
59430b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
59440b57cec5SDimitry Andric     break;
59450b57cec5SDimitry Andric   case ARM::VMRS_P0:
59460b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::VPR));
59470b57cec5SDimitry Andric     break;
59480b57cec5SDimitry Andric   }
59490b57cec5SDimitry Andric 
59500b57cec5SDimitry Andric   if (featureBits[ARM::ModeThumb]) {
59510b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARMCC::AL));
59520b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
59530b57cec5SDimitry Andric   } else {
59540b57cec5SDimitry Andric     unsigned pred = fieldFromInstruction(Val, 28, 4);
59550b57cec5SDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
59560b57cec5SDimitry Andric       return MCDisassembler::Fail;
59570b57cec5SDimitry Andric   }
59580b57cec5SDimitry Andric 
59590b57cec5SDimitry Andric   return S;
59600b57cec5SDimitry Andric }
59610b57cec5SDimitry Andric 
59620b57cec5SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
DecodeBFLabelOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)59630b57cec5SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned Val,
59640b57cec5SDimitry Andric                                          uint64_t Address,
59650b57cec5SDimitry Andric                                          const void *Decoder) {
59660b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59670b57cec5SDimitry Andric   if (Val == 0 && !zeroPermitted)
59680b57cec5SDimitry Andric     S = MCDisassembler::Fail;
59690b57cec5SDimitry Andric 
59700b57cec5SDimitry Andric   uint64_t DecVal;
59710b57cec5SDimitry Andric   if (isSigned)
59720b57cec5SDimitry Andric     DecVal = SignExtend32<size + 1>(Val << 1);
59730b57cec5SDimitry Andric   else
59740b57cec5SDimitry Andric     DecVal = (Val << 1);
59750b57cec5SDimitry Andric 
59760b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + DecVal + 4, true, 4, Inst,
59770b57cec5SDimitry Andric                                 Decoder))
59780b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(isNeg ? -DecVal : DecVal));
59790b57cec5SDimitry Andric   return S;
59800b57cec5SDimitry Andric }
59810b57cec5SDimitry Andric 
DecodeBFAfterTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)59820b57cec5SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned Val,
59830b57cec5SDimitry Andric                                                uint64_t Address,
59840b57cec5SDimitry Andric                                                const void *Decoder) {
59850b57cec5SDimitry Andric 
59860b57cec5SDimitry Andric   uint64_t LocImm = Inst.getOperand(0).getImm();
59870b57cec5SDimitry Andric   Val = LocImm + (2 << Val);
59880b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + Val + 4, true, 4, Inst,
59890b57cec5SDimitry Andric                                 Decoder))
59900b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val));
59910b57cec5SDimitry Andric   return MCDisassembler::Success;
59920b57cec5SDimitry Andric }
59930b57cec5SDimitry Andric 
DecodePredNoALOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)59940b57cec5SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
59950b57cec5SDimitry Andric                                           uint64_t Address,
59960b57cec5SDimitry Andric                                           const void *Decoder) {
59970b57cec5SDimitry Andric   if (Val >= ARMCC::AL)  // also exclude the non-condition NV
59980b57cec5SDimitry Andric     return MCDisassembler::Fail;
59990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
60000b57cec5SDimitry Andric   return MCDisassembler::Success;
60010b57cec5SDimitry Andric }
60020b57cec5SDimitry Andric 
DecodeLOLoop(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)60030b57cec5SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
60040b57cec5SDimitry Andric                                  const void *Decoder) {
60050b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
60060b57cec5SDimitry Andric 
60070b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MVE_LCTP)
60080b57cec5SDimitry Andric     return S;
60090b57cec5SDimitry Andric 
60100b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 11, 1) |
60110b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 1, 10) << 1;
60120b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
60130b57cec5SDimitry Andric   case ARM::t2LEUpdate:
60140b57cec5SDimitry Andric   case ARM::MVE_LETP:
60150b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
60160b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
60170b57cec5SDimitry Andric     LLVM_FALLTHROUGH;
60180b57cec5SDimitry Andric   case ARM::t2LE:
60190b57cec5SDimitry Andric     if (!Check(S, DecodeBFLabelOperand<false, true, true, 11>(
60200b57cec5SDimitry Andric                    Inst, Imm, Address, Decoder)))
60210b57cec5SDimitry Andric       return MCDisassembler::Fail;
60220b57cec5SDimitry Andric     break;
60230b57cec5SDimitry Andric   case ARM::t2WLS:
60240b57cec5SDimitry Andric   case ARM::MVE_WLSTP_8:
60250b57cec5SDimitry Andric   case ARM::MVE_WLSTP_16:
60260b57cec5SDimitry Andric   case ARM::MVE_WLSTP_32:
60270b57cec5SDimitry Andric   case ARM::MVE_WLSTP_64:
60280b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
60290b57cec5SDimitry Andric     if (!Check(S,
60300b57cec5SDimitry Andric                DecoderGPRRegisterClass(Inst, fieldFromInstruction(Insn, 16, 4),
60310b57cec5SDimitry Andric                                        Address, Decoder)) ||
60320b57cec5SDimitry Andric         !Check(S, DecodeBFLabelOperand<false, false, true, 11>(
60330b57cec5SDimitry Andric                    Inst, Imm, Address, Decoder)))
60340b57cec5SDimitry Andric       return MCDisassembler::Fail;
60350b57cec5SDimitry Andric     break;
60360b57cec5SDimitry Andric   case ARM::t2DLS:
60370b57cec5SDimitry Andric   case ARM::MVE_DLSTP_8:
60380b57cec5SDimitry Andric   case ARM::MVE_DLSTP_16:
60390b57cec5SDimitry Andric   case ARM::MVE_DLSTP_32:
60400b57cec5SDimitry Andric   case ARM::MVE_DLSTP_64:
60410b57cec5SDimitry Andric     unsigned Rn = fieldFromInstruction(Insn, 16, 4);
60420b57cec5SDimitry Andric     if (Rn == 0xF) {
60430b57cec5SDimitry Andric       // Enforce all the rest of the instruction bits in LCTP, which
60440b57cec5SDimitry Andric       // won't have been reliably checked based on LCTP's own tablegen
60450b57cec5SDimitry Andric       // record, because we came to this decode by a roundabout route.
60460b57cec5SDimitry Andric       uint32_t CanonicalLCTP = 0xF00FE001, SBZMask = 0x00300FFE;
60470b57cec5SDimitry Andric       if ((Insn & ~SBZMask) != CanonicalLCTP)
60480b57cec5SDimitry Andric         return MCDisassembler::Fail;   // a mandatory bit is wrong: hard fail
60490b57cec5SDimitry Andric       if (Insn != CanonicalLCTP)
60500b57cec5SDimitry Andric         Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail
60510b57cec5SDimitry Andric 
60520b57cec5SDimitry Andric       Inst.setOpcode(ARM::MVE_LCTP);
60530b57cec5SDimitry Andric     } else {
60540b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::LR));
60550b57cec5SDimitry Andric       if (!Check(S, DecoderGPRRegisterClass(Inst,
60560b57cec5SDimitry Andric                                             fieldFromInstruction(Insn, 16, 4),
60570b57cec5SDimitry Andric                                             Address, Decoder)))
60580b57cec5SDimitry Andric         return MCDisassembler::Fail;
60590b57cec5SDimitry Andric     }
60600b57cec5SDimitry Andric     break;
60610b57cec5SDimitry Andric   }
60620b57cec5SDimitry Andric   return S;
60630b57cec5SDimitry Andric }
60640b57cec5SDimitry Andric 
DecodeLongShiftOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)60650b57cec5SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
60660b57cec5SDimitry Andric                                            uint64_t Address,
60670b57cec5SDimitry Andric                                            const void *Decoder) {
60680b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
60690b57cec5SDimitry Andric 
60700b57cec5SDimitry Andric   if (Val == 0)
60710b57cec5SDimitry Andric     Val = 32;
60720b57cec5SDimitry Andric 
60730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
60740b57cec5SDimitry Andric 
60750b57cec5SDimitry Andric   return S;
60760b57cec5SDimitry Andric }
60770b57cec5SDimitry Andric 
DecodetGPROddRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)60780b57cec5SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
60790b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
60800b57cec5SDimitry Andric   if ((RegNo) + 1 > 11)
60810b57cec5SDimitry Andric     return MCDisassembler::Fail;
60820b57cec5SDimitry Andric 
60830b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[(RegNo) + 1];
60840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
60850b57cec5SDimitry Andric   return MCDisassembler::Success;
60860b57cec5SDimitry Andric }
60870b57cec5SDimitry Andric 
DecodetGPREvenRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)60880b57cec5SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
60890b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
60900b57cec5SDimitry Andric   if ((RegNo) > 14)
60910b57cec5SDimitry Andric     return MCDisassembler::Fail;
60920b57cec5SDimitry Andric 
60930b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[(RegNo)];
60940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
60950b57cec5SDimitry Andric   return MCDisassembler::Success;
60960b57cec5SDimitry Andric }
60970b57cec5SDimitry Andric 
60985ffd83dbSDimitry Andric static DecodeStatus
DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)60995ffd83dbSDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
61005ffd83dbSDimitry Andric                                         uint64_t Address, const void *Decoder) {
61015ffd83dbSDimitry Andric   if (RegNo == 15) {
61025ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
61035ffd83dbSDimitry Andric     return MCDisassembler::Success;
61045ffd83dbSDimitry Andric   }
61055ffd83dbSDimitry Andric 
61065ffd83dbSDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
61075ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
61085ffd83dbSDimitry Andric 
61095ffd83dbSDimitry Andric   if (RegNo == 13)
61105ffd83dbSDimitry Andric     return MCDisassembler::SoftFail;
61115ffd83dbSDimitry Andric 
61125ffd83dbSDimitry Andric   return MCDisassembler::Success;
61135ffd83dbSDimitry Andric }
61145ffd83dbSDimitry Andric 
DecodeVSCCLRM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)61150b57cec5SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
61160b57cec5SDimitry Andric                                   const void *Decoder) {
61170b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61180b57cec5SDimitry Andric 
61190b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMCC::AL));
61200b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
61210b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::VSCCLRMD) {
61220b57cec5SDimitry Andric     unsigned reglist = (fieldFromInstruction(Insn, 1, 7) << 1) |
61230b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 12, 4) << 8) |
61240b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 22, 1) << 12);
61250b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegListOperand(Inst, reglist, Address, Decoder))) {
61260b57cec5SDimitry Andric       return MCDisassembler::Fail;
61270b57cec5SDimitry Andric     }
61280b57cec5SDimitry Andric   } else {
61290b57cec5SDimitry Andric     unsigned reglist = fieldFromInstruction(Insn, 0, 8) |
61300b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 22, 1) << 8) |
61310b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 12, 4) << 9);
61320b57cec5SDimitry Andric     if (!Check(S, DecodeSPRRegListOperand(Inst, reglist, Address, Decoder))) {
61330b57cec5SDimitry Andric       return MCDisassembler::Fail;
61340b57cec5SDimitry Andric     }
61350b57cec5SDimitry Andric   }
61360b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
61370b57cec5SDimitry Andric 
61380b57cec5SDimitry Andric   return S;
61390b57cec5SDimitry Andric }
61400b57cec5SDimitry Andric 
DecodeMQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)61410b57cec5SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
61420b57cec5SDimitry Andric                               uint64_t Address,
61430b57cec5SDimitry Andric                               const void *Decoder) {
61440b57cec5SDimitry Andric   if (RegNo > 7)
61450b57cec5SDimitry Andric     return MCDisassembler::Fail;
61460b57cec5SDimitry Andric 
61470b57cec5SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
61480b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
61490b57cec5SDimitry Andric   return MCDisassembler::Success;
61500b57cec5SDimitry Andric }
61510b57cec5SDimitry Andric 
61520b57cec5SDimitry Andric static const uint16_t QQPRDecoderTable[] = {
61530b57cec5SDimitry Andric      ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
61540b57cec5SDimitry Andric      ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
61550b57cec5SDimitry Andric };
61560b57cec5SDimitry Andric 
DecodeQQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)61570b57cec5SDimitry Andric static DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
61580b57cec5SDimitry Andric                               uint64_t Address,
61590b57cec5SDimitry Andric                               const void *Decoder) {
61600b57cec5SDimitry Andric   if (RegNo > 6)
61610b57cec5SDimitry Andric     return MCDisassembler::Fail;
61620b57cec5SDimitry Andric 
61630b57cec5SDimitry Andric   unsigned Register = QQPRDecoderTable[RegNo];
61640b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
61650b57cec5SDimitry Andric   return MCDisassembler::Success;
61660b57cec5SDimitry Andric }
61670b57cec5SDimitry Andric 
61680b57cec5SDimitry Andric static const uint16_t QQQQPRDecoderTable[] = {
61690b57cec5SDimitry Andric      ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
61700b57cec5SDimitry Andric      ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
61710b57cec5SDimitry Andric };
61720b57cec5SDimitry Andric 
DecodeQQQQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)61730b57cec5SDimitry Andric static DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
61740b57cec5SDimitry Andric                               uint64_t Address,
61750b57cec5SDimitry Andric                               const void *Decoder) {
61760b57cec5SDimitry Andric   if (RegNo > 4)
61770b57cec5SDimitry Andric     return MCDisassembler::Fail;
61780b57cec5SDimitry Andric 
61790b57cec5SDimitry Andric   unsigned Register = QQQQPRDecoderTable[RegNo];
61800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
61810b57cec5SDimitry Andric   return MCDisassembler::Success;
61820b57cec5SDimitry Andric }
61830b57cec5SDimitry Andric 
DecodeVPTMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)61840b57cec5SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
61850b57cec5SDimitry Andric                                          uint64_t Address,
61860b57cec5SDimitry Andric                                          const void *Decoder) {
61870b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61880b57cec5SDimitry Andric 
61890b57cec5SDimitry Andric   // Parse VPT mask and encode it in the MCInst as an immediate with the same
61900b57cec5SDimitry Andric   // format as the it_mask.  That is, from the second 'e|t' encode 'e' as 1 and
61910b57cec5SDimitry Andric   // 't' as 0 and finish with a 1.
61920b57cec5SDimitry Andric   unsigned Imm = 0;
61930b57cec5SDimitry Andric   // We always start with a 't'.
61940b57cec5SDimitry Andric   unsigned CurBit = 0;
61950b57cec5SDimitry Andric   for (int i = 3; i >= 0; --i) {
61960b57cec5SDimitry Andric     // If the bit we are looking at is not the same as last one, invert the
61970b57cec5SDimitry Andric     // CurBit, if it is the same leave it as is.
61980b57cec5SDimitry Andric     CurBit ^= (Val >> i) & 1U;
61990b57cec5SDimitry Andric 
62000b57cec5SDimitry Andric     // Encode the CurBit at the right place in the immediate.
62010b57cec5SDimitry Andric     Imm |= (CurBit << i);
62020b57cec5SDimitry Andric 
62030b57cec5SDimitry Andric     // If we are done, finish the encoding with a 1.
62040b57cec5SDimitry Andric     if ((Val & ~(~0U << i)) == 0) {
62050b57cec5SDimitry Andric       Imm |= 1U << i;
62060b57cec5SDimitry Andric       break;
62070b57cec5SDimitry Andric     }
62080b57cec5SDimitry Andric   }
62090b57cec5SDimitry Andric 
62100b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
62110b57cec5SDimitry Andric 
62120b57cec5SDimitry Andric   return S;
62130b57cec5SDimitry Andric }
62140b57cec5SDimitry Andric 
DecodeVpredROperand(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)62150b57cec5SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
62160b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
62170b57cec5SDimitry Andric   // The vpred_r operand type includes an MQPR register field derived
62180b57cec5SDimitry Andric   // from the encoding. But we don't actually want to add an operand
62190b57cec5SDimitry Andric   // to the MCInst at this stage, because AddThumbPredicate will do it
62200b57cec5SDimitry Andric   // later, and will infer the register number from the TIED_TO
62210b57cec5SDimitry Andric   // constraint. So this is a deliberately empty decoder method that
62220b57cec5SDimitry Andric   // will inhibit the auto-generated disassembly code from adding an
62230b57cec5SDimitry Andric   // operand at all.
62240b57cec5SDimitry Andric   return MCDisassembler::Success;
62250b57cec5SDimitry Andric }
62260b57cec5SDimitry Andric 
DecodeRestrictedIPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)62270b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst,
62280b57cec5SDimitry Andric                                                       unsigned Val,
62290b57cec5SDimitry Andric                                                       uint64_t Address,
62300b57cec5SDimitry Andric                                                       const void *Decoder) {
62310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE));
62320b57cec5SDimitry Andric   return MCDisassembler::Success;
62330b57cec5SDimitry Andric }
62340b57cec5SDimitry Andric 
DecodeRestrictedSPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)62350b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst,
62360b57cec5SDimitry Andric                                                       unsigned Val,
62370b57cec5SDimitry Andric                                                       uint64_t Address,
62380b57cec5SDimitry Andric                                                       const void *Decoder) {
62390b57cec5SDimitry Andric   unsigned Code;
62400b57cec5SDimitry Andric   switch (Val & 0x3) {
62410b57cec5SDimitry Andric   case 0:
62420b57cec5SDimitry Andric     Code = ARMCC::GE;
62430b57cec5SDimitry Andric     break;
62440b57cec5SDimitry Andric   case 1:
62450b57cec5SDimitry Andric     Code = ARMCC::LT;
62460b57cec5SDimitry Andric     break;
62470b57cec5SDimitry Andric   case 2:
62480b57cec5SDimitry Andric     Code = ARMCC::GT;
62490b57cec5SDimitry Andric     break;
62500b57cec5SDimitry Andric   case 3:
62510b57cec5SDimitry Andric     Code = ARMCC::LE;
62520b57cec5SDimitry Andric     break;
62530b57cec5SDimitry Andric   }
62540b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Code));
62550b57cec5SDimitry Andric   return MCDisassembler::Success;
62560b57cec5SDimitry Andric }
62570b57cec5SDimitry Andric 
DecodeRestrictedUPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)62580b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst,
62590b57cec5SDimitry Andric                                                       unsigned Val,
62600b57cec5SDimitry Andric                                                       uint64_t Address,
62610b57cec5SDimitry Andric                                                       const void *Decoder) {
62620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI));
62630b57cec5SDimitry Andric   return MCDisassembler::Success;
62640b57cec5SDimitry Andric }
62650b57cec5SDimitry Andric 
DecodeRestrictedFPPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)62660b57cec5SDimitry Andric static DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val,
62670b57cec5SDimitry Andric                                                      uint64_t Address,
62680b57cec5SDimitry Andric                                                      const void *Decoder) {
62690b57cec5SDimitry Andric   unsigned Code;
62700b57cec5SDimitry Andric   switch (Val) {
62710b57cec5SDimitry Andric   default:
62720b57cec5SDimitry Andric     return MCDisassembler::Fail;
62730b57cec5SDimitry Andric   case 0:
62740b57cec5SDimitry Andric     Code = ARMCC::EQ;
62750b57cec5SDimitry Andric     break;
62760b57cec5SDimitry Andric   case 1:
62770b57cec5SDimitry Andric     Code = ARMCC::NE;
62780b57cec5SDimitry Andric     break;
62790b57cec5SDimitry Andric   case 4:
62800b57cec5SDimitry Andric     Code = ARMCC::GE;
62810b57cec5SDimitry Andric     break;
62820b57cec5SDimitry Andric   case 5:
62830b57cec5SDimitry Andric     Code = ARMCC::LT;
62840b57cec5SDimitry Andric     break;
62850b57cec5SDimitry Andric   case 6:
62860b57cec5SDimitry Andric     Code = ARMCC::GT;
62870b57cec5SDimitry Andric     break;
62880b57cec5SDimitry Andric   case 7:
62890b57cec5SDimitry Andric     Code = ARMCC::LE;
62900b57cec5SDimitry Andric     break;
62910b57cec5SDimitry Andric   }
62920b57cec5SDimitry Andric 
62930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Code));
62940b57cec5SDimitry Andric   return MCDisassembler::Success;
62950b57cec5SDimitry Andric }
62960b57cec5SDimitry Andric 
DecodeVCVTImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)62970b57cec5SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Val,
62980b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder) {
62990b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63000b57cec5SDimitry Andric 
63010b57cec5SDimitry Andric   unsigned DecodedVal = 64 - Val;
63020b57cec5SDimitry Andric 
63030b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
63040b57cec5SDimitry Andric   case ARM::MVE_VCVTf16s16_fix:
63050b57cec5SDimitry Andric   case ARM::MVE_VCVTs16f16_fix:
63060b57cec5SDimitry Andric   case ARM::MVE_VCVTf16u16_fix:
63070b57cec5SDimitry Andric   case ARM::MVE_VCVTu16f16_fix:
63080b57cec5SDimitry Andric     if (DecodedVal > 16)
63090b57cec5SDimitry Andric       return MCDisassembler::Fail;
63100b57cec5SDimitry Andric     break;
63110b57cec5SDimitry Andric   case ARM::MVE_VCVTf32s32_fix:
63120b57cec5SDimitry Andric   case ARM::MVE_VCVTs32f32_fix:
63130b57cec5SDimitry Andric   case ARM::MVE_VCVTf32u32_fix:
63140b57cec5SDimitry Andric   case ARM::MVE_VCVTu32f32_fix:
63150b57cec5SDimitry Andric     if (DecodedVal > 32)
63160b57cec5SDimitry Andric       return MCDisassembler::Fail;
63170b57cec5SDimitry Andric     break;
63180b57cec5SDimitry Andric   }
63190b57cec5SDimitry Andric 
63200b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
63210b57cec5SDimitry Andric 
63220b57cec5SDimitry Andric   return S;
63230b57cec5SDimitry Andric }
63240b57cec5SDimitry Andric 
FixedRegForVSTRVLDR_SYSREG(unsigned Opcode)63250b57cec5SDimitry Andric static unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) {
63260b57cec5SDimitry Andric   switch (Opcode) {
63270b57cec5SDimitry Andric   case ARM::VSTR_P0_off:
63280b57cec5SDimitry Andric   case ARM::VSTR_P0_pre:
63290b57cec5SDimitry Andric   case ARM::VSTR_P0_post:
63300b57cec5SDimitry Andric   case ARM::VLDR_P0_off:
63310b57cec5SDimitry Andric   case ARM::VLDR_P0_pre:
63320b57cec5SDimitry Andric   case ARM::VLDR_P0_post:
63330b57cec5SDimitry Andric     return ARM::P0;
63340b57cec5SDimitry Andric   default:
63350b57cec5SDimitry Andric     return 0;
63360b57cec5SDimitry Andric   }
63370b57cec5SDimitry Andric }
63380b57cec5SDimitry Andric 
63390b57cec5SDimitry Andric template<bool Writeback>
DecodeVSTRVLDR_SYSREG(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)63400b57cec5SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val,
63410b57cec5SDimitry Andric                                           uint64_t Address,
63420b57cec5SDimitry Andric                                           const void *Decoder) {
63430b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
63440b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_pre:
63450b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_pre:
63460b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_pre:
63470b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_pre:
63480b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_off:
63490b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_off:
63500b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_off:
63510b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_off:
63520b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_post:
63530b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_post:
63540b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_post:
63550b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_post:
63560b57cec5SDimitry Andric     const FeatureBitset &featureBits =
63570b57cec5SDimitry Andric         ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
63580b57cec5SDimitry Andric 
63590b57cec5SDimitry Andric     if (!featureBits[ARM::HasMVEIntegerOps] && !featureBits[ARM::FeatureVFP2])
63600b57cec5SDimitry Andric       return MCDisassembler::Fail;
63610b57cec5SDimitry Andric   }
63620b57cec5SDimitry Andric 
63630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63640b57cec5SDimitry Andric   if (unsigned Sysreg = FixedRegForVSTRVLDR_SYSREG(Inst.getOpcode()))
63650b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Sysreg));
63660b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
63670b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Val, 0, 7) |
63680b57cec5SDimitry Andric                   (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
63690b57cec5SDimitry Andric 
63700b57cec5SDimitry Andric   if (Writeback) {
63710b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
63720b57cec5SDimitry Andric       return MCDisassembler::Fail;
63730b57cec5SDimitry Andric   }
63740b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm7s4(Inst, addr, Address, Decoder)))
63750b57cec5SDimitry Andric     return MCDisassembler::Fail;
63760b57cec5SDimitry Andric 
63770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMCC::AL));
63780b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
63790b57cec5SDimitry Andric 
63800b57cec5SDimitry Andric   return S;
63810b57cec5SDimitry Andric }
63820b57cec5SDimitry Andric 
DecodeMVE_MEM_pre(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder,unsigned Rn,OperandDecoder RnDecoder,OperandDecoder AddrDecoder)63830b57cec5SDimitry Andric static inline DecodeStatus DecodeMVE_MEM_pre(
63840b57cec5SDimitry Andric   MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder,
63850b57cec5SDimitry Andric   unsigned Rn, OperandDecoder RnDecoder, OperandDecoder AddrDecoder) {
63860b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63870b57cec5SDimitry Andric 
63880b57cec5SDimitry Andric   unsigned Qd = fieldFromInstruction(Val, 13, 3);
63890b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Val, 0, 7) |
63900b57cec5SDimitry Andric                   (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
63910b57cec5SDimitry Andric 
63920b57cec5SDimitry Andric   if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder)))
63930b57cec5SDimitry Andric     return MCDisassembler::Fail;
63940b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
63950b57cec5SDimitry Andric     return MCDisassembler::Fail;
63960b57cec5SDimitry Andric   if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
63970b57cec5SDimitry Andric     return MCDisassembler::Fail;
63980b57cec5SDimitry Andric 
63990b57cec5SDimitry Andric   return S;
64000b57cec5SDimitry Andric }
64010b57cec5SDimitry Andric 
64020b57cec5SDimitry Andric template <int shift>
DecodeMVE_MEM_1_pre(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)64030b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
64040b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
64050b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
64060b57cec5SDimitry Andric                            fieldFromInstruction(Val, 16, 3),
64070b57cec5SDimitry Andric                            DecodetGPRRegisterClass,
64080b57cec5SDimitry Andric                            DecodeTAddrModeImm7<shift>);
64090b57cec5SDimitry Andric }
64100b57cec5SDimitry Andric 
64110b57cec5SDimitry Andric template <int shift>
DecodeMVE_MEM_2_pre(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)64120b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
64130b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
64140b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
64150b57cec5SDimitry Andric                            fieldFromInstruction(Val, 16, 4),
64160b57cec5SDimitry Andric                            DecoderGPRRegisterClass,
64170b57cec5SDimitry Andric                            DecodeT2AddrModeImm7<shift,1>);
64180b57cec5SDimitry Andric }
64190b57cec5SDimitry Andric 
64200b57cec5SDimitry Andric template <int shift>
DecodeMVE_MEM_3_pre(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)64210b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
64220b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder) {
64230b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
64240b57cec5SDimitry Andric                            fieldFromInstruction(Val, 17, 3),
64250b57cec5SDimitry Andric                            DecodeMQPRRegisterClass,
64260b57cec5SDimitry Andric                            DecodeMveAddrModeQ<shift>);
64270b57cec5SDimitry Andric }
64280b57cec5SDimitry Andric 
64290b57cec5SDimitry Andric template<unsigned MinLog, unsigned MaxLog>
DecodePowerTwoOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)64300b57cec5SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
64310b57cec5SDimitry Andric                                           uint64_t Address,
64320b57cec5SDimitry Andric                                           const void *Decoder) {
64330b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
64340b57cec5SDimitry Andric 
64350b57cec5SDimitry Andric   if (Val < MinLog || Val > MaxLog)
64360b57cec5SDimitry Andric     return MCDisassembler::Fail;
64370b57cec5SDimitry Andric 
64380b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(1LL << Val));
64390b57cec5SDimitry Andric   return S;
64400b57cec5SDimitry Andric }
64410b57cec5SDimitry Andric 
64420b57cec5SDimitry Andric template<unsigned start>
DecodeMVEPairVectorIndexOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)64430b57cec5SDimitry Andric static DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val,
64440b57cec5SDimitry Andric                                                     uint64_t Address,
64450b57cec5SDimitry Andric                                                     const void *Decoder) {
64460b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
64470b57cec5SDimitry Andric 
64480b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(start + Val));
64490b57cec5SDimitry Andric 
64500b57cec5SDimitry Andric   return S;
64510b57cec5SDimitry Andric }
64520b57cec5SDimitry Andric 
DecodeMVEVMOVQtoDReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)64530b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
64540b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder) {
64550b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
64560b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
64570b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
64580b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
64590b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
64600b57cec5SDimitry Andric   unsigned index = fieldFromInstruction(Insn, 4, 1);
64610b57cec5SDimitry Andric 
64620b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
64630b57cec5SDimitry Andric     return MCDisassembler::Fail;
64640b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
64650b57cec5SDimitry Andric     return MCDisassembler::Fail;
64660b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
64670b57cec5SDimitry Andric     return MCDisassembler::Fail;
64680b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
64690b57cec5SDimitry Andric     return MCDisassembler::Fail;
64700b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
64710b57cec5SDimitry Andric     return MCDisassembler::Fail;
64720b57cec5SDimitry Andric 
64730b57cec5SDimitry Andric   return S;
64740b57cec5SDimitry Andric }
64750b57cec5SDimitry Andric 
DecodeMVEVMOVDRegtoQ(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)64760b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
64770b57cec5SDimitry Andric                                          uint64_t Address, const void *Decoder) {
64780b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
64790b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
64800b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
64810b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
64820b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
64830b57cec5SDimitry Andric   unsigned index = fieldFromInstruction(Insn, 4, 1);
64840b57cec5SDimitry Andric 
64850b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
64860b57cec5SDimitry Andric     return MCDisassembler::Fail;
64870b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
64880b57cec5SDimitry Andric     return MCDisassembler::Fail;
64890b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
64900b57cec5SDimitry Andric     return MCDisassembler::Fail;
64910b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
64920b57cec5SDimitry Andric     return MCDisassembler::Fail;
64930b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
64940b57cec5SDimitry Andric     return MCDisassembler::Fail;
64950b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
64960b57cec5SDimitry Andric     return MCDisassembler::Fail;
64970b57cec5SDimitry Andric 
64980b57cec5SDimitry Andric   return S;
64990b57cec5SDimitry Andric }
65000b57cec5SDimitry Andric 
DecodeMVEOverlappingLongShift(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)65010b57cec5SDimitry Andric static DecodeStatus DecodeMVEOverlappingLongShift(
65020b57cec5SDimitry Andric   MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) {
65030b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
65040b57cec5SDimitry Andric 
65050b57cec5SDimitry Andric   unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1;
65060b57cec5SDimitry Andric   unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1;
65070b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 12, 4);
65080b57cec5SDimitry Andric 
65090b57cec5SDimitry Andric   if (RdaHi == 14) {
65100b57cec5SDimitry Andric     // This value of RdaHi (really indicating pc, because RdaHi has to
65110b57cec5SDimitry Andric     // be an odd-numbered register, so the low bit will be set by the
65120b57cec5SDimitry Andric     // decode function below) indicates that we must decode as SQRSHR
65130b57cec5SDimitry Andric     // or UQRSHL, which both have a single Rda register field with all
65140b57cec5SDimitry Andric     // four bits.
65150b57cec5SDimitry Andric     unsigned Rda = fieldFromInstruction(Insn, 16, 4);
65160b57cec5SDimitry Andric 
65170b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
65180b57cec5SDimitry Andric       case ARM::MVE_ASRLr:
65190b57cec5SDimitry Andric       case ARM::MVE_SQRSHRL:
65200b57cec5SDimitry Andric         Inst.setOpcode(ARM::MVE_SQRSHR);
65210b57cec5SDimitry Andric         break;
65220b57cec5SDimitry Andric       case ARM::MVE_LSLLr:
65230b57cec5SDimitry Andric       case ARM::MVE_UQRSHLL:
65240b57cec5SDimitry Andric         Inst.setOpcode(ARM::MVE_UQRSHL);
65250b57cec5SDimitry Andric         break;
65260b57cec5SDimitry Andric       default:
65270b57cec5SDimitry Andric         llvm_unreachable("Unexpected starting opcode!");
65280b57cec5SDimitry Andric     }
65290b57cec5SDimitry Andric 
65300b57cec5SDimitry Andric     // Rda as output parameter
65310b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
65320b57cec5SDimitry Andric       return MCDisassembler::Fail;
65330b57cec5SDimitry Andric 
65340b57cec5SDimitry Andric     // Rda again as input parameter
65350b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
65360b57cec5SDimitry Andric       return MCDisassembler::Fail;
65370b57cec5SDimitry Andric 
65380b57cec5SDimitry Andric     // Rm, the amount to shift by
65390b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
65400b57cec5SDimitry Andric       return MCDisassembler::Fail;
65410b57cec5SDimitry Andric 
65428bcb0991SDimitry Andric     if (fieldFromInstruction (Insn, 6, 3) != 4)
65438bcb0991SDimitry Andric       return MCDisassembler::SoftFail;
65448bcb0991SDimitry Andric 
65458bcb0991SDimitry Andric     if (Rda == Rm)
65468bcb0991SDimitry Andric       return MCDisassembler::SoftFail;
65478bcb0991SDimitry Andric 
65480b57cec5SDimitry Andric     return S;
65490b57cec5SDimitry Andric   }
65500b57cec5SDimitry Andric 
65510b57cec5SDimitry Andric   // Otherwise, we decode as whichever opcode our caller has already
65520b57cec5SDimitry Andric   // put into Inst. Those all look the same:
65530b57cec5SDimitry Andric 
65540b57cec5SDimitry Andric   // RdaLo,RdaHi as output parameters
65550b57cec5SDimitry Andric   if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
65560b57cec5SDimitry Andric     return MCDisassembler::Fail;
65570b57cec5SDimitry Andric   if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
65580b57cec5SDimitry Andric     return MCDisassembler::Fail;
65590b57cec5SDimitry Andric 
65600b57cec5SDimitry Andric   // RdaLo,RdaHi again as input parameters
65610b57cec5SDimitry Andric   if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
65620b57cec5SDimitry Andric     return MCDisassembler::Fail;
65630b57cec5SDimitry Andric   if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
65640b57cec5SDimitry Andric     return MCDisassembler::Fail;
65650b57cec5SDimitry Andric 
65660b57cec5SDimitry Andric   // Rm, the amount to shift by
65670b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
65680b57cec5SDimitry Andric     return MCDisassembler::Fail;
65690b57cec5SDimitry Andric 
65708bcb0991SDimitry Andric   if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
65718bcb0991SDimitry Andric       Inst.getOpcode() == ARM::MVE_UQRSHLL) {
65728bcb0991SDimitry Andric     unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
65738bcb0991SDimitry Andric     // Saturate, the bit position for saturation
65748bcb0991SDimitry Andric     Inst.addOperand(MCOperand::createImm(Saturate));
65758bcb0991SDimitry Andric   }
65768bcb0991SDimitry Andric 
65770b57cec5SDimitry Andric   return S;
65780b57cec5SDimitry Andric }
65790b57cec5SDimitry Andric 
DecodeMVEVCVTt1fp(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)65800b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn, uint64_t Address,
65810b57cec5SDimitry Andric                                       const void *Decoder) {
65820b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
65830b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
65840b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
65850b57cec5SDimitry Andric   unsigned Qm = ((fieldFromInstruction(Insn, 5, 1) << 3) |
65860b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 1, 3));
65870b57cec5SDimitry Andric   unsigned imm6 = fieldFromInstruction(Insn, 16, 6);
65880b57cec5SDimitry Andric 
65890b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
65900b57cec5SDimitry Andric     return MCDisassembler::Fail;
65910b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
65920b57cec5SDimitry Andric     return MCDisassembler::Fail;
65930b57cec5SDimitry Andric   if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
65940b57cec5SDimitry Andric     return MCDisassembler::Fail;
65950b57cec5SDimitry Andric 
65960b57cec5SDimitry Andric   return S;
65970b57cec5SDimitry Andric }
65980b57cec5SDimitry Andric 
65990b57cec5SDimitry Andric template<bool scalar, OperandDecoder predicate_decoder>
DecodeMVEVCMP(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)66000b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
66010b57cec5SDimitry Andric                                   const void *Decoder) {
66020b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
66030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
66040b57cec5SDimitry Andric   unsigned Qn = fieldFromInstruction(Insn, 17, 3);
66050b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
66060b57cec5SDimitry Andric     return MCDisassembler::Fail;
66070b57cec5SDimitry Andric 
66080b57cec5SDimitry Andric   unsigned fc;
66090b57cec5SDimitry Andric 
66100b57cec5SDimitry Andric   if (scalar) {
66110b57cec5SDimitry Andric     fc = fieldFromInstruction(Insn, 12, 1) << 2 |
66120b57cec5SDimitry Andric          fieldFromInstruction(Insn, 7, 1) |
66130b57cec5SDimitry Andric          fieldFromInstruction(Insn, 5, 1) << 1;
66140b57cec5SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 0, 4);
66150b57cec5SDimitry Andric     if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder)))
66160b57cec5SDimitry Andric       return MCDisassembler::Fail;
66170b57cec5SDimitry Andric   } else {
66180b57cec5SDimitry Andric     fc = fieldFromInstruction(Insn, 12, 1) << 2 |
66190b57cec5SDimitry Andric          fieldFromInstruction(Insn, 7, 1) |
66200b57cec5SDimitry Andric          fieldFromInstruction(Insn, 0, 1) << 1;
66210b57cec5SDimitry Andric     unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 |
66220b57cec5SDimitry Andric                   fieldFromInstruction(Insn, 1, 3);
66230b57cec5SDimitry Andric     if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
66240b57cec5SDimitry Andric       return MCDisassembler::Fail;
66250b57cec5SDimitry Andric   }
66260b57cec5SDimitry Andric 
66270b57cec5SDimitry Andric   if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
66280b57cec5SDimitry Andric     return MCDisassembler::Fail;
66290b57cec5SDimitry Andric 
66300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
66310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
66320b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
66330b57cec5SDimitry Andric 
66340b57cec5SDimitry Andric   return S;
66350b57cec5SDimitry Andric }
66360b57cec5SDimitry Andric 
DecodeMveVCTP(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)66370b57cec5SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
66380b57cec5SDimitry Andric                                   const void *Decoder) {
66390b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
66400b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
66410b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
66420b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
66430b57cec5SDimitry Andric     return MCDisassembler::Fail;
66440b57cec5SDimitry Andric   return S;
66450b57cec5SDimitry Andric }
66468bcb0991SDimitry Andric 
DecodeMVEVPNOT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)66478bcb0991SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn, uint64_t Address,
66488bcb0991SDimitry Andric                                    const void *Decoder) {
66498bcb0991SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
66508bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
66518bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
66528bcb0991SDimitry Andric   return S;
66538bcb0991SDimitry Andric }
6654480093f4SDimitry Andric 
DecodeT2AddSubSPImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)6655480093f4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
6656480093f4SDimitry Andric                                         uint64_t Address, const void *Decoder) {
6657480093f4SDimitry Andric   const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
6658480093f4SDimitry Andric   const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
6659480093f4SDimitry Andric   const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 |
6660480093f4SDimitry Andric                          fieldFromInstruction(Insn, 12, 3) << 8 |
6661480093f4SDimitry Andric                          fieldFromInstruction(Insn, 0, 8);
6662480093f4SDimitry Andric   const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1);
6663480093f4SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
6664480093f4SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
6665480093f4SDimitry Andric   unsigned S = fieldFromInstruction(Insn, 20, 1);
6666480093f4SDimitry Andric   if (sign1 != sign2)
6667480093f4SDimitry Andric     return MCDisassembler::Fail;
6668480093f4SDimitry Andric 
6669480093f4SDimitry Andric   // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm)
6670480093f4SDimitry Andric   DecodeStatus DS = MCDisassembler::Success;
6671480093f4SDimitry Andric   if ((!Check(DS,
6672480093f4SDimitry Andric               DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst
6673480093f4SDimitry Andric       (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder))))
6674480093f4SDimitry Andric     return MCDisassembler::Fail;
6675480093f4SDimitry Andric   if (TypeT3) {
6676480093f4SDimitry Andric     Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
6677480093f4SDimitry Andric     Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
6678480093f4SDimitry Andric   } else {
6679480093f4SDimitry Andric     Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
6680480093f4SDimitry Andric     if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
6681480093f4SDimitry Andric       return MCDisassembler::Fail;
6682480093f4SDimitry Andric     if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
6683480093f4SDimitry Andric       return MCDisassembler::Fail;
6684*5f7ddb14SDimitry Andric   }
6685480093f4SDimitry Andric 
6686480093f4SDimitry Andric   return DS;
6687480093f4SDimitry Andric }
6688