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"
1681ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
20bdd1243dSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
22349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
230b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
250b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
260b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
27fe013be4SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
280b57cec5SDimitry Andric #include <algorithm>
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <cstdint>
310b57cec5SDimitry Andric #include <vector>
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric using namespace llvm;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric #define DEBUG_TYPE "arm-disassembler"
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric namespace {
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   // Handles the condition code status of instructions in IT blocks
420b57cec5SDimitry Andric   class ITStatus
430b57cec5SDimitry Andric   {
440b57cec5SDimitry Andric     public:
450b57cec5SDimitry Andric       // Returns the condition code for instruction in IT block
getITCC()460b57cec5SDimitry Andric       unsigned getITCC() {
470b57cec5SDimitry Andric         unsigned CC = ARMCC::AL;
480b57cec5SDimitry Andric         if (instrInITBlock())
490b57cec5SDimitry Andric           CC = ITStates.back();
500b57cec5SDimitry Andric         return CC;
510b57cec5SDimitry Andric       }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric       // Advances the IT block state to the next T or E
advanceITState()540b57cec5SDimitry Andric       void advanceITState() {
550b57cec5SDimitry Andric         ITStates.pop_back();
560b57cec5SDimitry Andric       }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric       // Returns true if the current instruction is in an IT block
instrInITBlock()590b57cec5SDimitry Andric       bool instrInITBlock() {
600b57cec5SDimitry Andric         return !ITStates.empty();
610b57cec5SDimitry Andric       }
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric       // Returns true if current instruction is the last instruction in an IT block
instrLastInITBlock()640b57cec5SDimitry Andric       bool instrLastInITBlock() {
650b57cec5SDimitry Andric         return ITStates.size() == 1;
660b57cec5SDimitry Andric       }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric       // Called when decoding an IT instruction. Sets the IT state for
690b57cec5SDimitry Andric       // the following instructions that for the IT block. Firstcond
700b57cec5SDimitry Andric       // corresponds to the field in the IT instruction encoding; Mask
710b57cec5SDimitry Andric       // is in the MCOperand format in which 1 means 'else' and 0 'then'.
setITState(char Firstcond,char Mask)720b57cec5SDimitry Andric       void setITState(char Firstcond, char Mask) {
730b57cec5SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
74fe013be4SDimitry Andric         unsigned NumTZ = llvm::countr_zero<uint8_t>(Mask);
750b57cec5SDimitry Andric         unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
760b57cec5SDimitry Andric         assert(NumTZ <= 3 && "Invalid IT mask!");
770b57cec5SDimitry Andric         // push condition codes onto the stack the correct order for the pops
780b57cec5SDimitry Andric         for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
790b57cec5SDimitry Andric           unsigned Else = (Mask >> Pos) & 1;
800b57cec5SDimitry Andric           ITStates.push_back(CCBits ^ Else);
810b57cec5SDimitry Andric         }
820b57cec5SDimitry Andric         ITStates.push_back(CCBits);
830b57cec5SDimitry Andric       }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric     private:
860b57cec5SDimitry Andric       std::vector<unsigned char> ITStates;
870b57cec5SDimitry Andric   };
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   class VPTStatus
900b57cec5SDimitry Andric   {
910b57cec5SDimitry Andric     public:
getVPTPred()920b57cec5SDimitry Andric       unsigned getVPTPred() {
930b57cec5SDimitry Andric         unsigned Pred = ARMVCC::None;
940b57cec5SDimitry Andric         if (instrInVPTBlock())
950b57cec5SDimitry Andric           Pred = VPTStates.back();
960b57cec5SDimitry Andric         return Pred;
970b57cec5SDimitry Andric       }
980b57cec5SDimitry Andric 
advanceVPTState()990b57cec5SDimitry Andric       void advanceVPTState() {
1000b57cec5SDimitry Andric         VPTStates.pop_back();
1010b57cec5SDimitry Andric       }
1020b57cec5SDimitry Andric 
instrInVPTBlock()1030b57cec5SDimitry Andric       bool instrInVPTBlock() {
1040b57cec5SDimitry Andric         return !VPTStates.empty();
1050b57cec5SDimitry Andric       }
1060b57cec5SDimitry Andric 
instrLastInVPTBlock()1070b57cec5SDimitry Andric       bool instrLastInVPTBlock() {
1080b57cec5SDimitry Andric         return VPTStates.size() == 1;
1090b57cec5SDimitry Andric       }
1100b57cec5SDimitry Andric 
setVPTState(char Mask)1110b57cec5SDimitry Andric       void setVPTState(char Mask) {
1120b57cec5SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
113fe013be4SDimitry Andric         unsigned NumTZ = llvm::countr_zero<uint8_t>(Mask);
1140b57cec5SDimitry Andric         assert(NumTZ <= 3 && "Invalid VPT mask!");
1150b57cec5SDimitry Andric         // push predicates onto the stack the correct order for the pops
1160b57cec5SDimitry Andric         for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
1170b57cec5SDimitry Andric           bool T = ((Mask >> Pos) & 1) == 0;
1180b57cec5SDimitry Andric           if (T)
1190b57cec5SDimitry Andric             VPTStates.push_back(ARMVCC::Then);
1200b57cec5SDimitry Andric           else
1210b57cec5SDimitry Andric             VPTStates.push_back(ARMVCC::Else);
1220b57cec5SDimitry Andric         }
1230b57cec5SDimitry Andric         VPTStates.push_back(ARMVCC::Then);
1240b57cec5SDimitry Andric       }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric     private:
1270b57cec5SDimitry Andric       SmallVector<unsigned char, 4> VPTStates;
1280b57cec5SDimitry Andric   };
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric /// ARM disassembler for all ARM platforms.
1310b57cec5SDimitry Andric class ARMDisassembler : public MCDisassembler {
1320b57cec5SDimitry Andric public:
133bdd1243dSDimitry Andric   std::unique_ptr<const MCInstrInfo> MCII;
134bdd1243dSDimitry Andric 
ARMDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,const MCInstrInfo * MCII)135bdd1243dSDimitry Andric   ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
136bdd1243dSDimitry Andric                   const MCInstrInfo *MCII)
137bdd1243dSDimitry Andric       : MCDisassembler(STI, Ctx), MCII(MCII) {
138fe013be4SDimitry Andric         InstructionEndianness = STI.hasFeature(ARM::ModeBigEndianInstructions)
139*c9157d92SDimitry Andric                                     ? llvm::endianness::big
140*c9157d92SDimitry Andric                                     : llvm::endianness::little;
1410b57cec5SDimitry Andric   }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   ~ARMDisassembler() override = default;
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
1460b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
1470b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
1480b57cec5SDimitry Andric 
149972a253aSDimitry Andric   uint64_t suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
150972a253aSDimitry Andric                               uint64_t Address) const override;
151972a253aSDimitry Andric 
1520b57cec5SDimitry Andric private:
1530b57cec5SDimitry Andric   DecodeStatus getARMInstruction(MCInst &Instr, uint64_t &Size,
1540b57cec5SDimitry Andric                                  ArrayRef<uint8_t> Bytes, uint64_t Address,
1550b57cec5SDimitry Andric                                  raw_ostream &CStream) const;
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   DecodeStatus getThumbInstruction(MCInst &Instr, uint64_t &Size,
1580b57cec5SDimitry Andric                                    ArrayRef<uint8_t> Bytes, uint64_t Address,
1590b57cec5SDimitry Andric                                    raw_ostream &CStream) const;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   mutable ITStatus ITBlock;
1620b57cec5SDimitry Andric   mutable VPTStatus VPTBlock;
1630b57cec5SDimitry Andric 
164bdd1243dSDimitry Andric   void AddThumb1SBit(MCInst &MI, bool InITBlock) const;
165bdd1243dSDimitry Andric   bool isVectorPredicable(const MCInst &MI) const;
1660b57cec5SDimitry Andric   DecodeStatus AddThumbPredicate(MCInst&) const;
1670b57cec5SDimitry Andric   void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const;
168bdd1243dSDimitry Andric 
169*c9157d92SDimitry Andric   llvm::endianness InstructionEndianness;
1700b57cec5SDimitry Andric };
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric } // end anonymous namespace
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric // Forward declare these because the autogenerated code will reference them.
1750b57cec5SDimitry Andric // Definitions are further down.
1760b57cec5SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
17781ad6265SDimitry Andric                                            uint64_t Address,
17881ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1790b57cec5SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
18081ad6265SDimitry Andric                                                uint64_t Address,
18181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1820b57cec5SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
18381ad6265SDimitry Andric                                                uint64_t Address,
18481ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1850b57cec5SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
18681ad6265SDimitry Andric                                                 uint64_t Address,
18781ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
1885ffd83dbSDimitry Andric static DecodeStatus
1895ffd83dbSDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
19081ad6265SDimitry Andric                                         uint64_t Address,
19181ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
1924824e7fdSDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
1934824e7fdSDimitry Andric                                                uint64_t Address,
19481ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1954824e7fdSDimitry Andric static DecodeStatus DecodeGPRnospRegisterClass(MCInst &Inst, unsigned RegNo,
1964824e7fdSDimitry Andric                                                uint64_t Address,
19781ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
19881ad6265SDimitry Andric static DecodeStatus
19981ad6265SDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
20081ad6265SDimitry Andric                                const MCDisassembler *Decoder);
20181ad6265SDimitry Andric static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo,
20281ad6265SDimitry Andric                                                  uint64_t Address,
20381ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
20481ad6265SDimitry Andric static DecodeStatus
20581ad6265SDimitry Andric DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
20681ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
2070b57cec5SDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
20881ad6265SDimitry Andric                                             uint64_t Address,
20981ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
2100b57cec5SDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
21181ad6265SDimitry Andric                                              uint64_t Address,
21281ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
2130b57cec5SDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
21481ad6265SDimitry Andric                                             uint64_t Address,
21581ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
2160b57cec5SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
21781ad6265SDimitry Andric                                                uint64_t Address,
21881ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
21981ad6265SDimitry Andric static DecodeStatus
22081ad6265SDimitry Andric DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
22181ad6265SDimitry Andric                                const MCDisassembler *Decoder);
222480093f4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
223480093f4SDimitry Andric                                              uint64_t Address,
22481ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
2250b57cec5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
2260b57cec5SDimitry Andric                                            uint64_t Address,
22781ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
22881ad6265SDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
22981ad6265SDimitry Andric                                            uint64_t Address,
23081ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
23181ad6265SDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
23281ad6265SDimitry Andric                                            uint64_t Address,
23381ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
23481ad6265SDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
23581ad6265SDimitry Andric                                              uint64_t Address,
23681ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
23781ad6265SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
23881ad6265SDimitry Andric                                              uint64_t Address,
23981ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
24081ad6265SDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
24181ad6265SDimitry Andric                                                 uint64_t Address,
24281ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
2430b57cec5SDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
24481ad6265SDimitry Andric                                            uint64_t Address,
24581ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
2460b57cec5SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
24781ad6265SDimitry Andric                                             uint64_t Address,
24881ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
249349cc55cSDimitry Andric static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
250349cc55cSDimitry Andric                                              uint64_t Address,
25181ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
252349cc55cSDimitry Andric static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
253349cc55cSDimitry Andric                                                uint64_t Address,
25481ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
2550b57cec5SDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
25681ad6265SDimitry Andric                                              uint64_t Address,
25781ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
25881ad6265SDimitry Andric static DecodeStatus
25981ad6265SDimitry Andric DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
26081ad6265SDimitry Andric                                const MCDisassembler *Decoder);
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
26381ad6265SDimitry Andric                                            uint64_t Address,
26481ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
2650b57cec5SDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
26681ad6265SDimitry Andric                                        uint64_t Address,
26781ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
2680b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
26981ad6265SDimitry Andric                                          uint64_t Address,
27081ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2710b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
27281ad6265SDimitry Andric                                             uint64_t Address,
27381ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
2740b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
27581ad6265SDimitry Andric                                             uint64_t Address,
27681ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
2790b57cec5SDimitry Andric                                               uint64_t Address,
28081ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
28181ad6265SDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
28281ad6265SDimitry Andric                                             uint64_t Address,
28381ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
28481ad6265SDimitry Andric static DecodeStatus
28581ad6265SDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
28681ad6265SDimitry Andric                               const MCDisassembler *Decoder);
2870b57cec5SDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
28881ad6265SDimitry Andric                                           uint64_t Address,
28981ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
2900b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
29181ad6265SDimitry Andric                                                uint64_t Address,
29281ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
29381ad6265SDimitry Andric static DecodeStatus DecodeTSBInstruction(MCInst &Inst, unsigned Insn,
29481ad6265SDimitry Andric                                          uint64_t Address,
29581ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2960b57cec5SDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
29781ad6265SDimitry Andric                                           uint64_t Address,
29881ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
2990b57cec5SDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
30081ad6265SDimitry Andric                                           uint64_t Address,
30181ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
3020b57cec5SDimitry Andric 
30381ad6265SDimitry Andric static DecodeStatus
30481ad6265SDimitry Andric DecodeMemMultipleWritebackInstruction(MCInst &Inst, unsigned Insn,
3050b57cec5SDimitry Andric                                       uint64_t Adddress,
30681ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
3070b57cec5SDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
30881ad6265SDimitry Andric                                              uint64_t Address,
30981ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3100b57cec5SDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
31181ad6265SDimitry Andric                                               uint64_t Address,
31281ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
3130b57cec5SDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
31481ad6265SDimitry Andric                                           uint64_t Address,
31581ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
3160b57cec5SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
31781ad6265SDimitry Andric                                           uint64_t Address,
31881ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
3190b57cec5SDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
32081ad6265SDimitry Andric                                          uint64_t Address,
32181ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
3220b57cec5SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
32381ad6265SDimitry Andric                                          uint64_t Address,
32481ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
3250b57cec5SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
32681ad6265SDimitry Andric                                             uint64_t Address,
32781ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
3280b57cec5SDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
32981ad6265SDimitry Andric                                            uint64_t Address,
33081ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
3314824e7fdSDimitry Andric static DecodeStatus DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn,
3324824e7fdSDimitry Andric                                                  uint64_t Address,
33381ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
3340b57cec5SDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
33581ad6265SDimitry Andric                                                uint64_t Address,
33681ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
3370b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
33881ad6265SDimitry Andric                                            uint64_t Address,
33981ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
3400b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
34181ad6265SDimitry Andric                                                uint64_t Address,
34281ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
3430b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
34481ad6265SDimitry Andric                                            uint64_t Address,
34581ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
3460b57cec5SDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
34781ad6265SDimitry Andric                                          uint64_t Address,
34881ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
3490b57cec5SDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
35081ad6265SDimitry Andric                                                uint64_t Address,
35181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
3520b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
35381ad6265SDimitry Andric                                            uint64_t Address,
35481ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
3550b57cec5SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
35681ad6265SDimitry Andric                                             uint64_t Address,
35781ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
3580b57cec5SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
35981ad6265SDimitry Andric                                             uint64_t Address,
36081ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
3610b57cec5SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
36281ad6265SDimitry Andric                                             uint64_t Address,
36381ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
3640b57cec5SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
36581ad6265SDimitry Andric                                             uint64_t Address,
36681ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
3670b57cec5SDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
36881ad6265SDimitry Andric                                          uint64_t Address,
36981ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
3700b57cec5SDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
37181ad6265SDimitry Andric                                          uint64_t Address,
37281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
3730b57cec5SDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
37481ad6265SDimitry Andric                                              uint64_t Address,
37581ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3760b57cec5SDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
37781ad6265SDimitry Andric                                              uint64_t Address,
37881ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3790b57cec5SDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
38081ad6265SDimitry Andric                                              uint64_t Address,
38181ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3820b57cec5SDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
38381ad6265SDimitry Andric                                              uint64_t Address,
38481ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3858bcb0991SDimitry Andric static DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst, unsigned Val,
38681ad6265SDimitry Andric                                                 uint64_t Address,
38781ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
3880b57cec5SDimitry Andric static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Val,
38981ad6265SDimitry Andric                                                uint64_t Address,
39081ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
3910b57cec5SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
39281ad6265SDimitry Andric                                              uint64_t Address,
39381ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3940b57cec5SDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
39581ad6265SDimitry Andric                                              uint64_t Address,
39681ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
3970b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
39881ad6265SDimitry Andric                                          uint64_t Address,
39981ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
4000b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
40181ad6265SDimitry Andric                                           uint64_t Address,
40281ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
4030b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
40481ad6265SDimitry Andric                                           uint64_t Address,
40581ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
4060b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
40781ad6265SDimitry Andric                                           uint64_t Address,
40881ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
4090b57cec5SDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
41081ad6265SDimitry Andric                                          uint64_t Address,
41181ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
4120b57cec5SDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
41381ad6265SDimitry Andric                                      uint64_t Address,
41481ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
4150b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
41681ad6265SDimitry Andric                                         uint64_t Address,
41781ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
4180b57cec5SDimitry Andric template <int shift>
4190b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
4200b57cec5SDimitry Andric                                        uint64_t Address,
42181ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
42281ad6265SDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
42381ad6265SDimitry Andric                                       uint64_t Address,
42481ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
42581ad6265SDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
42681ad6265SDimitry Andric                                            uint64_t Address,
42781ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
42881ad6265SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
42981ad6265SDimitry Andric                                                 uint64_t Address,
43081ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
43181ad6265SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, uint64_t Address,
43281ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
43381ad6265SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
43481ad6265SDimitry Andric                                     uint64_t Address,
43581ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
43681ad6265SDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
43781ad6265SDimitry Andric                                         uint64_t Address,
43881ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
43981ad6265SDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
44081ad6265SDimitry Andric                                          uint64_t Address,
44181ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
44281ad6265SDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
44381ad6265SDimitry Andric                                     uint64_t Address,
44481ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
44581ad6265SDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
44681ad6265SDimitry Andric                                     uint64_t Address,
44781ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
44881ad6265SDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
44981ad6265SDimitry Andric                                     uint64_t Address,
45081ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
45181ad6265SDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
45281ad6265SDimitry Andric                                     uint64_t Address,
45381ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
45481ad6265SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
45581ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
45681ad6265SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
45781ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
45881ad6265SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
45981ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
46081ad6265SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
46181ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
46281ad6265SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
46381ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
46481ad6265SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
46581ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
46681ad6265SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
46781ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
46881ad6265SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
46981ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
47081ad6265SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, uint64_t Address,
47181ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
47281ad6265SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, uint64_t Address,
47381ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
47481ad6265SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, uint64_t Address,
47581ad6265SDimitry Andric                                const MCDisassembler *Decoder);
47681ad6265SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, uint64_t Address,
47781ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
47881ad6265SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, uint64_t Address,
47981ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
48081ad6265SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Insn,
48181ad6265SDimitry Andric                                          uint64_t Address,
48281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
48381ad6265SDimitry Andric static DecodeStatus
48481ad6265SDimitry Andric DecodeNEONComplexLane64Instruction(MCInst &Inst, unsigned Val, uint64_t Address,
48581ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
48881ad6265SDimitry Andric                                              uint64_t Address,
48981ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
4900b57cec5SDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
49181ad6265SDimitry Andric                                          uint64_t Address,
49281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
4930b57cec5SDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
49481ad6265SDimitry Andric                                       uint64_t Address,
49581ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
4960b57cec5SDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
49781ad6265SDimitry Andric                                             uint64_t Address,
49881ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
4990b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
50081ad6265SDimitry Andric                                           uint64_t Address,
50181ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5020b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
50381ad6265SDimitry Andric                                           uint64_t Address,
50481ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5050b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
50681ad6265SDimitry Andric                                           uint64_t Address,
50781ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5080b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
50981ad6265SDimitry Andric                                           uint64_t Address,
51081ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5110b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
51281ad6265SDimitry Andric                                           uint64_t Address,
51381ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5140b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
51581ad6265SDimitry Andric                                       uint64_t Address,
51681ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
5170b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
51881ad6265SDimitry Andric                                      uint64_t Address,
51981ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
5200b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
52181ad6265SDimitry Andric                                       uint64_t Address,
52281ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
52381ad6265SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, uint64_t Address,
52481ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
5250b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
52681ad6265SDimitry Andric                                       uint64_t Address,
52781ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
52881ad6265SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, uint64_t Address,
52981ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
53081ad6265SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
53181ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
5320b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
53381ad6265SDimitry Andric                                            uint64_t Address,
53481ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
5350b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
5360b57cec5SDimitry Andric                                            uint64_t Address,
53781ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
5380b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst, unsigned Val,
53981ad6265SDimitry Andric                                                 uint64_t Address,
54081ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
54181ad6265SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
54281ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
5430b57cec5SDimitry Andric template <int shift>
54481ad6265SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, uint64_t Address,
54581ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
5460b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
54781ad6265SDimitry Andric                                          uint64_t Address,
54881ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
5490b57cec5SDimitry Andric template <int shift>
5500b57cec5SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
55181ad6265SDimitry Andric                                         uint64_t Address,
55281ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
5530b57cec5SDimitry Andric template <int shift, int WriteBack>
5540b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
55581ad6265SDimitry Andric                                          uint64_t Address,
55681ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
5570b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
55881ad6265SDimitry Andric                                         uint64_t Address,
55981ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
5600b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
56181ad6265SDimitry Andric                                         uint64_t Address,
56281ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
5630b57cec5SDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
56481ad6265SDimitry Andric                                    uint64_t Address,
56581ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
5660b57cec5SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
56781ad6265SDimitry Andric                                           uint64_t Address,
56881ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5690b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
57081ad6265SDimitry Andric                                          uint64_t Address,
57181ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
5720b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
57381ad6265SDimitry Andric                                           uint64_t Address,
57481ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
5750b57cec5SDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
57681ad6265SDimitry Andric                                            uint64_t Address,
57781ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
5780b57cec5SDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
57981ad6265SDimitry Andric                                                uint64_t Address,
58081ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
58181ad6265SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, uint64_t Address,
58281ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
5830b57cec5SDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
58481ad6265SDimitry Andric                                                 uint64_t Address,
58581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
5860b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
58781ad6265SDimitry Andric                                                uint64_t Address,
58881ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
58981ad6265SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, uint64_t Address,
59081ad6265SDimitry Andric                              const MCDisassembler *Decoder);
5910b57cec5SDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
59281ad6265SDimitry Andric                                                uint64_t Address,
59381ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
5940b57cec5SDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
59581ad6265SDimitry Andric                                                uint64_t Address,
59681ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
59781ad6265SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, uint64_t Address,
59881ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
5990b57cec5SDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
60081ad6265SDimitry Andric                                     uint64_t Address,
60181ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
6020b57cec5SDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
60381ad6265SDimitry Andric                                               uint64_t Address,
60481ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
6050b57cec5SDimitry Andric 
60681ad6265SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address,
60781ad6265SDimitry Andric                               const MCDisassembler *Decoder);
6080b57cec5SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
60981ad6265SDimitry Andric                                             uint64_t Address,
61081ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
6110b57cec5SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
61281ad6265SDimitry Andric                                          uint64_t Address,
61381ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
6160b57cec5SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned val,
61781ad6265SDimitry Andric                                          uint64_t Address,
61881ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
6190b57cec5SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned val,
6200b57cec5SDimitry Andric                                                uint64_t Address,
62181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
6220b57cec5SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
6230b57cec5SDimitry Andric                                           uint64_t Address,
62481ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
6250b57cec5SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
62681ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
6270b57cec5SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
6280b57cec5SDimitry Andric                                            uint64_t Address,
62981ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
6300b57cec5SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
63181ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
6320b57cec5SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
63381ad6265SDimitry Andric                                          uint64_t Address,
63481ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
6350b57cec5SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val,
6360b57cec5SDimitry Andric                                         uint64_t Address,
63781ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
638bdd1243dSDimitry Andric static DecodeStatus DecodeVpredNOperand(MCInst &Inst, unsigned Val,
639bdd1243dSDimitry Andric                                         uint64_t Address,
640bdd1243dSDimitry Andric                                         const MCDisassembler *Decoder);
64181ad6265SDimitry Andric static DecodeStatus
64281ad6265SDimitry Andric DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
64381ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
64481ad6265SDimitry Andric static DecodeStatus
64581ad6265SDimitry Andric DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
64681ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
64781ad6265SDimitry Andric static DecodeStatus
64881ad6265SDimitry Andric DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
64981ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
65081ad6265SDimitry Andric static DecodeStatus
65181ad6265SDimitry Andric DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
65281ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
6530b57cec5SDimitry Andric template <bool Writeback>
6540b57cec5SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn,
6550b57cec5SDimitry Andric                                           uint64_t Address,
65681ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
6570b57cec5SDimitry Andric template <int shift>
6580b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
65981ad6265SDimitry Andric                                         uint64_t Address,
66081ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
6610b57cec5SDimitry Andric template <int shift>
6620b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
66381ad6265SDimitry Andric                                         uint64_t Address,
66481ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
6650b57cec5SDimitry Andric template <int shift>
6660b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
66781ad6265SDimitry Andric                                         uint64_t Address,
66881ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
6690b57cec5SDimitry Andric template <unsigned MinLog, unsigned MaxLog>
6700b57cec5SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
6710b57cec5SDimitry Andric                                           uint64_t Address,
67281ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
6730b57cec5SDimitry Andric template <unsigned start>
67481ad6265SDimitry Andric static DecodeStatus
67581ad6265SDimitry Andric DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, uint64_t Address,
67681ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
6770b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
6780b57cec5SDimitry Andric                                          uint64_t Address,
67981ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
6800b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
6810b57cec5SDimitry Andric                                          uint64_t Address,
68281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
6830b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
6840b57cec5SDimitry Andric                                       uint64_t Address,
68581ad6265SDimitry Andric                                       const MCDisassembler *Decoder);
68681ad6265SDimitry Andric typedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val,
68781ad6265SDimitry Andric                                     uint64_t Address,
68881ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
68981ad6265SDimitry Andric template <bool scalar, OperandDecoder predicate_decoder>
69081ad6265SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
69181ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
69281ad6265SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
69381ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
69481ad6265SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
69581ad6265SDimitry Andric                                    uint64_t Address,
69681ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
69781ad6265SDimitry Andric static DecodeStatus
69881ad6265SDimitry Andric DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, uint64_t Address,
69981ad6265SDimitry Andric                               const MCDisassembler *Decoder);
700480093f4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
70181ad6265SDimitry Andric                                         uint64_t Address,
70281ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
703480093f4SDimitry Andric 
7040b57cec5SDimitry Andric #include "ARMGenDisassemblerTables.inc"
7050b57cec5SDimitry Andric 
createARMDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)7060b57cec5SDimitry Andric static MCDisassembler *createARMDisassembler(const Target &T,
7070b57cec5SDimitry Andric                                              const MCSubtargetInfo &STI,
7080b57cec5SDimitry Andric                                              MCContext &Ctx) {
709bdd1243dSDimitry Andric   return new ARMDisassembler(STI, Ctx, T.createMCInstrInfo());
7100b57cec5SDimitry Andric }
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric // Post-decoding checks
checkDecodedInstruction(MCInst & MI,uint64_t & Size,uint64_t Address,raw_ostream & CS,uint32_t Insn,DecodeStatus Result)7130b57cec5SDimitry Andric static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
714480093f4SDimitry Andric                                             uint64_t Address, raw_ostream &CS,
7150b57cec5SDimitry Andric                                             uint32_t Insn,
7160b57cec5SDimitry Andric                                             DecodeStatus Result) {
7170b57cec5SDimitry Andric   switch (MI.getOpcode()) {
7180b57cec5SDimitry Andric     case ARM::HVC: {
7190b57cec5SDimitry Andric       // HVC is undefined if condition = 0xf otherwise upredictable
7200b57cec5SDimitry Andric       // if condition != 0xe
7210b57cec5SDimitry Andric       uint32_t Cond = (Insn >> 28) & 0xF;
7220b57cec5SDimitry Andric       if (Cond == 0xF)
7230b57cec5SDimitry Andric         return MCDisassembler::Fail;
7240b57cec5SDimitry Andric       if (Cond != 0xE)
7250b57cec5SDimitry Andric         return MCDisassembler::SoftFail;
7260b57cec5SDimitry Andric       return Result;
7270b57cec5SDimitry Andric     }
7280b57cec5SDimitry Andric     case ARM::t2ADDri:
7290b57cec5SDimitry Andric     case ARM::t2ADDri12:
7300b57cec5SDimitry Andric     case ARM::t2ADDrr:
7310b57cec5SDimitry Andric     case ARM::t2ADDrs:
7320b57cec5SDimitry Andric     case ARM::t2SUBri:
7330b57cec5SDimitry Andric     case ARM::t2SUBri12:
7340b57cec5SDimitry Andric     case ARM::t2SUBrr:
7350b57cec5SDimitry Andric     case ARM::t2SUBrs:
7360b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == ARM::SP &&
7370b57cec5SDimitry Andric           MI.getOperand(1).getReg() != ARM::SP)
7380b57cec5SDimitry Andric         return MCDisassembler::SoftFail;
7390b57cec5SDimitry Andric       return Result;
7400b57cec5SDimitry Andric     default: return Result;
7410b57cec5SDimitry Andric   }
7420b57cec5SDimitry Andric }
7430b57cec5SDimitry Andric 
suggestBytesToSkip(ArrayRef<uint8_t> Bytes,uint64_t Address) const744972a253aSDimitry Andric uint64_t ARMDisassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
745972a253aSDimitry Andric                                              uint64_t Address) const {
746972a253aSDimitry Andric   // In Arm state, instructions are always 4 bytes wide, so there's no
747972a253aSDimitry Andric   // point in skipping any smaller number of bytes if an instruction
748972a253aSDimitry Andric   // can't be decoded.
749fe013be4SDimitry Andric   if (!STI.hasFeature(ARM::ModeThumb))
750972a253aSDimitry Andric     return 4;
751972a253aSDimitry Andric 
752972a253aSDimitry Andric   // In a Thumb instruction stream, a halfword is a standalone 2-byte
753972a253aSDimitry Andric   // instruction if and only if its value is less than 0xE800.
754972a253aSDimitry Andric   // Otherwise, it's the first halfword of a 4-byte instruction.
755972a253aSDimitry Andric   //
756972a253aSDimitry Andric   // So, if we can see the upcoming halfword, we can judge on that
757972a253aSDimitry Andric   // basis, and maybe skip a whole 4-byte instruction that we don't
758972a253aSDimitry Andric   // know how to decode, without accidentally trying to interpret its
759972a253aSDimitry Andric   // second half as something else.
760972a253aSDimitry Andric   //
761972a253aSDimitry Andric   // If we don't have the instruction data available, we just have to
762972a253aSDimitry Andric   // recommend skipping the minimum sensible distance, which is 2
763972a253aSDimitry Andric   // bytes.
764972a253aSDimitry Andric   if (Bytes.size() < 2)
765972a253aSDimitry Andric     return 2;
766972a253aSDimitry Andric 
767bdd1243dSDimitry Andric   uint16_t Insn16 = llvm::support::endian::read<uint16_t>(
768bdd1243dSDimitry Andric       Bytes.data(), InstructionEndianness);
769972a253aSDimitry Andric   return Insn16 < 0xE800 ? 2 : 4;
770972a253aSDimitry Andric }
771972a253aSDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const7720b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
7730b57cec5SDimitry Andric                                              ArrayRef<uint8_t> Bytes,
774480093f4SDimitry Andric                                              uint64_t Address,
7750b57cec5SDimitry Andric                                              raw_ostream &CS) const {
776fe013be4SDimitry Andric   if (STI.hasFeature(ARM::ModeThumb))
777480093f4SDimitry Andric     return getThumbInstruction(MI, Size, Bytes, Address, CS);
778480093f4SDimitry Andric   return getARMInstruction(MI, Size, Bytes, Address, CS);
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric 
getARMInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const7810b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
7820b57cec5SDimitry Andric                                                 ArrayRef<uint8_t> Bytes,
7830b57cec5SDimitry Andric                                                 uint64_t Address,
7840b57cec5SDimitry Andric                                                 raw_ostream &CS) const {
7850b57cec5SDimitry Andric   CommentStream = &CS;
7860b57cec5SDimitry Andric 
787fe013be4SDimitry Andric   assert(!STI.hasFeature(ARM::ModeThumb) &&
7880b57cec5SDimitry Andric          "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
7890b57cec5SDimitry Andric          "mode!");
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
7920b57cec5SDimitry Andric   if (Bytes.size() < 4) {
7930b57cec5SDimitry Andric     Size = 0;
7940b57cec5SDimitry Andric     return MCDisassembler::Fail;
7950b57cec5SDimitry Andric   }
7960b57cec5SDimitry Andric 
797bdd1243dSDimitry Andric   // Encoded as a 32-bit word in the stream.
798bdd1243dSDimitry Andric   uint32_t Insn = llvm::support::endian::read<uint32_t>(Bytes.data(),
799bdd1243dSDimitry Andric                                                         InstructionEndianness);
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   // Calling the auto-generated decoder function.
8020b57cec5SDimitry Andric   DecodeStatus Result =
8030b57cec5SDimitry Andric       decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
8040b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
8050b57cec5SDimitry Andric     Size = 4;
806480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
8070b57cec5SDimitry Andric   }
8080b57cec5SDimitry Andric 
8090b57cec5SDimitry Andric   struct DecodeTable {
8100b57cec5SDimitry Andric     const uint8_t *P;
8110b57cec5SDimitry Andric     bool DecodePred;
8120b57cec5SDimitry Andric   };
8130b57cec5SDimitry Andric 
8140b57cec5SDimitry Andric   const DecodeTable Tables[] = {
8150b57cec5SDimitry Andric       {DecoderTableVFP32, false},      {DecoderTableVFPV832, false},
8160b57cec5SDimitry Andric       {DecoderTableNEONData32, true},  {DecoderTableNEONLoadStore32, true},
8170b57cec5SDimitry Andric       {DecoderTableNEONDup32, true},   {DecoderTablev8NEON32, false},
8180b57cec5SDimitry Andric       {DecoderTablev8Crypto32, false},
8190b57cec5SDimitry Andric   };
8200b57cec5SDimitry Andric 
8210b57cec5SDimitry Andric   for (auto Table : Tables) {
8220b57cec5SDimitry Andric     Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
8230b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
8240b57cec5SDimitry Andric       Size = 4;
8250b57cec5SDimitry Andric       // Add a fake predicate operand, because we share these instruction
8260b57cec5SDimitry Andric       // definitions with Thumb2 where these instructions are predicable.
8270b57cec5SDimitry Andric       if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
8280b57cec5SDimitry Andric         return MCDisassembler::Fail;
8290b57cec5SDimitry Andric       return Result;
8300b57cec5SDimitry Andric     }
8310b57cec5SDimitry Andric   }
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric   Result =
8340b57cec5SDimitry Andric       decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
8350b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
8360b57cec5SDimitry Andric     Size = 4;
837480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
8380b57cec5SDimitry Andric   }
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric   Size = 4;
8410b57cec5SDimitry Andric   return MCDisassembler::Fail;
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
8450b57cec5SDimitry Andric /// immediate Value in the MCInst.  The immediate Value has had any PC
8460b57cec5SDimitry Andric /// adjustment made by the caller.  If the instruction is a branch instruction
8470b57cec5SDimitry Andric /// then isBranch is true, else false.  If the getOpInfo() function was set as
8480b57cec5SDimitry Andric /// part of the setupForSymbolicDisassembly() call then that function is called
8490b57cec5SDimitry Andric /// to get any symbolic information at the Address for this instruction.  If
8500b57cec5SDimitry Andric /// that returns non-zero then the symbolic information it returns is used to
8510b57cec5SDimitry Andric /// create an MCExpr and that is added as an operand to the MCInst.  If
8520b57cec5SDimitry Andric /// getOpInfo() returns zero and isBranch is true then a symbol look up for
8530b57cec5SDimitry Andric /// Value is done and if a symbol is found an MCExpr is created with that, else
8540b57cec5SDimitry Andric /// an MCExpr with Value is created.  This function returns true if it adds an
8550b57cec5SDimitry Andric /// operand to the MCInst and false otherwise.
tryAddingSymbolicOperand(uint64_t Address,int32_t Value,bool isBranch,uint64_t InstSize,MCInst & MI,const MCDisassembler * Decoder)8560b57cec5SDimitry Andric static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
8570b57cec5SDimitry Andric                                      bool isBranch, uint64_t InstSize,
85881ad6265SDimitry Andric                                      MCInst &MI,
85981ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
8600b57cec5SDimitry Andric   // FIXME: Does it make sense for value to be negative?
86181ad6265SDimitry Andric   return Decoder->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address,
86281ad6265SDimitry Andric                                            isBranch, /*Offset=*/0, /*OpSize=*/0,
86381ad6265SDimitry Andric                                            InstSize);
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
8670b57cec5SDimitry Andric /// referenced by a load instruction with the base register that is the Pc.
8680b57cec5SDimitry Andric /// These can often be values in a literal pool near the Address of the
8690b57cec5SDimitry Andric /// instruction.  The Address of the instruction and its immediate Value are
8700b57cec5SDimitry Andric /// used as a possible literal pool entry.  The SymbolLookUp call back will
8710b57cec5SDimitry Andric /// return the name of a symbol referenced by the literal pool's entry if
8720b57cec5SDimitry Andric /// the referenced address is that of a symbol.  Or it will return a pointer to
8730b57cec5SDimitry Andric /// a literal 'C' string if the referenced address of the literal pool's entry
8740b57cec5SDimitry Andric /// is an address into a section with 'C' string literals.
tryAddingPcLoadReferenceComment(uint64_t Address,int Value,const MCDisassembler * Decoder)8750b57cec5SDimitry Andric static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
87681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
8770b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
8780b57cec5SDimitry Andric   Dis->tryAddingPcLoadReferenceComment(Value, Address);
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric // Thumb1 instructions don't have explicit S bits.  Rather, they
8820b57cec5SDimitry Andric // implicitly set CPSR.  Since it's not represented in the encoding, the
8830b57cec5SDimitry Andric // auto-generated decoder won't inject the CPSR operand.  We need to fix
8840b57cec5SDimitry Andric // that as a post-pass.
AddThumb1SBit(MCInst & MI,bool InITBlock) const885bdd1243dSDimitry Andric void ARMDisassembler::AddThumb1SBit(MCInst &MI, bool InITBlock) const {
886bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
8870b57cec5SDimitry Andric   MCInst::iterator I = MI.begin();
888bdd1243dSDimitry Andric   for (unsigned i = 0; i < MCID.NumOperands; ++i, ++I) {
8890b57cec5SDimitry Andric     if (I == MI.end()) break;
890bdd1243dSDimitry Andric     if (MCID.operands()[i].isOptionalDef() &&
891bdd1243dSDimitry Andric         MCID.operands()[i].RegClass == ARM::CCRRegClassID) {
892bdd1243dSDimitry Andric       if (i > 0 && MCID.operands()[i - 1].isPredicate())
893bdd1243dSDimitry Andric         continue;
8940b57cec5SDimitry Andric       MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
8950b57cec5SDimitry Andric       return;
8960b57cec5SDimitry Andric     }
8970b57cec5SDimitry Andric   }
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric   MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
9000b57cec5SDimitry Andric }
9010b57cec5SDimitry Andric 
isVectorPredicable(const MCInst & MI) const902bdd1243dSDimitry Andric bool ARMDisassembler::isVectorPredicable(const MCInst &MI) const {
903bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
904bdd1243dSDimitry Andric   for (unsigned i = 0; i < MCID.NumOperands; ++i) {
905bdd1243dSDimitry Andric     if (ARM::isVpred(MCID.operands()[i].OperandType))
9060b57cec5SDimitry Andric       return true;
9070b57cec5SDimitry Andric   }
9080b57cec5SDimitry Andric   return false;
9090b57cec5SDimitry Andric }
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric // Most Thumb instructions don't have explicit predicates in the
9120b57cec5SDimitry Andric // encoding, but rather get their predicates from IT context.  We need
9130b57cec5SDimitry Andric // to fix up the predicate operands using this context information as a
9140b57cec5SDimitry Andric // post-pass.
9150b57cec5SDimitry Andric MCDisassembler::DecodeStatus
AddThumbPredicate(MCInst & MI) const9160b57cec5SDimitry Andric ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
9170b57cec5SDimitry Andric   MCDisassembler::DecodeStatus S = Success;
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric   // A few instructions actually have predicates encoded in them.  Don't
9220b57cec5SDimitry Andric   // try to overwrite it if we're seeing one of those.
9230b57cec5SDimitry Andric   switch (MI.getOpcode()) {
9240b57cec5SDimitry Andric     case ARM::tBcc:
9250b57cec5SDimitry Andric     case ARM::t2Bcc:
9260b57cec5SDimitry Andric     case ARM::tCBZ:
9270b57cec5SDimitry Andric     case ARM::tCBNZ:
9280b57cec5SDimitry Andric     case ARM::tCPS:
9290b57cec5SDimitry Andric     case ARM::t2CPS3p:
9300b57cec5SDimitry Andric     case ARM::t2CPS2p:
9310b57cec5SDimitry Andric     case ARM::t2CPS1p:
9320b57cec5SDimitry Andric     case ARM::t2CSEL:
9330b57cec5SDimitry Andric     case ARM::t2CSINC:
9340b57cec5SDimitry Andric     case ARM::t2CSINV:
9350b57cec5SDimitry Andric     case ARM::t2CSNEG:
9360b57cec5SDimitry Andric     case ARM::tMOVSr:
9370b57cec5SDimitry Andric     case ARM::tSETEND:
9380b57cec5SDimitry Andric       // Some instructions (mostly conditional branches) are not
9390b57cec5SDimitry Andric       // allowed in IT blocks.
9400b57cec5SDimitry Andric       if (ITBlock.instrInITBlock())
9410b57cec5SDimitry Andric         S = SoftFail;
9420b57cec5SDimitry Andric       else
9430b57cec5SDimitry Andric         return Success;
9440b57cec5SDimitry Andric       break;
9450b57cec5SDimitry Andric     case ARM::t2HINT:
9460b57cec5SDimitry Andric       if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
9470b57cec5SDimitry Andric         S = SoftFail;
9480b57cec5SDimitry Andric       break;
9490b57cec5SDimitry Andric     case ARM::tB:
9500b57cec5SDimitry Andric     case ARM::t2B:
9510b57cec5SDimitry Andric     case ARM::t2TBB:
9520b57cec5SDimitry Andric     case ARM::t2TBH:
9530b57cec5SDimitry Andric       // Some instructions (mostly unconditional branches) can
9540b57cec5SDimitry Andric       // only appears at the end of, or outside of, an IT.
9550b57cec5SDimitry Andric       if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
9560b57cec5SDimitry Andric         S = SoftFail;
9570b57cec5SDimitry Andric       break;
9580b57cec5SDimitry Andric     default:
9590b57cec5SDimitry Andric       break;
9600b57cec5SDimitry Andric   }
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   // Warn on non-VPT predicable instruction in a VPT block and a VPT
9630b57cec5SDimitry Andric   // predicable instruction in an IT block
964bdd1243dSDimitry Andric   if ((!isVectorPredicable(MI) && VPTBlock.instrInVPTBlock()) ||
965bdd1243dSDimitry Andric       (isVectorPredicable(MI) && ITBlock.instrInITBlock()))
9660b57cec5SDimitry Andric     S = SoftFail;
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   // If we're in an IT/VPT block, base the predicate on that.  Otherwise,
9690b57cec5SDimitry Andric   // assume a predicate of AL.
9700b57cec5SDimitry Andric   unsigned CC = ARMCC::AL;
9710b57cec5SDimitry Andric   unsigned VCC = ARMVCC::None;
9720b57cec5SDimitry Andric   if (ITBlock.instrInITBlock()) {
9730b57cec5SDimitry Andric     CC = ITBlock.getITCC();
9740b57cec5SDimitry Andric     ITBlock.advanceITState();
9750b57cec5SDimitry Andric   } else if (VPTBlock.instrInVPTBlock()) {
9760b57cec5SDimitry Andric     VCC = VPTBlock.getVPTPred();
9770b57cec5SDimitry Andric     VPTBlock.advanceVPTState();
9780b57cec5SDimitry Andric   }
9790b57cec5SDimitry Andric 
980bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric   MCInst::iterator CCI = MI.begin();
983bdd1243dSDimitry Andric   for (unsigned i = 0; i < MCID.NumOperands; ++i, ++CCI) {
984bdd1243dSDimitry Andric     if (MCID.operands()[i].isPredicate() || CCI == MI.end())
985bdd1243dSDimitry Andric       break;
9860b57cec5SDimitry Andric   }
9870b57cec5SDimitry Andric 
988bdd1243dSDimitry Andric   if (MCID.isPredicable()) {
9890b57cec5SDimitry Andric     CCI = MI.insert(CCI, MCOperand::createImm(CC));
9900b57cec5SDimitry Andric     ++CCI;
9910b57cec5SDimitry Andric     if (CC == ARMCC::AL)
9920b57cec5SDimitry Andric       MI.insert(CCI, MCOperand::createReg(0));
9930b57cec5SDimitry Andric     else
9940b57cec5SDimitry Andric       MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
9950b57cec5SDimitry Andric   } else if (CC != ARMCC::AL) {
9960b57cec5SDimitry Andric     Check(S, SoftFail);
9970b57cec5SDimitry Andric   }
9980b57cec5SDimitry Andric 
9990b57cec5SDimitry Andric   MCInst::iterator VCCI = MI.begin();
10000b57cec5SDimitry Andric   unsigned VCCPos;
1001bdd1243dSDimitry Andric   for (VCCPos = 0; VCCPos < MCID.NumOperands; ++VCCPos, ++VCCI) {
1002bdd1243dSDimitry Andric     if (ARM::isVpred(MCID.operands()[VCCPos].OperandType) || VCCI == MI.end())
1003bdd1243dSDimitry Andric       break;
10040b57cec5SDimitry Andric   }
10050b57cec5SDimitry Andric 
1006bdd1243dSDimitry Andric   if (isVectorPredicable(MI)) {
10070b57cec5SDimitry Andric     VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
10080b57cec5SDimitry Andric     ++VCCI;
10090b57cec5SDimitry Andric     if (VCC == ARMVCC::None)
1010349cc55cSDimitry Andric       VCCI = MI.insert(VCCI, MCOperand::createReg(0));
10110b57cec5SDimitry Andric     else
1012349cc55cSDimitry Andric       VCCI = MI.insert(VCCI, MCOperand::createReg(ARM::P0));
1013349cc55cSDimitry Andric     ++VCCI;
1014349cc55cSDimitry Andric     VCCI = MI.insert(VCCI, MCOperand::createReg(0));
1015349cc55cSDimitry Andric     ++VCCI;
1016bdd1243dSDimitry Andric     if (MCID.operands()[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
1017bdd1243dSDimitry Andric       int TiedOp = MCID.getOperandConstraint(VCCPos + 3, MCOI::TIED_TO);
10180b57cec5SDimitry Andric       assert(TiedOp >= 0 &&
10190b57cec5SDimitry Andric              "Inactive register in vpred_r is not tied to an output!");
1020e8d8bef9SDimitry Andric       // Copy the operand to ensure it's not invalidated when MI grows.
1021e8d8bef9SDimitry Andric       MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
10220b57cec5SDimitry Andric     }
10230b57cec5SDimitry Andric   } else if (VCC != ARMVCC::None) {
10240b57cec5SDimitry Andric     Check(S, SoftFail);
10250b57cec5SDimitry Andric   }
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric   return S;
10280b57cec5SDimitry Andric }
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric // Thumb VFP instructions are a special case.  Because we share their
10310b57cec5SDimitry Andric // encodings between ARM and Thumb modes, and they are predicable in ARM
10320b57cec5SDimitry Andric // mode, the auto-generated decoder will give them an (incorrect)
10330b57cec5SDimitry Andric // predicate operand.  We need to rewrite these operands based on the IT
10340b57cec5SDimitry Andric // context as a post-pass.
UpdateThumbVFPPredicate(DecodeStatus & S,MCInst & MI) const10350b57cec5SDimitry Andric void ARMDisassembler::UpdateThumbVFPPredicate(
10360b57cec5SDimitry Andric   DecodeStatus &S, MCInst &MI) const {
10370b57cec5SDimitry Andric   unsigned CC;
10380b57cec5SDimitry Andric   CC = ITBlock.getITCC();
10390b57cec5SDimitry Andric   if (CC == 0xF)
10400b57cec5SDimitry Andric     CC = ARMCC::AL;
10410b57cec5SDimitry Andric   if (ITBlock.instrInITBlock())
10420b57cec5SDimitry Andric     ITBlock.advanceITState();
10430b57cec5SDimitry Andric   else if (VPTBlock.instrInVPTBlock()) {
10440b57cec5SDimitry Andric     CC = VPTBlock.getVPTPred();
10450b57cec5SDimitry Andric     VPTBlock.advanceVPTState();
10460b57cec5SDimitry Andric   }
10470b57cec5SDimitry Andric 
1048bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
1049bdd1243dSDimitry Andric   ArrayRef<MCOperandInfo> OpInfo = MCID.operands();
10500b57cec5SDimitry Andric   MCInst::iterator I = MI.begin();
1051bdd1243dSDimitry Andric   unsigned short NumOps = MCID.NumOperands;
10520b57cec5SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
10530b57cec5SDimitry Andric     if (OpInfo[i].isPredicate() ) {
1054bdd1243dSDimitry Andric       if (CC != ARMCC::AL && !MCID.isPredicable())
10550b57cec5SDimitry Andric         Check(S, SoftFail);
10560b57cec5SDimitry Andric       I->setImm(CC);
10570b57cec5SDimitry Andric       ++I;
10580b57cec5SDimitry Andric       if (CC == ARMCC::AL)
10590b57cec5SDimitry Andric         I->setReg(0);
10600b57cec5SDimitry Andric       else
10610b57cec5SDimitry Andric         I->setReg(ARM::CPSR);
10620b57cec5SDimitry Andric       return;
10630b57cec5SDimitry Andric     }
10640b57cec5SDimitry Andric   }
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric 
getThumbInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const10670b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
10680b57cec5SDimitry Andric                                                   ArrayRef<uint8_t> Bytes,
10690b57cec5SDimitry Andric                                                   uint64_t Address,
10700b57cec5SDimitry Andric                                                   raw_ostream &CS) const {
10710b57cec5SDimitry Andric   CommentStream = &CS;
10720b57cec5SDimitry Andric 
1073fe013be4SDimitry Andric   assert(STI.hasFeature(ARM::ModeThumb) &&
10740b57cec5SDimitry Andric          "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   // We want to read exactly 2 bytes of data.
10770b57cec5SDimitry Andric   if (Bytes.size() < 2) {
10780b57cec5SDimitry Andric     Size = 0;
10790b57cec5SDimitry Andric     return MCDisassembler::Fail;
10800b57cec5SDimitry Andric   }
10810b57cec5SDimitry Andric 
1082bdd1243dSDimitry Andric   uint16_t Insn16 = llvm::support::endian::read<uint16_t>(
1083bdd1243dSDimitry Andric       Bytes.data(), InstructionEndianness);
10840b57cec5SDimitry Andric   DecodeStatus Result =
10850b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
10860b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
10870b57cec5SDimitry Andric     Size = 2;
10880b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
10890b57cec5SDimitry Andric     return Result;
10900b57cec5SDimitry Andric   }
10910b57cec5SDimitry Andric 
10920b57cec5SDimitry Andric   Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
10930b57cec5SDimitry Andric                              STI);
10940b57cec5SDimitry Andric   if (Result) {
10950b57cec5SDimitry Andric     Size = 2;
10960b57cec5SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
10970b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
10980b57cec5SDimitry Andric     AddThumb1SBit(MI, InITBlock);
10990b57cec5SDimitry Andric     return Result;
11000b57cec5SDimitry Andric   }
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric   Result =
11030b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
11040b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11050b57cec5SDimitry Andric     Size = 2;
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric     // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
11080b57cec5SDimitry Andric     // the Thumb predicate.
11090b57cec5SDimitry Andric     if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
11100b57cec5SDimitry Andric       Result = MCDisassembler::SoftFail;
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric     // If we find an IT instruction, we need to parse its condition
11150b57cec5SDimitry Andric     // code and mask operands so that we can apply them correctly
11160b57cec5SDimitry Andric     // to the subsequent instructions.
11170b57cec5SDimitry Andric     if (MI.getOpcode() == ARM::t2IT) {
11180b57cec5SDimitry Andric       unsigned Firstcond = MI.getOperand(0).getImm();
11190b57cec5SDimitry Andric       unsigned Mask = MI.getOperand(1).getImm();
11200b57cec5SDimitry Andric       ITBlock.setITState(Firstcond, Mask);
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric       // An IT instruction that would give a 'NV' predicate is unpredictable.
11230b57cec5SDimitry Andric       if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
11240b57cec5SDimitry Andric         CS << "unpredictable IT predicate sequence";
11250b57cec5SDimitry Andric     }
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric     return Result;
11280b57cec5SDimitry Andric   }
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
11310b57cec5SDimitry Andric   if (Bytes.size() < 4) {
11320b57cec5SDimitry Andric     Size = 0;
11330b57cec5SDimitry Andric     return MCDisassembler::Fail;
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   uint32_t Insn32 =
1137bdd1243dSDimitry Andric       (uint32_t(Insn16) << 16) | llvm::support::endian::read<uint16_t>(
1138bdd1243dSDimitry Andric                                      Bytes.data() + 2, InstructionEndianness);
11390b57cec5SDimitry Andric 
11400b57cec5SDimitry Andric   Result =
11410b57cec5SDimitry Andric       decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI);
11420b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11430b57cec5SDimitry Andric     Size = 4;
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric     // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add
11460b57cec5SDimitry Andric     // the VPT predicate.
11470b57cec5SDimitry Andric     if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock())
11480b57cec5SDimitry Andric       Result = MCDisassembler::SoftFail;
11490b57cec5SDimitry Andric 
11500b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric     if (isVPTOpcode(MI.getOpcode())) {
11530b57cec5SDimitry Andric       unsigned Mask = MI.getOperand(0).getImm();
11540b57cec5SDimitry Andric       VPTBlock.setVPTState(Mask);
11550b57cec5SDimitry Andric     }
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric     return Result;
11580b57cec5SDimitry Andric   }
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric   Result =
11610b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
11620b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11630b57cec5SDimitry Andric     Size = 4;
11640b57cec5SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
11650b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11660b57cec5SDimitry Andric     AddThumb1SBit(MI, InITBlock);
11670b57cec5SDimitry Andric     return Result;
11680b57cec5SDimitry Andric   }
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric   Result =
11710b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
11720b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11730b57cec5SDimitry Andric     Size = 4;
11740b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
1175480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn32, Result);
11760b57cec5SDimitry Andric   }
11770b57cec5SDimitry Andric 
11780b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
11790b57cec5SDimitry Andric     Result =
11800b57cec5SDimitry Andric         decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
11810b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
11820b57cec5SDimitry Andric       Size = 4;
11830b57cec5SDimitry Andric       UpdateThumbVFPPredicate(Result, MI);
11840b57cec5SDimitry Andric       return Result;
11850b57cec5SDimitry Andric     }
11860b57cec5SDimitry Andric   }
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric   Result =
11890b57cec5SDimitry Andric       decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
11900b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11910b57cec5SDimitry Andric     Size = 4;
11920b57cec5SDimitry Andric     return Result;
11930b57cec5SDimitry Andric   }
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
11960b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
11970b57cec5SDimitry Andric                                STI);
11980b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
11990b57cec5SDimitry Andric       Size = 4;
12000b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
12010b57cec5SDimitry Andric       return Result;
12020b57cec5SDimitry Andric     }
12030b57cec5SDimitry Andric   }
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
12060b57cec5SDimitry Andric     uint32_t NEONLdStInsn = Insn32;
12070b57cec5SDimitry Andric     NEONLdStInsn &= 0xF0FFFFFF;
12080b57cec5SDimitry Andric     NEONLdStInsn |= 0x04000000;
12090b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
12100b57cec5SDimitry Andric                                Address, this, STI);
12110b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12120b57cec5SDimitry Andric       Size = 4;
12130b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
12140b57cec5SDimitry Andric       return Result;
12150b57cec5SDimitry Andric     }
12160b57cec5SDimitry Andric   }
12170b57cec5SDimitry Andric 
12180b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
12190b57cec5SDimitry Andric     uint32_t NEONDataInsn = Insn32;
12200b57cec5SDimitry Andric     NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
12210b57cec5SDimitry Andric     NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
12220b57cec5SDimitry Andric     NEONDataInsn |= 0x12000000; // Set bits 28 and 25
12230b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
12240b57cec5SDimitry Andric                                Address, this, STI);
12250b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12260b57cec5SDimitry Andric       Size = 4;
12270b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
12280b57cec5SDimitry Andric       return Result;
12290b57cec5SDimitry Andric     }
12300b57cec5SDimitry Andric 
12310b57cec5SDimitry Andric     uint32_t NEONCryptoInsn = Insn32;
12320b57cec5SDimitry Andric     NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
12330b57cec5SDimitry Andric     NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
12340b57cec5SDimitry Andric     NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
12350b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
12360b57cec5SDimitry Andric                                Address, this, STI);
12370b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12380b57cec5SDimitry Andric       Size = 4;
12390b57cec5SDimitry Andric       return Result;
12400b57cec5SDimitry Andric     }
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric     uint32_t NEONv8Insn = Insn32;
12430b57cec5SDimitry Andric     NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
12440b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
12450b57cec5SDimitry Andric                                this, STI);
12460b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12470b57cec5SDimitry Andric       Size = 4;
12480b57cec5SDimitry Andric       return Result;
12490b57cec5SDimitry Andric     }
12500b57cec5SDimitry Andric   }
12510b57cec5SDimitry Andric 
12525ffd83dbSDimitry Andric   uint32_t Coproc = fieldFromInstruction(Insn32, 8, 4);
12535ffd83dbSDimitry Andric   const uint8_t *DecoderTable = ARM::isCDECoproc(Coproc, STI)
12545ffd83dbSDimitry Andric                                     ? DecoderTableThumb2CDE32
12555ffd83dbSDimitry Andric                                     : DecoderTableThumb2CoProc32;
12560b57cec5SDimitry Andric   Result =
12575ffd83dbSDimitry Andric       decodeInstruction(DecoderTable, MI, Insn32, Address, this, STI);
12580b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
12590b57cec5SDimitry Andric     Size = 4;
12600b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
12610b57cec5SDimitry Andric     return Result;
12620b57cec5SDimitry Andric   }
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric   Size = 0;
12650b57cec5SDimitry Andric   return MCDisassembler::Fail;
12660b57cec5SDimitry Andric }
12670b57cec5SDimitry Andric 
LLVMInitializeARMDisassembler()1268480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMDisassembler() {
12690b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(),
12700b57cec5SDimitry Andric                                          createARMDisassembler);
12710b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(),
12720b57cec5SDimitry Andric                                          createARMDisassembler);
12730b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(),
12740b57cec5SDimitry Andric                                          createARMDisassembler);
12750b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(),
12760b57cec5SDimitry Andric                                          createARMDisassembler);
12770b57cec5SDimitry Andric }
12780b57cec5SDimitry Andric 
12790b57cec5SDimitry Andric static const uint16_t GPRDecoderTable[] = {
12800b57cec5SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
12810b57cec5SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
12820b57cec5SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
12830b57cec5SDimitry Andric   ARM::R12, ARM::SP, ARM::LR, ARM::PC
12840b57cec5SDimitry Andric };
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric static const uint16_t CLRMGPRDecoderTable[] = {
12870b57cec5SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
12880b57cec5SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
12890b57cec5SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
12900b57cec5SDimitry Andric   ARM::R12, 0, ARM::LR, ARM::APSR
12910b57cec5SDimitry Andric };
12920b57cec5SDimitry Andric 
DecodeGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)12930b57cec5SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
129481ad6265SDimitry Andric                                            uint64_t Address,
129581ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
12960b57cec5SDimitry Andric   if (RegNo > 15)
12970b57cec5SDimitry Andric     return MCDisassembler::Fail;
12980b57cec5SDimitry Andric 
12990b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
13000b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13010b57cec5SDimitry Andric   return MCDisassembler::Success;
13020b57cec5SDimitry Andric }
13030b57cec5SDimitry Andric 
DecodeCLRMGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13040b57cec5SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
13050b57cec5SDimitry Andric                                                uint64_t Address,
130681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13070b57cec5SDimitry Andric   if (RegNo > 15)
13080b57cec5SDimitry Andric     return MCDisassembler::Fail;
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric   unsigned Register = CLRMGPRDecoderTable[RegNo];
13110b57cec5SDimitry Andric   if (Register == 0)
13120b57cec5SDimitry Andric     return MCDisassembler::Fail;
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13150b57cec5SDimitry Andric   return MCDisassembler::Success;
13160b57cec5SDimitry Andric }
13170b57cec5SDimitry Andric 
DecodeGPRnopcRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)131881ad6265SDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
131981ad6265SDimitry Andric                                                uint64_t Address,
132081ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13210b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric   if (RegNo == 15)
13240b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric   return S;
13290b57cec5SDimitry Andric }
13300b57cec5SDimitry Andric 
DecodeGPRnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13314824e7fdSDimitry Andric static DecodeStatus DecodeGPRnospRegisterClass(MCInst &Inst, unsigned RegNo,
13324824e7fdSDimitry Andric                                                uint64_t Address,
133381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13344824e7fdSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13354824e7fdSDimitry Andric 
13364824e7fdSDimitry Andric   if (RegNo == 13)
13374824e7fdSDimitry Andric     S = MCDisassembler::SoftFail;
13384824e7fdSDimitry Andric 
13394824e7fdSDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13404824e7fdSDimitry Andric 
13414824e7fdSDimitry Andric   return S;
13424824e7fdSDimitry Andric }
13434824e7fdSDimitry Andric 
13440b57cec5SDimitry Andric static DecodeStatus
DecodeGPRwithAPSRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)134581ad6265SDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
134681ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
13470b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13480b57cec5SDimitry Andric 
13490b57cec5SDimitry Andric   if (RegNo == 15)
13500b57cec5SDimitry Andric   {
13510b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
13520b57cec5SDimitry Andric     return MCDisassembler::Success;
13530b57cec5SDimitry Andric   }
13540b57cec5SDimitry Andric 
13550b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13560b57cec5SDimitry Andric   return S;
13570b57cec5SDimitry Andric }
13580b57cec5SDimitry Andric 
13590b57cec5SDimitry Andric static DecodeStatus
DecodeGPRwithZRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)136081ad6265SDimitry Andric DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
136181ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
13620b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric   if (RegNo == 15)
13650b57cec5SDimitry Andric   {
13660b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::ZR));
13670b57cec5SDimitry Andric     return MCDisassembler::Success;
13680b57cec5SDimitry Andric   }
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric   if (RegNo == 13)
13710b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13740b57cec5SDimitry Andric   return S;
13750b57cec5SDimitry Andric }
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric static DecodeStatus
DecodeGPRwithZRnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)137881ad6265SDimitry Andric DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
137981ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
13800b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13810b57cec5SDimitry Andric   if (RegNo == 13)
13820b57cec5SDimitry Andric     return MCDisassembler::Fail;
13830b57cec5SDimitry Andric   Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder));
13840b57cec5SDimitry Andric   return S;
13850b57cec5SDimitry Andric }
13860b57cec5SDimitry Andric 
DecodetGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13870b57cec5SDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
138881ad6265SDimitry Andric                                             uint64_t Address,
138981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
13900b57cec5SDimitry Andric   if (RegNo > 7)
13910b57cec5SDimitry Andric     return MCDisassembler::Fail;
13920b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
13930b57cec5SDimitry Andric }
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
13960b57cec5SDimitry Andric   ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
13970b57cec5SDimitry Andric   ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
13980b57cec5SDimitry Andric };
13990b57cec5SDimitry Andric 
DecodeGPRPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14000b57cec5SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
140181ad6265SDimitry Andric                                                uint64_t Address,
140281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
14030b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14040b57cec5SDimitry Andric 
14055ffd83dbSDimitry Andric   // According to the Arm ARM RegNo = 14 is undefined, but we return fail
14065ffd83dbSDimitry Andric   // rather than SoftFail as there is no GPRPair table entry for index 7.
14070b57cec5SDimitry Andric   if (RegNo > 13)
14080b57cec5SDimitry Andric     return MCDisassembler::Fail;
14090b57cec5SDimitry Andric 
14105ffd83dbSDimitry Andric   if (RegNo & 1)
14110b57cec5SDimitry Andric      S = MCDisassembler::SoftFail;
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
14140b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
14150b57cec5SDimitry Andric   return S;
14160b57cec5SDimitry Andric }
14170b57cec5SDimitry Andric 
141881ad6265SDimitry Andric static DecodeStatus
DecodeGPRPairnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)141981ad6265SDimitry Andric DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
142081ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
14215ffd83dbSDimitry Andric   if (RegNo > 13)
14225ffd83dbSDimitry Andric     return MCDisassembler::Fail;
14235ffd83dbSDimitry Andric 
14245ffd83dbSDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
14255ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
14265ffd83dbSDimitry Andric 
14275ffd83dbSDimitry Andric   if ((RegNo & 1) || RegNo > 10)
14285ffd83dbSDimitry Andric      return MCDisassembler::SoftFail;
14295ffd83dbSDimitry Andric   return MCDisassembler::Success;
14305ffd83dbSDimitry Andric }
14315ffd83dbSDimitry Andric 
DecodeGPRspRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1432480093f4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
1433480093f4SDimitry Andric                                              uint64_t Address,
143481ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
1435480093f4SDimitry Andric   if (RegNo != 13)
1436480093f4SDimitry Andric     return MCDisassembler::Fail;
1437480093f4SDimitry Andric 
1438480093f4SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
1439480093f4SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
1440480093f4SDimitry Andric   return MCDisassembler::Success;
1441480093f4SDimitry Andric }
1442480093f4SDimitry Andric 
DecodetcGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14430b57cec5SDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
144481ad6265SDimitry Andric                                              uint64_t Address,
144581ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
14460b57cec5SDimitry Andric   unsigned Register = 0;
14470b57cec5SDimitry Andric   switch (RegNo) {
14480b57cec5SDimitry Andric     case 0:
14490b57cec5SDimitry Andric       Register = ARM::R0;
14500b57cec5SDimitry Andric       break;
14510b57cec5SDimitry Andric     case 1:
14520b57cec5SDimitry Andric       Register = ARM::R1;
14530b57cec5SDimitry Andric       break;
14540b57cec5SDimitry Andric     case 2:
14550b57cec5SDimitry Andric       Register = ARM::R2;
14560b57cec5SDimitry Andric       break;
14570b57cec5SDimitry Andric     case 3:
14580b57cec5SDimitry Andric       Register = ARM::R3;
14590b57cec5SDimitry Andric       break;
14600b57cec5SDimitry Andric     case 9:
14610b57cec5SDimitry Andric       Register = ARM::R9;
14620b57cec5SDimitry Andric       break;
14630b57cec5SDimitry Andric     case 12:
14640b57cec5SDimitry Andric       Register = ARM::R12;
14650b57cec5SDimitry Andric       break;
14660b57cec5SDimitry Andric     default:
14670b57cec5SDimitry Andric       return MCDisassembler::Fail;
14680b57cec5SDimitry Andric     }
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
14710b57cec5SDimitry Andric   return MCDisassembler::Success;
14720b57cec5SDimitry Andric }
14730b57cec5SDimitry Andric 
DecoderGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14740b57cec5SDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
147581ad6265SDimitry Andric                                             uint64_t Address,
147681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
14770b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   const FeatureBitset &featureBits =
14800b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric   if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15)
14830b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
14860b57cec5SDimitry Andric   return S;
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric static const uint16_t SPRDecoderTable[] = {
14900b57cec5SDimitry Andric      ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
14910b57cec5SDimitry Andric      ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
14920b57cec5SDimitry Andric      ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
14930b57cec5SDimitry Andric     ARM::S12, ARM::S13, ARM::S14, ARM::S15,
14940b57cec5SDimitry Andric     ARM::S16, ARM::S17, ARM::S18, ARM::S19,
14950b57cec5SDimitry Andric     ARM::S20, ARM::S21, ARM::S22, ARM::S23,
14960b57cec5SDimitry Andric     ARM::S24, ARM::S25, ARM::S26, ARM::S27,
14970b57cec5SDimitry Andric     ARM::S28, ARM::S29, ARM::S30, ARM::S31
14980b57cec5SDimitry Andric };
14990b57cec5SDimitry Andric 
DecodeSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15000b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
150181ad6265SDimitry Andric                                            uint64_t Address,
150281ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15030b57cec5SDimitry Andric   if (RegNo > 31)
15040b57cec5SDimitry Andric     return MCDisassembler::Fail;
15050b57cec5SDimitry Andric 
15060b57cec5SDimitry Andric   unsigned Register = SPRDecoderTable[RegNo];
15070b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
15080b57cec5SDimitry Andric   return MCDisassembler::Success;
15090b57cec5SDimitry Andric }
15100b57cec5SDimitry Andric 
DecodeHPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15110b57cec5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
151281ad6265SDimitry Andric                                            uint64_t Address,
151381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15140b57cec5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
15150b57cec5SDimitry Andric }
15160b57cec5SDimitry Andric 
15170b57cec5SDimitry Andric static const uint16_t DPRDecoderTable[] = {
15180b57cec5SDimitry Andric      ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
15190b57cec5SDimitry Andric      ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
15200b57cec5SDimitry Andric      ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
15210b57cec5SDimitry Andric     ARM::D12, ARM::D13, ARM::D14, ARM::D15,
15220b57cec5SDimitry Andric     ARM::D16, ARM::D17, ARM::D18, ARM::D19,
15230b57cec5SDimitry Andric     ARM::D20, ARM::D21, ARM::D22, ARM::D23,
15240b57cec5SDimitry Andric     ARM::D24, ARM::D25, ARM::D26, ARM::D27,
15250b57cec5SDimitry Andric     ARM::D28, ARM::D29, ARM::D30, ARM::D31
15260b57cec5SDimitry Andric };
15270b57cec5SDimitry Andric 
DecodeDPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15280b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
152981ad6265SDimitry Andric                                            uint64_t Address,
153081ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15310b57cec5SDimitry Andric   const FeatureBitset &featureBits =
15320b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric   bool hasD32 = featureBits[ARM::FeatureD32];
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric   if (RegNo > 31 || (!hasD32 && RegNo > 15))
15370b57cec5SDimitry Andric     return MCDisassembler::Fail;
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric   unsigned Register = DPRDecoderTable[RegNo];
15400b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
15410b57cec5SDimitry Andric   return MCDisassembler::Success;
15420b57cec5SDimitry Andric }
15430b57cec5SDimitry Andric 
DecodeDPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15440b57cec5SDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
154581ad6265SDimitry Andric                                              uint64_t Address,
154681ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
15470b57cec5SDimitry Andric   if (RegNo > 7)
15480b57cec5SDimitry Andric     return MCDisassembler::Fail;
15490b57cec5SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
15500b57cec5SDimitry Andric }
15510b57cec5SDimitry Andric 
DecodeSPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15520b57cec5SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
155381ad6265SDimitry Andric                                              uint64_t Address,
155481ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
15550b57cec5SDimitry Andric   if (RegNo > 15)
15560b57cec5SDimitry Andric     return MCDisassembler::Fail;
15570b57cec5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
15580b57cec5SDimitry Andric }
15590b57cec5SDimitry Andric 
DecodeDPR_VFP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)156081ad6265SDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
156181ad6265SDimitry Andric                                                 uint64_t Address,
156281ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
15630b57cec5SDimitry Andric   if (RegNo > 15)
15640b57cec5SDimitry Andric     return MCDisassembler::Fail;
15650b57cec5SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
15660b57cec5SDimitry Andric }
15670b57cec5SDimitry Andric 
15680b57cec5SDimitry Andric static const uint16_t QPRDecoderTable[] = {
15690b57cec5SDimitry Andric      ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
15700b57cec5SDimitry Andric      ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
15710b57cec5SDimitry Andric      ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
15720b57cec5SDimitry Andric     ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
15730b57cec5SDimitry Andric };
15740b57cec5SDimitry Andric 
DecodeQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15750b57cec5SDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
157681ad6265SDimitry Andric                                            uint64_t Address,
157781ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15780b57cec5SDimitry Andric   if (RegNo > 31 || (RegNo & 1) != 0)
15790b57cec5SDimitry Andric     return MCDisassembler::Fail;
15800b57cec5SDimitry Andric   RegNo >>= 1;
15810b57cec5SDimitry Andric 
15820b57cec5SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
15830b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
15840b57cec5SDimitry Andric   return MCDisassembler::Success;
15850b57cec5SDimitry Andric }
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric static const uint16_t DPairDecoderTable[] = {
15880b57cec5SDimitry Andric   ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
15890b57cec5SDimitry Andric   ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
15900b57cec5SDimitry Andric   ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
15910b57cec5SDimitry Andric   ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
15920b57cec5SDimitry Andric   ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
15930b57cec5SDimitry Andric   ARM::Q15
15940b57cec5SDimitry Andric };
15950b57cec5SDimitry Andric 
DecodeDPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)15960b57cec5SDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
159781ad6265SDimitry Andric                                              uint64_t Address,
159881ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
15990b57cec5SDimitry Andric   if (RegNo > 30)
16000b57cec5SDimitry Andric     return MCDisassembler::Fail;
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric   unsigned Register = DPairDecoderTable[RegNo];
16030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
16040b57cec5SDimitry Andric   return MCDisassembler::Success;
16050b57cec5SDimitry Andric }
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric static const uint16_t DPairSpacedDecoderTable[] = {
16080b57cec5SDimitry Andric   ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
16090b57cec5SDimitry Andric   ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
16100b57cec5SDimitry Andric   ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
16110b57cec5SDimitry Andric   ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
16120b57cec5SDimitry Andric   ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
16130b57cec5SDimitry Andric   ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
16140b57cec5SDimitry Andric   ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
16150b57cec5SDimitry Andric   ARM::D28_D30, ARM::D29_D31
16160b57cec5SDimitry Andric };
16170b57cec5SDimitry Andric 
161881ad6265SDimitry Andric static DecodeStatus
DecodeDPairSpacedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)161981ad6265SDimitry Andric DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
162081ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
16210b57cec5SDimitry Andric   if (RegNo > 29)
16220b57cec5SDimitry Andric     return MCDisassembler::Fail;
16230b57cec5SDimitry Andric 
16240b57cec5SDimitry Andric   unsigned Register = DPairSpacedDecoderTable[RegNo];
16250b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
16260b57cec5SDimitry Andric   return MCDisassembler::Success;
16270b57cec5SDimitry Andric }
16280b57cec5SDimitry Andric 
DecodePredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)16290b57cec5SDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
163081ad6265SDimitry Andric                                            uint64_t Address,
163181ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
16320b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16330b57cec5SDimitry Andric   if (Val == 0xF) return MCDisassembler::Fail;
16340b57cec5SDimitry Andric   // AL predicate is not allowed on Thumb1 branches.
16350b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
16360b57cec5SDimitry Andric     return MCDisassembler::Fail;
1637bdd1243dSDimitry Andric   const MCInstrInfo *MCII =
1638bdd1243dSDimitry Andric       static_cast<const ARMDisassembler *>(Decoder)->MCII.get();
1639bdd1243dSDimitry Andric   if (Val != ARMCC::AL && !MCII->get(Inst.getOpcode()).isPredicable())
16400b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
16410b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
16420b57cec5SDimitry Andric   if (Val == ARMCC::AL) {
16430b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
16440b57cec5SDimitry Andric   } else
16450b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
16460b57cec5SDimitry Andric   return S;
16470b57cec5SDimitry Andric }
16480b57cec5SDimitry Andric 
DecodeCCOutOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)16490b57cec5SDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
165081ad6265SDimitry Andric                                        uint64_t Address,
165181ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
16520b57cec5SDimitry Andric   if (Val)
16530b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
16540b57cec5SDimitry Andric   else
16550b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
16560b57cec5SDimitry Andric   return MCDisassembler::Success;
16570b57cec5SDimitry Andric }
16580b57cec5SDimitry Andric 
DecodeSORegImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)16590b57cec5SDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
166081ad6265SDimitry Andric                                           uint64_t Address,
166181ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
16620b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
16650b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
16660b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric   // Register-immediate
16690b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
16700b57cec5SDimitry Andric     return MCDisassembler::Fail;
16710b57cec5SDimitry Andric 
16720b57cec5SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
16730b57cec5SDimitry Andric   switch (type) {
16740b57cec5SDimitry Andric     case 0:
16750b57cec5SDimitry Andric       Shift = ARM_AM::lsl;
16760b57cec5SDimitry Andric       break;
16770b57cec5SDimitry Andric     case 1:
16780b57cec5SDimitry Andric       Shift = ARM_AM::lsr;
16790b57cec5SDimitry Andric       break;
16800b57cec5SDimitry Andric     case 2:
16810b57cec5SDimitry Andric       Shift = ARM_AM::asr;
16820b57cec5SDimitry Andric       break;
16830b57cec5SDimitry Andric     case 3:
16840b57cec5SDimitry Andric       Shift = ARM_AM::ror;
16850b57cec5SDimitry Andric       break;
16860b57cec5SDimitry Andric   }
16870b57cec5SDimitry Andric 
16880b57cec5SDimitry Andric   if (Shift == ARM_AM::ror && imm == 0)
16890b57cec5SDimitry Andric     Shift = ARM_AM::rrx;
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric   unsigned Op = Shift | (imm << 3);
16920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Op));
16930b57cec5SDimitry Andric 
16940b57cec5SDimitry Andric   return S;
16950b57cec5SDimitry Andric }
16960b57cec5SDimitry Andric 
DecodeSORegRegOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)16970b57cec5SDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
169881ad6265SDimitry Andric                                           uint64_t Address,
169981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
17000b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
17030b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
17040b57cec5SDimitry Andric   unsigned Rs = fieldFromInstruction(Val, 8, 4);
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric   // Register-register
17070b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
17080b57cec5SDimitry Andric     return MCDisassembler::Fail;
17090b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
17100b57cec5SDimitry Andric     return MCDisassembler::Fail;
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
17130b57cec5SDimitry Andric   switch (type) {
17140b57cec5SDimitry Andric     case 0:
17150b57cec5SDimitry Andric       Shift = ARM_AM::lsl;
17160b57cec5SDimitry Andric       break;
17170b57cec5SDimitry Andric     case 1:
17180b57cec5SDimitry Andric       Shift = ARM_AM::lsr;
17190b57cec5SDimitry Andric       break;
17200b57cec5SDimitry Andric     case 2:
17210b57cec5SDimitry Andric       Shift = ARM_AM::asr;
17220b57cec5SDimitry Andric       break;
17230b57cec5SDimitry Andric     case 3:
17240b57cec5SDimitry Andric       Shift = ARM_AM::ror;
17250b57cec5SDimitry Andric       break;
17260b57cec5SDimitry Andric   }
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Shift));
17290b57cec5SDimitry Andric 
17300b57cec5SDimitry Andric   return S;
17310b57cec5SDimitry Andric }
17320b57cec5SDimitry Andric 
DecodeRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)17330b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
173481ad6265SDimitry Andric                                          uint64_t Address,
173581ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
17360b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric   bool NeedDisjointWriteback = false;
17390b57cec5SDimitry Andric   unsigned WritebackReg = 0;
17400b57cec5SDimitry Andric   bool CLRM = false;
17410b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
17420b57cec5SDimitry Andric   default:
17430b57cec5SDimitry Andric     break;
17440b57cec5SDimitry Andric   case ARM::LDMIA_UPD:
17450b57cec5SDimitry Andric   case ARM::LDMDB_UPD:
17460b57cec5SDimitry Andric   case ARM::LDMIB_UPD:
17470b57cec5SDimitry Andric   case ARM::LDMDA_UPD:
17480b57cec5SDimitry Andric   case ARM::t2LDMIA_UPD:
17490b57cec5SDimitry Andric   case ARM::t2LDMDB_UPD:
17500b57cec5SDimitry Andric   case ARM::t2STMIA_UPD:
17510b57cec5SDimitry Andric   case ARM::t2STMDB_UPD:
17520b57cec5SDimitry Andric     NeedDisjointWriteback = true;
17530b57cec5SDimitry Andric     WritebackReg = Inst.getOperand(0).getReg();
17540b57cec5SDimitry Andric     break;
17550b57cec5SDimitry Andric   case ARM::t2CLRM:
17560b57cec5SDimitry Andric     CLRM = true;
17570b57cec5SDimitry Andric     break;
17580b57cec5SDimitry Andric   }
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric   // Empty register lists are not allowed.
17610b57cec5SDimitry Andric   if (Val == 0) return MCDisassembler::Fail;
17620b57cec5SDimitry Andric   for (unsigned i = 0; i < 16; ++i) {
17630b57cec5SDimitry Andric     if (Val & (1 << i)) {
17640b57cec5SDimitry Andric       if (CLRM) {
17650b57cec5SDimitry Andric         if (!Check(S, DecodeCLRMGPRRegisterClass(Inst, i, Address, Decoder))) {
17660b57cec5SDimitry Andric           return MCDisassembler::Fail;
17670b57cec5SDimitry Andric         }
17680b57cec5SDimitry Andric       } else {
17690b57cec5SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
17700b57cec5SDimitry Andric           return MCDisassembler::Fail;
17710b57cec5SDimitry Andric         // Writeback not allowed if Rn is in the target list.
17720b57cec5SDimitry Andric         if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
17730b57cec5SDimitry Andric           Check(S, MCDisassembler::SoftFail);
17740b57cec5SDimitry Andric       }
17750b57cec5SDimitry Andric     }
17760b57cec5SDimitry Andric   }
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric   return S;
17790b57cec5SDimitry Andric }
17800b57cec5SDimitry Andric 
DecodeSPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)17810b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
178281ad6265SDimitry Andric                                             uint64_t Address,
178381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
17840b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
17870b57cec5SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 0, 8);
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric   // In case of unpredictable encoding, tweak the operands.
17900b57cec5SDimitry Andric   if (regs == 0 || (Vd + regs) > 32) {
17910b57cec5SDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
17920b57cec5SDimitry Andric     regs = std::max( 1u, regs);
17930b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
17940b57cec5SDimitry Andric   }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
17970b57cec5SDimitry Andric     return MCDisassembler::Fail;
17980b57cec5SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
17990b57cec5SDimitry Andric     if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
18000b57cec5SDimitry Andric       return MCDisassembler::Fail;
18010b57cec5SDimitry Andric   }
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric   return S;
18040b57cec5SDimitry Andric }
18050b57cec5SDimitry Andric 
DecodeDPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)18060b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
180781ad6265SDimitry Andric                                             uint64_t Address,
180881ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
18090b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18100b57cec5SDimitry Andric 
18110b57cec5SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
18120b57cec5SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 1, 7);
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric   // In case of unpredictable encoding, tweak the operands.
18150b57cec5SDimitry Andric   if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
18160b57cec5SDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
18170b57cec5SDimitry Andric     regs = std::max( 1u, regs);
18180b57cec5SDimitry Andric     regs = std::min(16u, regs);
18190b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
18200b57cec5SDimitry Andric   }
18210b57cec5SDimitry Andric 
18220b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
18230b57cec5SDimitry Andric       return MCDisassembler::Fail;
18240b57cec5SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
18250b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
18260b57cec5SDimitry Andric       return MCDisassembler::Fail;
18270b57cec5SDimitry Andric   }
18280b57cec5SDimitry Andric 
18290b57cec5SDimitry Andric   return S;
18300b57cec5SDimitry Andric }
18310b57cec5SDimitry Andric 
DecodeBitfieldMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)18320b57cec5SDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
183381ad6265SDimitry Andric                                               uint64_t Address,
183481ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
18350b57cec5SDimitry Andric   // This operand encodes a mask of contiguous zeros between a specified MSB
18360b57cec5SDimitry Andric   // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
18370b57cec5SDimitry Andric   // the mask of all bits LSB-and-lower, and then xor them to create
18380b57cec5SDimitry Andric   // the mask of that's all ones on [msb, lsb].  Finally we not it to
18390b57cec5SDimitry Andric   // create the final mask.
18400b57cec5SDimitry Andric   unsigned msb = fieldFromInstruction(Val, 5, 5);
18410b57cec5SDimitry Andric   unsigned lsb = fieldFromInstruction(Val, 0, 5);
18420b57cec5SDimitry Andric 
18430b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18440b57cec5SDimitry Andric   if (lsb > msb) {
18450b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
18460b57cec5SDimitry Andric     // The check above will cause the warning for the "potentially undefined
18470b57cec5SDimitry Andric     // instruction encoding" but we can't build a bad MCOperand value here
18480b57cec5SDimitry Andric     // with a lsb > msb or else printing the MCInst will cause a crash.
18490b57cec5SDimitry Andric     lsb = msb;
18500b57cec5SDimitry Andric   }
18510b57cec5SDimitry Andric 
18520b57cec5SDimitry Andric   uint32_t msb_mask = 0xFFFFFFFF;
18530b57cec5SDimitry Andric   if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
18540b57cec5SDimitry Andric   uint32_t lsb_mask = (1U << lsb) - 1;
18550b57cec5SDimitry Andric 
18560b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask)));
18570b57cec5SDimitry Andric   return S;
18580b57cec5SDimitry Andric }
18590b57cec5SDimitry Andric 
DecodeCopMemInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)18600b57cec5SDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
186181ad6265SDimitry Andric                                             uint64_t Address,
186281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
18630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
18660b57cec5SDimitry Andric   unsigned CRd = fieldFromInstruction(Insn, 12, 4);
18670b57cec5SDimitry Andric   unsigned coproc = fieldFromInstruction(Insn, 8, 4);
18680b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
18690b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
18700b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
18710b57cec5SDimitry Andric   const FeatureBitset &featureBits =
18720b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
18730b57cec5SDimitry Andric 
18740b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
18750b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
18760b57cec5SDimitry Andric     case ARM::LDC_PRE:
18770b57cec5SDimitry Andric     case ARM::LDC_POST:
18780b57cec5SDimitry Andric     case ARM::LDC_OPTION:
18790b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
18800b57cec5SDimitry Andric     case ARM::LDCL_PRE:
18810b57cec5SDimitry Andric     case ARM::LDCL_POST:
18820b57cec5SDimitry Andric     case ARM::LDCL_OPTION:
18830b57cec5SDimitry Andric     case ARM::STC_OFFSET:
18840b57cec5SDimitry Andric     case ARM::STC_PRE:
18850b57cec5SDimitry Andric     case ARM::STC_POST:
18860b57cec5SDimitry Andric     case ARM::STC_OPTION:
18870b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
18880b57cec5SDimitry Andric     case ARM::STCL_PRE:
18890b57cec5SDimitry Andric     case ARM::STCL_POST:
18900b57cec5SDimitry Andric     case ARM::STCL_OPTION:
18910b57cec5SDimitry Andric     case ARM::t2LDC_OFFSET:
18920b57cec5SDimitry Andric     case ARM::t2LDC_PRE:
18930b57cec5SDimitry Andric     case ARM::t2LDC_POST:
18940b57cec5SDimitry Andric     case ARM::t2LDC_OPTION:
18950b57cec5SDimitry Andric     case ARM::t2LDCL_OFFSET:
18960b57cec5SDimitry Andric     case ARM::t2LDCL_PRE:
18970b57cec5SDimitry Andric     case ARM::t2LDCL_POST:
18980b57cec5SDimitry Andric     case ARM::t2LDCL_OPTION:
18990b57cec5SDimitry Andric     case ARM::t2STC_OFFSET:
19000b57cec5SDimitry Andric     case ARM::t2STC_PRE:
19010b57cec5SDimitry Andric     case ARM::t2STC_POST:
19020b57cec5SDimitry Andric     case ARM::t2STC_OPTION:
19030b57cec5SDimitry Andric     case ARM::t2STCL_OFFSET:
19040b57cec5SDimitry Andric     case ARM::t2STCL_PRE:
19050b57cec5SDimitry Andric     case ARM::t2STCL_POST:
19060b57cec5SDimitry Andric     case ARM::t2STCL_OPTION:
19070b57cec5SDimitry Andric     case ARM::t2LDC2_OFFSET:
19080b57cec5SDimitry Andric     case ARM::t2LDC2L_OFFSET:
19090b57cec5SDimitry Andric     case ARM::t2LDC2_PRE:
19100b57cec5SDimitry Andric     case ARM::t2LDC2L_PRE:
19110b57cec5SDimitry Andric     case ARM::t2STC2_OFFSET:
19120b57cec5SDimitry Andric     case ARM::t2STC2L_OFFSET:
19130b57cec5SDimitry Andric     case ARM::t2STC2_PRE:
19140b57cec5SDimitry Andric     case ARM::t2STC2L_PRE:
19150b57cec5SDimitry Andric     case ARM::LDC2_OFFSET:
19160b57cec5SDimitry Andric     case ARM::LDC2L_OFFSET:
19170b57cec5SDimitry Andric     case ARM::LDC2_PRE:
19180b57cec5SDimitry Andric     case ARM::LDC2L_PRE:
19190b57cec5SDimitry Andric     case ARM::STC2_OFFSET:
19200b57cec5SDimitry Andric     case ARM::STC2L_OFFSET:
19210b57cec5SDimitry Andric     case ARM::STC2_PRE:
19220b57cec5SDimitry Andric     case ARM::STC2L_PRE:
19230b57cec5SDimitry Andric     case ARM::t2LDC2_OPTION:
19240b57cec5SDimitry Andric     case ARM::t2STC2_OPTION:
19250b57cec5SDimitry Andric     case ARM::t2LDC2_POST:
19260b57cec5SDimitry Andric     case ARM::t2LDC2L_POST:
19270b57cec5SDimitry Andric     case ARM::t2STC2_POST:
19280b57cec5SDimitry Andric     case ARM::t2STC2L_POST:
19290b57cec5SDimitry Andric     case ARM::LDC2_POST:
19300b57cec5SDimitry Andric     case ARM::LDC2L_POST:
19310b57cec5SDimitry Andric     case ARM::STC2_POST:
19320b57cec5SDimitry Andric     case ARM::STC2L_POST:
19330b57cec5SDimitry Andric       if (coproc == 0xA || coproc == 0xB ||
19340b57cec5SDimitry Andric           (featureBits[ARM::HasV8_1MMainlineOps] &&
19350b57cec5SDimitry Andric            (coproc == 0x8 || coproc == 0x9 || coproc == 0xA || coproc == 0xB ||
19360b57cec5SDimitry Andric             coproc == 0xE || coproc == 0xF)))
19370b57cec5SDimitry Andric         return MCDisassembler::Fail;
19380b57cec5SDimitry Andric       break;
19390b57cec5SDimitry Andric     default:
19400b57cec5SDimitry Andric       break;
19410b57cec5SDimitry Andric   }
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric   if (featureBits[ARM::HasV8Ops] && (coproc != 14))
19440b57cec5SDimitry Andric     return MCDisassembler::Fail;
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(coproc));
19470b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRd));
19480b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
19490b57cec5SDimitry Andric     return MCDisassembler::Fail;
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
19520b57cec5SDimitry Andric     case ARM::t2LDC2_OFFSET:
19530b57cec5SDimitry Andric     case ARM::t2LDC2L_OFFSET:
19540b57cec5SDimitry Andric     case ARM::t2LDC2_PRE:
19550b57cec5SDimitry Andric     case ARM::t2LDC2L_PRE:
19560b57cec5SDimitry Andric     case ARM::t2STC2_OFFSET:
19570b57cec5SDimitry Andric     case ARM::t2STC2L_OFFSET:
19580b57cec5SDimitry Andric     case ARM::t2STC2_PRE:
19590b57cec5SDimitry Andric     case ARM::t2STC2L_PRE:
19600b57cec5SDimitry Andric     case ARM::LDC2_OFFSET:
19610b57cec5SDimitry Andric     case ARM::LDC2L_OFFSET:
19620b57cec5SDimitry Andric     case ARM::LDC2_PRE:
19630b57cec5SDimitry Andric     case ARM::LDC2L_PRE:
19640b57cec5SDimitry Andric     case ARM::STC2_OFFSET:
19650b57cec5SDimitry Andric     case ARM::STC2L_OFFSET:
19660b57cec5SDimitry Andric     case ARM::STC2_PRE:
19670b57cec5SDimitry Andric     case ARM::STC2L_PRE:
19680b57cec5SDimitry Andric     case ARM::t2LDC_OFFSET:
19690b57cec5SDimitry Andric     case ARM::t2LDCL_OFFSET:
19700b57cec5SDimitry Andric     case ARM::t2LDC_PRE:
19710b57cec5SDimitry Andric     case ARM::t2LDCL_PRE:
19720b57cec5SDimitry Andric     case ARM::t2STC_OFFSET:
19730b57cec5SDimitry Andric     case ARM::t2STCL_OFFSET:
19740b57cec5SDimitry Andric     case ARM::t2STC_PRE:
19750b57cec5SDimitry Andric     case ARM::t2STCL_PRE:
19760b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
19770b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
19780b57cec5SDimitry Andric     case ARM::LDC_PRE:
19790b57cec5SDimitry Andric     case ARM::LDCL_PRE:
19800b57cec5SDimitry Andric     case ARM::STC_OFFSET:
19810b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
19820b57cec5SDimitry Andric     case ARM::STC_PRE:
19830b57cec5SDimitry Andric     case ARM::STCL_PRE:
19840b57cec5SDimitry Andric       imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
19850b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
19860b57cec5SDimitry Andric       break;
19870b57cec5SDimitry Andric     case ARM::t2LDC2_POST:
19880b57cec5SDimitry Andric     case ARM::t2LDC2L_POST:
19890b57cec5SDimitry Andric     case ARM::t2STC2_POST:
19900b57cec5SDimitry Andric     case ARM::t2STC2L_POST:
19910b57cec5SDimitry Andric     case ARM::LDC2_POST:
19920b57cec5SDimitry Andric     case ARM::LDC2L_POST:
19930b57cec5SDimitry Andric     case ARM::STC2_POST:
19940b57cec5SDimitry Andric     case ARM::STC2L_POST:
19950b57cec5SDimitry Andric     case ARM::t2LDC_POST:
19960b57cec5SDimitry Andric     case ARM::t2LDCL_POST:
19970b57cec5SDimitry Andric     case ARM::t2STC_POST:
19980b57cec5SDimitry Andric     case ARM::t2STCL_POST:
19990b57cec5SDimitry Andric     case ARM::LDC_POST:
20000b57cec5SDimitry Andric     case ARM::LDCL_POST:
20010b57cec5SDimitry Andric     case ARM::STC_POST:
20020b57cec5SDimitry Andric     case ARM::STCL_POST:
20030b57cec5SDimitry Andric       imm |= U << 8;
2004bdd1243dSDimitry Andric       [[fallthrough]];
20050b57cec5SDimitry Andric     default:
20060b57cec5SDimitry Andric       // The 'option' variant doesn't encode 'U' in the immediate since
20070b57cec5SDimitry Andric       // the immediate is unsigned [0,255].
20080b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
20090b57cec5SDimitry Andric       break;
20100b57cec5SDimitry Andric   }
20110b57cec5SDimitry Andric 
20120b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20130b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
20140b57cec5SDimitry Andric     case ARM::LDC_PRE:
20150b57cec5SDimitry Andric     case ARM::LDC_POST:
20160b57cec5SDimitry Andric     case ARM::LDC_OPTION:
20170b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
20180b57cec5SDimitry Andric     case ARM::LDCL_PRE:
20190b57cec5SDimitry Andric     case ARM::LDCL_POST:
20200b57cec5SDimitry Andric     case ARM::LDCL_OPTION:
20210b57cec5SDimitry Andric     case ARM::STC_OFFSET:
20220b57cec5SDimitry Andric     case ARM::STC_PRE:
20230b57cec5SDimitry Andric     case ARM::STC_POST:
20240b57cec5SDimitry Andric     case ARM::STC_OPTION:
20250b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
20260b57cec5SDimitry Andric     case ARM::STCL_PRE:
20270b57cec5SDimitry Andric     case ARM::STCL_POST:
20280b57cec5SDimitry Andric     case ARM::STCL_OPTION:
20290b57cec5SDimitry Andric       if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
20300b57cec5SDimitry Andric         return MCDisassembler::Fail;
20310b57cec5SDimitry Andric       break;
20320b57cec5SDimitry Andric     default:
20330b57cec5SDimitry Andric       break;
20340b57cec5SDimitry Andric   }
20350b57cec5SDimitry Andric 
20360b57cec5SDimitry Andric   return S;
20370b57cec5SDimitry Andric }
20380b57cec5SDimitry Andric 
20390b57cec5SDimitry Andric static DecodeStatus
DecodeAddrMode2IdxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)204081ad6265SDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
204181ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
20420b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
20450b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
20460b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
20470b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
20480b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
20490b57cec5SDimitry Andric   unsigned reg = fieldFromInstruction(Insn, 25, 1);
20500b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
20510b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric   // On stores, the writeback operand precedes Rt.
20540b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20550b57cec5SDimitry Andric     case ARM::STR_POST_IMM:
20560b57cec5SDimitry Andric     case ARM::STR_POST_REG:
20570b57cec5SDimitry Andric     case ARM::STRB_POST_IMM:
20580b57cec5SDimitry Andric     case ARM::STRB_POST_REG:
20590b57cec5SDimitry Andric     case ARM::STRT_POST_REG:
20600b57cec5SDimitry Andric     case ARM::STRT_POST_IMM:
20610b57cec5SDimitry Andric     case ARM::STRBT_POST_REG:
20620b57cec5SDimitry Andric     case ARM::STRBT_POST_IMM:
20630b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
20640b57cec5SDimitry Andric         return MCDisassembler::Fail;
20650b57cec5SDimitry Andric       break;
20660b57cec5SDimitry Andric     default:
20670b57cec5SDimitry Andric       break;
20680b57cec5SDimitry Andric   }
20690b57cec5SDimitry Andric 
20700b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
20710b57cec5SDimitry Andric     return MCDisassembler::Fail;
20720b57cec5SDimitry Andric 
20730b57cec5SDimitry Andric   // On loads, the writeback operand comes after Rt.
20740b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20750b57cec5SDimitry Andric     case ARM::LDR_POST_IMM:
20760b57cec5SDimitry Andric     case ARM::LDR_POST_REG:
20770b57cec5SDimitry Andric     case ARM::LDRB_POST_IMM:
20780b57cec5SDimitry Andric     case ARM::LDRB_POST_REG:
20790b57cec5SDimitry Andric     case ARM::LDRBT_POST_REG:
20800b57cec5SDimitry Andric     case ARM::LDRBT_POST_IMM:
20810b57cec5SDimitry Andric     case ARM::LDRT_POST_REG:
20820b57cec5SDimitry Andric     case ARM::LDRT_POST_IMM:
20830b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
20840b57cec5SDimitry Andric         return MCDisassembler::Fail;
20850b57cec5SDimitry Andric       break;
20860b57cec5SDimitry Andric     default:
20870b57cec5SDimitry Andric       break;
20880b57cec5SDimitry Andric   }
20890b57cec5SDimitry Andric 
20900b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
20910b57cec5SDimitry Andric     return MCDisassembler::Fail;
20920b57cec5SDimitry Andric 
20930b57cec5SDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::add;
20940b57cec5SDimitry Andric   if (!fieldFromInstruction(Insn, 23, 1))
20950b57cec5SDimitry Andric     Op = ARM_AM::sub;
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric   bool writeback = (P == 0) || (W == 1);
20980b57cec5SDimitry Andric   unsigned idx_mode = 0;
20990b57cec5SDimitry Andric   if (P && writeback)
21000b57cec5SDimitry Andric     idx_mode = ARMII::IndexModePre;
21010b57cec5SDimitry Andric   else if (!P && writeback)
21020b57cec5SDimitry Andric     idx_mode = ARMII::IndexModePost;
21030b57cec5SDimitry Andric 
21040b57cec5SDimitry Andric   if (writeback && (Rn == 15 || Rn == Rt))
21050b57cec5SDimitry Andric     S = MCDisassembler::SoftFail; // UNPREDICTABLE
21060b57cec5SDimitry Andric 
21070b57cec5SDimitry Andric   if (reg) {
21080b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
21090b57cec5SDimitry Andric       return MCDisassembler::Fail;
21100b57cec5SDimitry Andric     ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
21110b57cec5SDimitry Andric     switch( fieldFromInstruction(Insn, 5, 2)) {
21120b57cec5SDimitry Andric       case 0:
21130b57cec5SDimitry Andric         Opc = ARM_AM::lsl;
21140b57cec5SDimitry Andric         break;
21150b57cec5SDimitry Andric       case 1:
21160b57cec5SDimitry Andric         Opc = ARM_AM::lsr;
21170b57cec5SDimitry Andric         break;
21180b57cec5SDimitry Andric       case 2:
21190b57cec5SDimitry Andric         Opc = ARM_AM::asr;
21200b57cec5SDimitry Andric         break;
21210b57cec5SDimitry Andric       case 3:
21220b57cec5SDimitry Andric         Opc = ARM_AM::ror;
21230b57cec5SDimitry Andric         break;
21240b57cec5SDimitry Andric       default:
21250b57cec5SDimitry Andric         return MCDisassembler::Fail;
21260b57cec5SDimitry Andric     }
21270b57cec5SDimitry Andric     unsigned amt = fieldFromInstruction(Insn, 7, 5);
21280b57cec5SDimitry Andric     if (Opc == ARM_AM::ror && amt == 0)
21290b57cec5SDimitry Andric       Opc = ARM_AM::rrx;
21300b57cec5SDimitry Andric     unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
21310b57cec5SDimitry Andric 
21320b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
21330b57cec5SDimitry Andric   } else {
21340b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
21350b57cec5SDimitry Andric     unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
21360b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(tmp));
21370b57cec5SDimitry Andric   }
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
21400b57cec5SDimitry Andric     return MCDisassembler::Fail;
21410b57cec5SDimitry Andric 
21420b57cec5SDimitry Andric   return S;
21430b57cec5SDimitry Andric }
21440b57cec5SDimitry Andric 
DecodeSORegMemOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)21450b57cec5SDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
214681ad6265SDimitry Andric                                           uint64_t Address,
214781ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
21480b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
21510b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val,  0, 4);
21520b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
21530b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
21540b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 12, 1);
21550b57cec5SDimitry Andric 
21560b57cec5SDimitry Andric   ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
21570b57cec5SDimitry Andric   switch (type) {
21580b57cec5SDimitry Andric     case 0:
21590b57cec5SDimitry Andric       ShOp = ARM_AM::lsl;
21600b57cec5SDimitry Andric       break;
21610b57cec5SDimitry Andric     case 1:
21620b57cec5SDimitry Andric       ShOp = ARM_AM::lsr;
21630b57cec5SDimitry Andric       break;
21640b57cec5SDimitry Andric     case 2:
21650b57cec5SDimitry Andric       ShOp = ARM_AM::asr;
21660b57cec5SDimitry Andric       break;
21670b57cec5SDimitry Andric     case 3:
21680b57cec5SDimitry Andric       ShOp = ARM_AM::ror;
21690b57cec5SDimitry Andric       break;
21700b57cec5SDimitry Andric   }
21710b57cec5SDimitry Andric 
21720b57cec5SDimitry Andric   if (ShOp == ARM_AM::ror && imm == 0)
21730b57cec5SDimitry Andric     ShOp = ARM_AM::rrx;
21740b57cec5SDimitry Andric 
21750b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
21760b57cec5SDimitry Andric     return MCDisassembler::Fail;
21770b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
21780b57cec5SDimitry Andric     return MCDisassembler::Fail;
21790b57cec5SDimitry Andric   unsigned shift;
21800b57cec5SDimitry Andric   if (U)
21810b57cec5SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
21820b57cec5SDimitry Andric   else
21830b57cec5SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
21840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric   return S;
21870b57cec5SDimitry Andric }
21880b57cec5SDimitry Andric 
DecodeTSBInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)218981ad6265SDimitry Andric static DecodeStatus DecodeTSBInstruction(MCInst &Inst, unsigned Insn,
219081ad6265SDimitry Andric                                          uint64_t Address,
219181ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
219281ad6265SDimitry Andric   if (Inst.getOpcode() != ARM::TSB && Inst.getOpcode() != ARM::t2TSB)
219381ad6265SDimitry Andric     return MCDisassembler::Fail;
219481ad6265SDimitry Andric 
219581ad6265SDimitry Andric   // The "csync" operand is not encoded into the "tsb" instruction (as this is
219681ad6265SDimitry Andric   // the only available operand), but LLVM expects the instruction to have one
219781ad6265SDimitry Andric   // operand, so we need to add the csync when decoding.
219881ad6265SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARM_TSB::CSYNC));
219981ad6265SDimitry Andric   return MCDisassembler::Success;
220081ad6265SDimitry Andric }
220181ad6265SDimitry Andric 
DecodeAddrMode3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)220281ad6265SDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
220381ad6265SDimitry Andric                                                uint64_t Address,
220481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
22050b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22060b57cec5SDimitry Andric 
22070b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
22080b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
22090b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
22100b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 22, 1);
22110b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 8, 4);
22120b57cec5SDimitry Andric   unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
22130b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
22140b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
22150b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
22160b57cec5SDimitry Andric   unsigned Rt2 = Rt + 1;
22170b57cec5SDimitry Andric 
22180b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
22190b57cec5SDimitry Andric 
22200b57cec5SDimitry Andric   // For {LD,ST}RD, Rt must be even, else undefined.
22210b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
22220b57cec5SDimitry Andric     case ARM::STRD:
22230b57cec5SDimitry Andric     case ARM::STRD_PRE:
22240b57cec5SDimitry Andric     case ARM::STRD_POST:
22250b57cec5SDimitry Andric     case ARM::LDRD:
22260b57cec5SDimitry Andric     case ARM::LDRD_PRE:
22270b57cec5SDimitry Andric     case ARM::LDRD_POST:
22280b57cec5SDimitry Andric       if (Rt & 0x1) S = MCDisassembler::SoftFail;
22290b57cec5SDimitry Andric       break;
22300b57cec5SDimitry Andric     default:
22310b57cec5SDimitry Andric       break;
22320b57cec5SDimitry Andric   }
22330b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
22340b57cec5SDimitry Andric     case ARM::STRD:
22350b57cec5SDimitry Andric     case ARM::STRD_PRE:
22360b57cec5SDimitry Andric     case ARM::STRD_POST:
22370b57cec5SDimitry Andric       if (P == 0 && W == 1)
22380b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22390b57cec5SDimitry Andric 
22400b57cec5SDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
22410b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22420b57cec5SDimitry Andric       if (type && Rm == 15)
22430b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22440b57cec5SDimitry Andric       if (Rt2 == 15)
22450b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22460b57cec5SDimitry Andric       if (!type && fieldFromInstruction(Insn, 8, 4))
22470b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22480b57cec5SDimitry Andric       break;
22490b57cec5SDimitry Andric     case ARM::STRH:
22500b57cec5SDimitry Andric     case ARM::STRH_PRE:
22510b57cec5SDimitry Andric     case ARM::STRH_POST:
22520b57cec5SDimitry Andric       if (Rt == 15)
22530b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22540b57cec5SDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt))
22550b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22560b57cec5SDimitry Andric       if (!type && Rm == 15)
22570b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22580b57cec5SDimitry Andric       break;
22590b57cec5SDimitry Andric     case ARM::LDRD:
22600b57cec5SDimitry Andric     case ARM::LDRD_PRE:
22610b57cec5SDimitry Andric     case ARM::LDRD_POST:
22620b57cec5SDimitry Andric       if (type && Rn == 15) {
22630b57cec5SDimitry Andric         if (Rt2 == 15)
22640b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
22650b57cec5SDimitry Andric         break;
22660b57cec5SDimitry Andric       }
22670b57cec5SDimitry Andric       if (P == 0 && W == 1)
22680b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22690b57cec5SDimitry Andric       if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
22700b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22710b57cec5SDimitry Andric       if (!type && writeback && Rn == 15)
22720b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22730b57cec5SDimitry Andric       if (writeback && (Rn == Rt || Rn == Rt2))
22740b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22750b57cec5SDimitry Andric       break;
22760b57cec5SDimitry Andric     case ARM::LDRH:
22770b57cec5SDimitry Andric     case ARM::LDRH_PRE:
22780b57cec5SDimitry Andric     case ARM::LDRH_POST:
22790b57cec5SDimitry Andric       if (type && Rn == 15) {
22800b57cec5SDimitry Andric         if (Rt == 15)
22810b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
22820b57cec5SDimitry Andric         break;
22830b57cec5SDimitry Andric       }
22840b57cec5SDimitry Andric       if (Rt == 15)
22850b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22860b57cec5SDimitry Andric       if (!type && Rm == 15)
22870b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22880b57cec5SDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
22890b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22900b57cec5SDimitry Andric       break;
22910b57cec5SDimitry Andric     case ARM::LDRSH:
22920b57cec5SDimitry Andric     case ARM::LDRSH_PRE:
22930b57cec5SDimitry Andric     case ARM::LDRSH_POST:
22940b57cec5SDimitry Andric     case ARM::LDRSB:
22950b57cec5SDimitry Andric     case ARM::LDRSB_PRE:
22960b57cec5SDimitry Andric     case ARM::LDRSB_POST:
22970b57cec5SDimitry Andric       if (type && Rn == 15) {
22980b57cec5SDimitry Andric         if (Rt == 15)
22990b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
23000b57cec5SDimitry Andric         break;
23010b57cec5SDimitry Andric       }
23020b57cec5SDimitry Andric       if (type && (Rt == 15 || (writeback && Rn == Rt)))
23030b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
23040b57cec5SDimitry Andric       if (!type && (Rt == 15 || Rm == 15))
23050b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
23060b57cec5SDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
23070b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
23080b57cec5SDimitry Andric       break;
23090b57cec5SDimitry Andric     default:
23100b57cec5SDimitry Andric       break;
23110b57cec5SDimitry Andric   }
23120b57cec5SDimitry Andric 
23130b57cec5SDimitry Andric   if (writeback) { // Writeback
23140b57cec5SDimitry Andric     if (P)
23150b57cec5SDimitry Andric       U |= ARMII::IndexModePre << 9;
23160b57cec5SDimitry Andric     else
23170b57cec5SDimitry Andric       U |= ARMII::IndexModePost << 9;
23180b57cec5SDimitry Andric 
23190b57cec5SDimitry Andric     // On stores, the writeback operand precedes Rt.
23200b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
23210b57cec5SDimitry Andric     case ARM::STRD:
23220b57cec5SDimitry Andric     case ARM::STRD_PRE:
23230b57cec5SDimitry Andric     case ARM::STRD_POST:
23240b57cec5SDimitry Andric     case ARM::STRH:
23250b57cec5SDimitry Andric     case ARM::STRH_PRE:
23260b57cec5SDimitry Andric     case ARM::STRH_POST:
23270b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23280b57cec5SDimitry Andric         return MCDisassembler::Fail;
23290b57cec5SDimitry Andric       break;
23300b57cec5SDimitry Andric     default:
23310b57cec5SDimitry Andric       break;
23320b57cec5SDimitry Andric     }
23330b57cec5SDimitry Andric   }
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
23360b57cec5SDimitry Andric     return MCDisassembler::Fail;
23370b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
23380b57cec5SDimitry Andric     case ARM::STRD:
23390b57cec5SDimitry Andric     case ARM::STRD_PRE:
23400b57cec5SDimitry Andric     case ARM::STRD_POST:
23410b57cec5SDimitry Andric     case ARM::LDRD:
23420b57cec5SDimitry Andric     case ARM::LDRD_PRE:
23430b57cec5SDimitry Andric     case ARM::LDRD_POST:
23440b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
23450b57cec5SDimitry Andric         return MCDisassembler::Fail;
23460b57cec5SDimitry Andric       break;
23470b57cec5SDimitry Andric     default:
23480b57cec5SDimitry Andric       break;
23490b57cec5SDimitry Andric   }
23500b57cec5SDimitry Andric 
23510b57cec5SDimitry Andric   if (writeback) {
23520b57cec5SDimitry Andric     // On loads, the writeback operand comes after Rt.
23530b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
23540b57cec5SDimitry Andric     case ARM::LDRD:
23550b57cec5SDimitry Andric     case ARM::LDRD_PRE:
23560b57cec5SDimitry Andric     case ARM::LDRD_POST:
23570b57cec5SDimitry Andric     case ARM::LDRH:
23580b57cec5SDimitry Andric     case ARM::LDRH_PRE:
23590b57cec5SDimitry Andric     case ARM::LDRH_POST:
23600b57cec5SDimitry Andric     case ARM::LDRSH:
23610b57cec5SDimitry Andric     case ARM::LDRSH_PRE:
23620b57cec5SDimitry Andric     case ARM::LDRSH_POST:
23630b57cec5SDimitry Andric     case ARM::LDRSB:
23640b57cec5SDimitry Andric     case ARM::LDRSB_PRE:
23650b57cec5SDimitry Andric     case ARM::LDRSB_POST:
23660b57cec5SDimitry Andric     case ARM::LDRHTr:
23670b57cec5SDimitry Andric     case ARM::LDRSBTr:
23680b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23690b57cec5SDimitry Andric         return MCDisassembler::Fail;
23700b57cec5SDimitry Andric       break;
23710b57cec5SDimitry Andric     default:
23720b57cec5SDimitry Andric       break;
23730b57cec5SDimitry Andric     }
23740b57cec5SDimitry Andric   }
23750b57cec5SDimitry Andric 
23760b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23770b57cec5SDimitry Andric     return MCDisassembler::Fail;
23780b57cec5SDimitry Andric 
23790b57cec5SDimitry Andric   if (type) {
23800b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
23810b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm));
23820b57cec5SDimitry Andric   } else {
23830b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
23840b57cec5SDimitry Andric     return MCDisassembler::Fail;
23850b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(U));
23860b57cec5SDimitry Andric   }
23870b57cec5SDimitry Andric 
23880b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
23890b57cec5SDimitry Andric     return MCDisassembler::Fail;
23900b57cec5SDimitry Andric 
23910b57cec5SDimitry Andric   return S;
23920b57cec5SDimitry Andric }
23930b57cec5SDimitry Andric 
DecodeRFEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)23940b57cec5SDimitry Andric static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
239581ad6265SDimitry Andric                                          uint64_t Address,
239681ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
23970b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
23980b57cec5SDimitry Andric 
23990b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
24000b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 23, 2);
24010b57cec5SDimitry Andric 
24020b57cec5SDimitry Andric   switch (mode) {
24030b57cec5SDimitry Andric     case 0:
24040b57cec5SDimitry Andric       mode = ARM_AM::da;
24050b57cec5SDimitry Andric       break;
24060b57cec5SDimitry Andric     case 1:
24070b57cec5SDimitry Andric       mode = ARM_AM::ia;
24080b57cec5SDimitry Andric       break;
24090b57cec5SDimitry Andric     case 2:
24100b57cec5SDimitry Andric       mode = ARM_AM::db;
24110b57cec5SDimitry Andric       break;
24120b57cec5SDimitry Andric     case 3:
24130b57cec5SDimitry Andric       mode = ARM_AM::ib;
24140b57cec5SDimitry Andric       break;
24150b57cec5SDimitry Andric   }
24160b57cec5SDimitry Andric 
24170b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(mode));
24180b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
24190b57cec5SDimitry Andric     return MCDisassembler::Fail;
24200b57cec5SDimitry Andric 
24210b57cec5SDimitry Andric   return S;
24220b57cec5SDimitry Andric }
24230b57cec5SDimitry Andric 
DecodeQADDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)24240b57cec5SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
242581ad6265SDimitry Andric                                           uint64_t Address,
242681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
24270b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24280b57cec5SDimitry Andric 
24290b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
24300b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
24310b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
24320b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
24330b57cec5SDimitry Andric 
24340b57cec5SDimitry Andric   if (pred == 0xF)
24350b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
24360b57cec5SDimitry Andric 
24370b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
24380b57cec5SDimitry Andric     return MCDisassembler::Fail;
24390b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
24400b57cec5SDimitry Andric     return MCDisassembler::Fail;
24410b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
24420b57cec5SDimitry Andric     return MCDisassembler::Fail;
24430b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
24440b57cec5SDimitry Andric     return MCDisassembler::Fail;
24450b57cec5SDimitry Andric   return S;
24460b57cec5SDimitry Andric }
24470b57cec5SDimitry Andric 
244881ad6265SDimitry Andric static DecodeStatus
DecodeMemMultipleWritebackInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)244981ad6265SDimitry Andric DecodeMemMultipleWritebackInstruction(MCInst &Inst, unsigned Insn,
245081ad6265SDimitry Andric                                       uint64_t Address,
245181ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
24520b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
24550b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
24560b57cec5SDimitry Andric   unsigned reglist = fieldFromInstruction(Insn, 0, 16);
24570b57cec5SDimitry Andric 
24580b57cec5SDimitry Andric   if (pred == 0xF) {
24590b57cec5SDimitry Andric     // Ambiguous with RFE and SRS
24600b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
24610b57cec5SDimitry Andric       case ARM::LDMDA:
24620b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDA);
24630b57cec5SDimitry Andric         break;
24640b57cec5SDimitry Andric       case ARM::LDMDA_UPD:
24650b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDA_UPD);
24660b57cec5SDimitry Andric         break;
24670b57cec5SDimitry Andric       case ARM::LDMDB:
24680b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDB);
24690b57cec5SDimitry Andric         break;
24700b57cec5SDimitry Andric       case ARM::LDMDB_UPD:
24710b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDB_UPD);
24720b57cec5SDimitry Andric         break;
24730b57cec5SDimitry Andric       case ARM::LDMIA:
24740b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIA);
24750b57cec5SDimitry Andric         break;
24760b57cec5SDimitry Andric       case ARM::LDMIA_UPD:
24770b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIA_UPD);
24780b57cec5SDimitry Andric         break;
24790b57cec5SDimitry Andric       case ARM::LDMIB:
24800b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIB);
24810b57cec5SDimitry Andric         break;
24820b57cec5SDimitry Andric       case ARM::LDMIB_UPD:
24830b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIB_UPD);
24840b57cec5SDimitry Andric         break;
24850b57cec5SDimitry Andric       case ARM::STMDA:
24860b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDA);
24870b57cec5SDimitry Andric         break;
24880b57cec5SDimitry Andric       case ARM::STMDA_UPD:
24890b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDA_UPD);
24900b57cec5SDimitry Andric         break;
24910b57cec5SDimitry Andric       case ARM::STMDB:
24920b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDB);
24930b57cec5SDimitry Andric         break;
24940b57cec5SDimitry Andric       case ARM::STMDB_UPD:
24950b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDB_UPD);
24960b57cec5SDimitry Andric         break;
24970b57cec5SDimitry Andric       case ARM::STMIA:
24980b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIA);
24990b57cec5SDimitry Andric         break;
25000b57cec5SDimitry Andric       case ARM::STMIA_UPD:
25010b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIA_UPD);
25020b57cec5SDimitry Andric         break;
25030b57cec5SDimitry Andric       case ARM::STMIB:
25040b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIB);
25050b57cec5SDimitry Andric         break;
25060b57cec5SDimitry Andric       case ARM::STMIB_UPD:
25070b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIB_UPD);
25080b57cec5SDimitry Andric         break;
25090b57cec5SDimitry Andric       default:
25100b57cec5SDimitry Andric         return MCDisassembler::Fail;
25110b57cec5SDimitry Andric     }
25120b57cec5SDimitry Andric 
25130b57cec5SDimitry Andric     // For stores (which become SRS's, the only operand is the mode.
25140b57cec5SDimitry Andric     if (fieldFromInstruction(Insn, 20, 1) == 0) {
25150b57cec5SDimitry Andric       // Check SRS encoding constraints
25160b57cec5SDimitry Andric       if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
25170b57cec5SDimitry Andric             fieldFromInstruction(Insn, 20, 1) == 0))
25180b57cec5SDimitry Andric         return MCDisassembler::Fail;
25190b57cec5SDimitry Andric 
25200b57cec5SDimitry Andric       Inst.addOperand(
25210b57cec5SDimitry Andric           MCOperand::createImm(fieldFromInstruction(Insn, 0, 4)));
25220b57cec5SDimitry Andric       return S;
25230b57cec5SDimitry Andric     }
25240b57cec5SDimitry Andric 
25250b57cec5SDimitry Andric     return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
25260b57cec5SDimitry Andric   }
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25290b57cec5SDimitry Andric     return MCDisassembler::Fail;
25300b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25310b57cec5SDimitry Andric     return MCDisassembler::Fail; // Tied
25320b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
25330b57cec5SDimitry Andric     return MCDisassembler::Fail;
25340b57cec5SDimitry Andric   if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
25350b57cec5SDimitry Andric     return MCDisassembler::Fail;
25360b57cec5SDimitry Andric 
25370b57cec5SDimitry Andric   return S;
25380b57cec5SDimitry Andric }
25390b57cec5SDimitry Andric 
25400b57cec5SDimitry Andric // Check for UNPREDICTABLE predicated ESB instruction
DecodeHINTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)25410b57cec5SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
254281ad6265SDimitry Andric                                           uint64_t Address,
254381ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
25440b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
25450b57cec5SDimitry Andric   unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
25460b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
25470b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
25480b57cec5SDimitry Andric 
25490b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm8));
25520b57cec5SDimitry Andric 
25530b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
25540b57cec5SDimitry Andric     return MCDisassembler::Fail;
25550b57cec5SDimitry Andric 
25560b57cec5SDimitry Andric   // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
25570b57cec5SDimitry Andric   // so all predicates should be allowed.
25580b57cec5SDimitry Andric   if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
25590b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
25600b57cec5SDimitry Andric 
25610b57cec5SDimitry Andric   return S;
25620b57cec5SDimitry Andric }
25630b57cec5SDimitry Andric 
DecodeCPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)25640b57cec5SDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
256581ad6265SDimitry Andric                                          uint64_t Address,
256681ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
25670b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 18, 2);
25680b57cec5SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 17, 1);
25690b57cec5SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 6, 3);
25700b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25730b57cec5SDimitry Andric 
25740b57cec5SDimitry Andric   // This decoder is called from multiple location that do not check
25750b57cec5SDimitry Andric   // the full encoding is valid before they do.
25760b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 5, 1) != 0 ||
25770b57cec5SDimitry Andric       fieldFromInstruction(Insn, 16, 1) != 0 ||
25780b57cec5SDimitry Andric       fieldFromInstruction(Insn, 20, 8) != 0x10)
25790b57cec5SDimitry Andric     return MCDisassembler::Fail;
25800b57cec5SDimitry Andric 
25810b57cec5SDimitry Andric   // imod == '01' --> UNPREDICTABLE
25820b57cec5SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
25830b57cec5SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
25840b57cec5SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
25850b57cec5SDimitry Andric 
25860b57cec5SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
25870b57cec5SDimitry Andric 
25880b57cec5SDimitry Andric   if (imod && M) {
25890b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS3p);
25900b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
25910b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
25920b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
25930b57cec5SDimitry Andric   } else if (imod && !M) {
25940b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS2p);
25950b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
25960b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
25970b57cec5SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
25980b57cec5SDimitry Andric   } else if (!imod && M) {
25990b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
26000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26010b57cec5SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
26020b57cec5SDimitry Andric   } else {
26030b57cec5SDimitry Andric     // imod == '00' && M == '0' --> UNPREDICTABLE
26040b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
26050b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26060b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
26070b57cec5SDimitry Andric   }
26080b57cec5SDimitry Andric 
26090b57cec5SDimitry Andric   return S;
26100b57cec5SDimitry Andric }
26110b57cec5SDimitry Andric 
DecodeT2CPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)26120b57cec5SDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
261381ad6265SDimitry Andric                                            uint64_t Address,
261481ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
26150b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 9, 2);
26160b57cec5SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 8, 1);
26170b57cec5SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 5, 3);
26180b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
26190b57cec5SDimitry Andric 
26200b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26210b57cec5SDimitry Andric 
26220b57cec5SDimitry Andric   // imod == '01' --> UNPREDICTABLE
26230b57cec5SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
26240b57cec5SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
26250b57cec5SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
26260b57cec5SDimitry Andric 
26270b57cec5SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
26280b57cec5SDimitry Andric 
26290b57cec5SDimitry Andric   if (imod && M) {
26300b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS3p);
26310b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
26320b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
26330b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26340b57cec5SDimitry Andric   } else if (imod && !M) {
26350b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS2p);
26360b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
26370b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
26380b57cec5SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
26390b57cec5SDimitry Andric   } else if (!imod && M) {
26400b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS1p);
26410b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26420b57cec5SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
26430b57cec5SDimitry Andric   } else {
26440b57cec5SDimitry Andric     // imod == '00' && M == '0' --> this is a HINT instruction
26450b57cec5SDimitry Andric     int imm = fieldFromInstruction(Insn, 0, 8);
26460b57cec5SDimitry Andric     // HINT are defined only for immediate in [0..4]
26470b57cec5SDimitry Andric     if(imm > 4) return MCDisassembler::Fail;
26480b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2HINT);
26490b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
26500b57cec5SDimitry Andric   }
26510b57cec5SDimitry Andric 
26520b57cec5SDimitry Andric   return S;
26530b57cec5SDimitry Andric }
26540b57cec5SDimitry Andric 
265581ad6265SDimitry Andric static DecodeStatus
DecodeT2HintSpaceInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)265681ad6265SDimitry Andric DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
265781ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
26584824e7fdSDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
26594824e7fdSDimitry Andric 
26604824e7fdSDimitry Andric   unsigned Opcode = ARM::t2HINT;
26614824e7fdSDimitry Andric 
26624824e7fdSDimitry Andric   if (imm == 0x0D) {
26634824e7fdSDimitry Andric     Opcode = ARM::t2PACBTI;
26644824e7fdSDimitry Andric   } else if (imm == 0x1D) {
26654824e7fdSDimitry Andric     Opcode = ARM::t2PAC;
26664824e7fdSDimitry Andric   } else if (imm == 0x2D) {
26674824e7fdSDimitry Andric     Opcode = ARM::t2AUT;
26684824e7fdSDimitry Andric   } else if (imm == 0x0F) {
26694824e7fdSDimitry Andric     Opcode = ARM::t2BTI;
26704824e7fdSDimitry Andric   }
26714824e7fdSDimitry Andric 
26724824e7fdSDimitry Andric   Inst.setOpcode(Opcode);
26734824e7fdSDimitry Andric   if (Opcode == ARM::t2HINT) {
26744824e7fdSDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
26754824e7fdSDimitry Andric   }
26764824e7fdSDimitry Andric 
26774824e7fdSDimitry Andric   return MCDisassembler::Success;
26784824e7fdSDimitry Andric }
26794824e7fdSDimitry Andric 
DecodeT2MOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)26800b57cec5SDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
268181ad6265SDimitry Andric                                              uint64_t Address,
268281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
26830b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26840b57cec5SDimitry Andric 
26850b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 8, 4);
26860b57cec5SDimitry Andric   unsigned imm = 0;
26870b57cec5SDimitry Andric 
26880b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
26890b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
26900b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
26910b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
26920b57cec5SDimitry Andric 
26930b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::t2MOVTi16)
26940b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
26950b57cec5SDimitry Andric       return MCDisassembler::Fail;
26960b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
26970b57cec5SDimitry Andric     return MCDisassembler::Fail;
26980b57cec5SDimitry Andric 
26990b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
27000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
27010b57cec5SDimitry Andric 
27020b57cec5SDimitry Andric   return S;
27030b57cec5SDimitry Andric }
27040b57cec5SDimitry Andric 
DecodeArmMOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)27050b57cec5SDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
270681ad6265SDimitry Andric                                               uint64_t Address,
270781ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
27080b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27090b57cec5SDimitry Andric 
27100b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
27110b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
27120b57cec5SDimitry Andric   unsigned imm = 0;
27130b57cec5SDimitry Andric 
27140b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
27150b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
27160b57cec5SDimitry Andric 
27170b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MOVTi16)
27180b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
27190b57cec5SDimitry Andric       return MCDisassembler::Fail;
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
27220b57cec5SDimitry Andric     return MCDisassembler::Fail;
27230b57cec5SDimitry Andric 
27240b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
27250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
27260b57cec5SDimitry Andric 
27270b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
27280b57cec5SDimitry Andric     return MCDisassembler::Fail;
27290b57cec5SDimitry Andric 
27300b57cec5SDimitry Andric   return S;
27310b57cec5SDimitry Andric }
27320b57cec5SDimitry Andric 
DecodeSMLAInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)27330b57cec5SDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
273481ad6265SDimitry Andric                                           uint64_t Address,
273581ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
27360b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27370b57cec5SDimitry Andric 
27380b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 16, 4);
27390b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 0, 4);
27400b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 8, 4);
27410b57cec5SDimitry Andric   unsigned Ra = fieldFromInstruction(Insn, 12, 4);
27420b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
27430b57cec5SDimitry Andric 
27440b57cec5SDimitry Andric   if (pred == 0xF)
27450b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
27460b57cec5SDimitry Andric 
27470b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
27480b57cec5SDimitry Andric     return MCDisassembler::Fail;
27490b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
27500b57cec5SDimitry Andric     return MCDisassembler::Fail;
27510b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
27520b57cec5SDimitry Andric     return MCDisassembler::Fail;
27530b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
27540b57cec5SDimitry Andric     return MCDisassembler::Fail;
27550b57cec5SDimitry Andric 
27560b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
27570b57cec5SDimitry Andric     return MCDisassembler::Fail;
27580b57cec5SDimitry Andric 
27590b57cec5SDimitry Andric   return S;
27600b57cec5SDimitry Andric }
27610b57cec5SDimitry Andric 
DecodeTSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)27620b57cec5SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
276381ad6265SDimitry Andric                                          uint64_t Address,
276481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
27650b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27660b57cec5SDimitry Andric 
27670b57cec5SDimitry Andric   unsigned Pred = fieldFromInstruction(Insn, 28, 4);
27680b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
27690b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
27700b57cec5SDimitry Andric 
27710b57cec5SDimitry Andric   if (Pred == 0xF)
27720b57cec5SDimitry Andric     return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
27730b57cec5SDimitry Andric 
27740b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
27750b57cec5SDimitry Andric     return MCDisassembler::Fail;
27760b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
27770b57cec5SDimitry Andric     return MCDisassembler::Fail;
27780b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
27790b57cec5SDimitry Andric     return MCDisassembler::Fail;
27800b57cec5SDimitry Andric 
27810b57cec5SDimitry Andric   return S;
27820b57cec5SDimitry Andric }
27830b57cec5SDimitry Andric 
DecodeSETPANInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)27840b57cec5SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
278581ad6265SDimitry Andric                                             uint64_t Address,
278681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
27870b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27880b57cec5SDimitry Andric 
27890b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 9, 1);
27900b57cec5SDimitry Andric 
27910b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
27920b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
27930b57cec5SDimitry Andric 
27940b57cec5SDimitry Andric   if (!FeatureBits[ARM::HasV8_1aOps] ||
27950b57cec5SDimitry Andric       !FeatureBits[ARM::HasV8Ops])
27960b57cec5SDimitry Andric     return MCDisassembler::Fail;
27970b57cec5SDimitry Andric 
27980b57cec5SDimitry Andric   // Decoder can be called from DecodeTST, which does not check the full
27990b57cec5SDimitry Andric   // encoding is valid.
28000b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
28010b57cec5SDimitry Andric       fieldFromInstruction(Insn, 4,4) != 0)
28020b57cec5SDimitry Andric     return MCDisassembler::Fail;
28030b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 10,10) != 0 ||
28040b57cec5SDimitry Andric       fieldFromInstruction(Insn, 0,4) != 0)
28050b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
28060b57cec5SDimitry Andric 
28070b57cec5SDimitry Andric   Inst.setOpcode(ARM::SETPAN);
28080b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
28090b57cec5SDimitry Andric 
28100b57cec5SDimitry Andric   return S;
28110b57cec5SDimitry Andric }
28120b57cec5SDimitry Andric 
DecodeAddrModeImm12Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)28130b57cec5SDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
281481ad6265SDimitry Andric                                                uint64_t Address,
281581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
28160b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
28170b57cec5SDimitry Andric 
28180b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Val, 12, 1);
28190b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
28200b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
28210b57cec5SDimitry Andric 
28220b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
28230b57cec5SDimitry Andric     return MCDisassembler::Fail;
28240b57cec5SDimitry Andric 
28250b57cec5SDimitry Andric   if (!add) imm *= -1;
28260b57cec5SDimitry Andric   if (imm == 0 && !add) imm = INT32_MIN;
28270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
28280b57cec5SDimitry Andric   if (Rn == 15)
28290b57cec5SDimitry Andric     tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
28300b57cec5SDimitry Andric 
28310b57cec5SDimitry Andric   return S;
28320b57cec5SDimitry Andric }
28330b57cec5SDimitry Andric 
DecodeAddrMode5Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)28340b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
283581ad6265SDimitry Andric                                            uint64_t Address,
283681ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
28370b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
28380b57cec5SDimitry Andric 
28390b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
28400b57cec5SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
28410b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
28420b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
28430b57cec5SDimitry Andric 
28440b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
28450b57cec5SDimitry Andric     return MCDisassembler::Fail;
28460b57cec5SDimitry Andric 
28470b57cec5SDimitry Andric   if (U)
28480b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
28490b57cec5SDimitry Andric   else
28500b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
28510b57cec5SDimitry Andric 
28520b57cec5SDimitry Andric   return S;
28530b57cec5SDimitry Andric }
28540b57cec5SDimitry Andric 
DecodeAddrMode5FP16Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)28550b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
285681ad6265SDimitry Andric                                                uint64_t Address,
285781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
28580b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
28590b57cec5SDimitry Andric 
28600b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
28610b57cec5SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
28620b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
28630b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
28640b57cec5SDimitry Andric 
28650b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
28660b57cec5SDimitry Andric     return MCDisassembler::Fail;
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric   if (U)
28690b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm)));
28700b57cec5SDimitry Andric   else
28710b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm)));
28720b57cec5SDimitry Andric 
28730b57cec5SDimitry Andric   return S;
28740b57cec5SDimitry Andric }
28750b57cec5SDimitry Andric 
DecodeAddrMode7Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)28760b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
287781ad6265SDimitry Andric                                            uint64_t Address,
287881ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
28790b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
28800b57cec5SDimitry Andric }
28810b57cec5SDimitry Andric 
DecodeT2BInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)288281ad6265SDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
288381ad6265SDimitry Andric                                          uint64_t Address,
288481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
28850b57cec5SDimitry Andric   DecodeStatus Status = MCDisassembler::Success;
28860b57cec5SDimitry Andric 
28870b57cec5SDimitry Andric   // Note the J1 and J2 values are from the encoded instruction.  So here
28880b57cec5SDimitry Andric   // change them to I1 and I2 values via as documented:
28890b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
28900b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
28910b57cec5SDimitry Andric   // and build the imm32 with one trailing zero as documented:
28920b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
28930b57cec5SDimitry Andric   unsigned S = fieldFromInstruction(Insn, 26, 1);
28940b57cec5SDimitry Andric   unsigned J1 = fieldFromInstruction(Insn, 13, 1);
28950b57cec5SDimitry Andric   unsigned J2 = fieldFromInstruction(Insn, 11, 1);
28960b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
28970b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
28980b57cec5SDimitry Andric   unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
28990b57cec5SDimitry Andric   unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
29000b57cec5SDimitry Andric   unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
29010b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
29020b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
29030b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
29040b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
29050b57cec5SDimitry Andric 
29060b57cec5SDimitry Andric   return Status;
29070b57cec5SDimitry Andric }
29080b57cec5SDimitry Andric 
DecodeBranchImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)290981ad6265SDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
291081ad6265SDimitry Andric                                                uint64_t Address,
291181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
29120b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29130b57cec5SDimitry Andric 
29140b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
29150b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
29160b57cec5SDimitry Andric 
29170b57cec5SDimitry Andric   if (pred == 0xF) {
29180b57cec5SDimitry Andric     Inst.setOpcode(ARM::BLXi);
29190b57cec5SDimitry Andric     imm |= fieldFromInstruction(Insn, 24, 1) << 1;
29200b57cec5SDimitry Andric     if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
29210b57cec5SDimitry Andric                                   true, 4, Inst, Decoder))
29220b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
29230b57cec5SDimitry Andric     return S;
29240b57cec5SDimitry Andric   }
29250b57cec5SDimitry Andric 
29260b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
29270b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
29280b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
2929fe6060f1SDimitry Andric 
2930fe6060f1SDimitry Andric   // We already have BL_pred for BL w/ predicate, no need to add addition
2931fe6060f1SDimitry Andric   // predicate opreands for BL
2932fe6060f1SDimitry Andric   if (Inst.getOpcode() != ARM::BL)
29330b57cec5SDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
29340b57cec5SDimitry Andric       return MCDisassembler::Fail;
29350b57cec5SDimitry Andric 
29360b57cec5SDimitry Andric   return S;
29370b57cec5SDimitry Andric }
29380b57cec5SDimitry Andric 
DecodeAddrMode6Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)29390b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
294081ad6265SDimitry Andric                                            uint64_t Address,
294181ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
29420b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29430b57cec5SDimitry Andric 
29440b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
29450b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Val, 4, 2);
29460b57cec5SDimitry Andric 
29470b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
29480b57cec5SDimitry Andric     return MCDisassembler::Fail;
29490b57cec5SDimitry Andric   if (!align)
29500b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
29510b57cec5SDimitry Andric   else
29520b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(4 << align));
29530b57cec5SDimitry Andric 
29540b57cec5SDimitry Andric   return S;
29550b57cec5SDimitry Andric }
29560b57cec5SDimitry Andric 
DecodeVLDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)29570b57cec5SDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
295881ad6265SDimitry Andric                                          uint64_t Address,
295981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
29600b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29610b57cec5SDimitry Andric 
29620b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
29630b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
29640b57cec5SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
29650b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
29660b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
29670b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
29680b57cec5SDimitry Andric 
29690b57cec5SDimitry Andric   // First output register
29700b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
29710b57cec5SDimitry Andric   case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
29720b57cec5SDimitry Andric   case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
29730b57cec5SDimitry Andric   case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
29740b57cec5SDimitry Andric   case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
29750b57cec5SDimitry Andric   case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
29760b57cec5SDimitry Andric   case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
29770b57cec5SDimitry Andric   case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
29780b57cec5SDimitry Andric   case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
29790b57cec5SDimitry Andric   case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
29800b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
29810b57cec5SDimitry Andric       return MCDisassembler::Fail;
29820b57cec5SDimitry Andric     break;
29830b57cec5SDimitry Andric   case ARM::VLD2b16:
29840b57cec5SDimitry Andric   case ARM::VLD2b32:
29850b57cec5SDimitry Andric   case ARM::VLD2b8:
29860b57cec5SDimitry Andric   case ARM::VLD2b16wb_fixed:
29870b57cec5SDimitry Andric   case ARM::VLD2b16wb_register:
29880b57cec5SDimitry Andric   case ARM::VLD2b32wb_fixed:
29890b57cec5SDimitry Andric   case ARM::VLD2b32wb_register:
29900b57cec5SDimitry Andric   case ARM::VLD2b8wb_fixed:
29910b57cec5SDimitry Andric   case ARM::VLD2b8wb_register:
29920b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
29930b57cec5SDimitry Andric       return MCDisassembler::Fail;
29940b57cec5SDimitry Andric     break;
29950b57cec5SDimitry Andric   default:
29960b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
29970b57cec5SDimitry Andric       return MCDisassembler::Fail;
29980b57cec5SDimitry Andric   }
29990b57cec5SDimitry Andric 
30000b57cec5SDimitry Andric   // Second output register
30010b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
30020b57cec5SDimitry Andric     case ARM::VLD3d8:
30030b57cec5SDimitry Andric     case ARM::VLD3d16:
30040b57cec5SDimitry Andric     case ARM::VLD3d32:
30050b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
30060b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
30070b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
30080b57cec5SDimitry Andric     case ARM::VLD4d8:
30090b57cec5SDimitry Andric     case ARM::VLD4d16:
30100b57cec5SDimitry Andric     case ARM::VLD4d32:
30110b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
30120b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
30130b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
30140b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
30150b57cec5SDimitry Andric         return MCDisassembler::Fail;
30160b57cec5SDimitry Andric       break;
30170b57cec5SDimitry Andric     case ARM::VLD3q8:
30180b57cec5SDimitry Andric     case ARM::VLD3q16:
30190b57cec5SDimitry Andric     case ARM::VLD3q32:
30200b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
30210b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
30220b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
30230b57cec5SDimitry Andric     case ARM::VLD4q8:
30240b57cec5SDimitry Andric     case ARM::VLD4q16:
30250b57cec5SDimitry Andric     case ARM::VLD4q32:
30260b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
30270b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
30280b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
30290b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
30300b57cec5SDimitry Andric         return MCDisassembler::Fail;
30310b57cec5SDimitry Andric       break;
30320b57cec5SDimitry Andric     default:
30330b57cec5SDimitry Andric       break;
30340b57cec5SDimitry Andric   }
30350b57cec5SDimitry Andric 
30360b57cec5SDimitry Andric   // Third output register
30370b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
30380b57cec5SDimitry Andric     case ARM::VLD3d8:
30390b57cec5SDimitry Andric     case ARM::VLD3d16:
30400b57cec5SDimitry Andric     case ARM::VLD3d32:
30410b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
30420b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
30430b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
30440b57cec5SDimitry Andric     case ARM::VLD4d8:
30450b57cec5SDimitry Andric     case ARM::VLD4d16:
30460b57cec5SDimitry Andric     case ARM::VLD4d32:
30470b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
30480b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
30490b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
30500b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
30510b57cec5SDimitry Andric         return MCDisassembler::Fail;
30520b57cec5SDimitry Andric       break;
30530b57cec5SDimitry Andric     case ARM::VLD3q8:
30540b57cec5SDimitry Andric     case ARM::VLD3q16:
30550b57cec5SDimitry Andric     case ARM::VLD3q32:
30560b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
30570b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
30580b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
30590b57cec5SDimitry Andric     case ARM::VLD4q8:
30600b57cec5SDimitry Andric     case ARM::VLD4q16:
30610b57cec5SDimitry Andric     case ARM::VLD4q32:
30620b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
30630b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
30640b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
30650b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
30660b57cec5SDimitry Andric         return MCDisassembler::Fail;
30670b57cec5SDimitry Andric       break;
30680b57cec5SDimitry Andric     default:
30690b57cec5SDimitry Andric       break;
30700b57cec5SDimitry Andric   }
30710b57cec5SDimitry Andric 
30720b57cec5SDimitry Andric   // Fourth output register
30730b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
30740b57cec5SDimitry Andric     case ARM::VLD4d8:
30750b57cec5SDimitry Andric     case ARM::VLD4d16:
30760b57cec5SDimitry Andric     case ARM::VLD4d32:
30770b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
30780b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
30790b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
30800b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
30810b57cec5SDimitry Andric         return MCDisassembler::Fail;
30820b57cec5SDimitry Andric       break;
30830b57cec5SDimitry Andric     case ARM::VLD4q8:
30840b57cec5SDimitry Andric     case ARM::VLD4q16:
30850b57cec5SDimitry Andric     case ARM::VLD4q32:
30860b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
30870b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
30880b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
30890b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
30900b57cec5SDimitry Andric         return MCDisassembler::Fail;
30910b57cec5SDimitry Andric       break;
30920b57cec5SDimitry Andric     default:
30930b57cec5SDimitry Andric       break;
30940b57cec5SDimitry Andric   }
30950b57cec5SDimitry Andric 
30960b57cec5SDimitry Andric   // Writeback operand
30970b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
30980b57cec5SDimitry Andric     case ARM::VLD1d8wb_fixed:
30990b57cec5SDimitry Andric     case ARM::VLD1d16wb_fixed:
31000b57cec5SDimitry Andric     case ARM::VLD1d32wb_fixed:
31010b57cec5SDimitry Andric     case ARM::VLD1d64wb_fixed:
31020b57cec5SDimitry Andric     case ARM::VLD1d8wb_register:
31030b57cec5SDimitry Andric     case ARM::VLD1d16wb_register:
31040b57cec5SDimitry Andric     case ARM::VLD1d32wb_register:
31050b57cec5SDimitry Andric     case ARM::VLD1d64wb_register:
31060b57cec5SDimitry Andric     case ARM::VLD1q8wb_fixed:
31070b57cec5SDimitry Andric     case ARM::VLD1q16wb_fixed:
31080b57cec5SDimitry Andric     case ARM::VLD1q32wb_fixed:
31090b57cec5SDimitry Andric     case ARM::VLD1q64wb_fixed:
31100b57cec5SDimitry Andric     case ARM::VLD1q8wb_register:
31110b57cec5SDimitry Andric     case ARM::VLD1q16wb_register:
31120b57cec5SDimitry Andric     case ARM::VLD1q32wb_register:
31130b57cec5SDimitry Andric     case ARM::VLD1q64wb_register:
31140b57cec5SDimitry Andric     case ARM::VLD1d8Twb_fixed:
31150b57cec5SDimitry Andric     case ARM::VLD1d8Twb_register:
31160b57cec5SDimitry Andric     case ARM::VLD1d16Twb_fixed:
31170b57cec5SDimitry Andric     case ARM::VLD1d16Twb_register:
31180b57cec5SDimitry Andric     case ARM::VLD1d32Twb_fixed:
31190b57cec5SDimitry Andric     case ARM::VLD1d32Twb_register:
31200b57cec5SDimitry Andric     case ARM::VLD1d64Twb_fixed:
31210b57cec5SDimitry Andric     case ARM::VLD1d64Twb_register:
31220b57cec5SDimitry Andric     case ARM::VLD1d8Qwb_fixed:
31230b57cec5SDimitry Andric     case ARM::VLD1d8Qwb_register:
31240b57cec5SDimitry Andric     case ARM::VLD1d16Qwb_fixed:
31250b57cec5SDimitry Andric     case ARM::VLD1d16Qwb_register:
31260b57cec5SDimitry Andric     case ARM::VLD1d32Qwb_fixed:
31270b57cec5SDimitry Andric     case ARM::VLD1d32Qwb_register:
31280b57cec5SDimitry Andric     case ARM::VLD1d64Qwb_fixed:
31290b57cec5SDimitry Andric     case ARM::VLD1d64Qwb_register:
31300b57cec5SDimitry Andric     case ARM::VLD2d8wb_fixed:
31310b57cec5SDimitry Andric     case ARM::VLD2d16wb_fixed:
31320b57cec5SDimitry Andric     case ARM::VLD2d32wb_fixed:
31330b57cec5SDimitry Andric     case ARM::VLD2q8wb_fixed:
31340b57cec5SDimitry Andric     case ARM::VLD2q16wb_fixed:
31350b57cec5SDimitry Andric     case ARM::VLD2q32wb_fixed:
31360b57cec5SDimitry Andric     case ARM::VLD2d8wb_register:
31370b57cec5SDimitry Andric     case ARM::VLD2d16wb_register:
31380b57cec5SDimitry Andric     case ARM::VLD2d32wb_register:
31390b57cec5SDimitry Andric     case ARM::VLD2q8wb_register:
31400b57cec5SDimitry Andric     case ARM::VLD2q16wb_register:
31410b57cec5SDimitry Andric     case ARM::VLD2q32wb_register:
31420b57cec5SDimitry Andric     case ARM::VLD2b8wb_fixed:
31430b57cec5SDimitry Andric     case ARM::VLD2b16wb_fixed:
31440b57cec5SDimitry Andric     case ARM::VLD2b32wb_fixed:
31450b57cec5SDimitry Andric     case ARM::VLD2b8wb_register:
31460b57cec5SDimitry Andric     case ARM::VLD2b16wb_register:
31470b57cec5SDimitry Andric     case ARM::VLD2b32wb_register:
31480b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
31490b57cec5SDimitry Andric       break;
31500b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
31510b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
31520b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
31530b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
31540b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
31550b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
31560b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
31570b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
31580b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
31590b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
31600b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
31610b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
31620b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
31630b57cec5SDimitry Andric         return MCDisassembler::Fail;
31640b57cec5SDimitry Andric       break;
31650b57cec5SDimitry Andric     default:
31660b57cec5SDimitry Andric       break;
31670b57cec5SDimitry Andric   }
31680b57cec5SDimitry Andric 
31690b57cec5SDimitry Andric   // AddrMode6 Base (register+alignment)
31700b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
31710b57cec5SDimitry Andric     return MCDisassembler::Fail;
31720b57cec5SDimitry Andric 
31730b57cec5SDimitry Andric   // AddrMode6 Offset (register)
31740b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
31750b57cec5SDimitry Andric   default:
31760b57cec5SDimitry Andric     // The below have been updated to have explicit am6offset split
31770b57cec5SDimitry Andric     // between fixed and register offset. For those instructions not
31780b57cec5SDimitry Andric     // yet updated, we need to add an additional reg0 operand for the
31790b57cec5SDimitry Andric     // fixed variant.
31800b57cec5SDimitry Andric     //
31810b57cec5SDimitry Andric     // The fixed offset encodes as Rm == 0xd, so we check for that.
31820b57cec5SDimitry Andric     if (Rm == 0xd) {
31830b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
31840b57cec5SDimitry Andric       break;
31850b57cec5SDimitry Andric     }
31860b57cec5SDimitry Andric     // Fall through to handle the register offset variant.
3187bdd1243dSDimitry Andric     [[fallthrough]];
31880b57cec5SDimitry Andric   case ARM::VLD1d8wb_fixed:
31890b57cec5SDimitry Andric   case ARM::VLD1d16wb_fixed:
31900b57cec5SDimitry Andric   case ARM::VLD1d32wb_fixed:
31910b57cec5SDimitry Andric   case ARM::VLD1d64wb_fixed:
31920b57cec5SDimitry Andric   case ARM::VLD1d8Twb_fixed:
31930b57cec5SDimitry Andric   case ARM::VLD1d16Twb_fixed:
31940b57cec5SDimitry Andric   case ARM::VLD1d32Twb_fixed:
31950b57cec5SDimitry Andric   case ARM::VLD1d64Twb_fixed:
31960b57cec5SDimitry Andric   case ARM::VLD1d8Qwb_fixed:
31970b57cec5SDimitry Andric   case ARM::VLD1d16Qwb_fixed:
31980b57cec5SDimitry Andric   case ARM::VLD1d32Qwb_fixed:
31990b57cec5SDimitry Andric   case ARM::VLD1d64Qwb_fixed:
32000b57cec5SDimitry Andric   case ARM::VLD1d8wb_register:
32010b57cec5SDimitry Andric   case ARM::VLD1d16wb_register:
32020b57cec5SDimitry Andric   case ARM::VLD1d32wb_register:
32030b57cec5SDimitry Andric   case ARM::VLD1d64wb_register:
32040b57cec5SDimitry Andric   case ARM::VLD1q8wb_fixed:
32050b57cec5SDimitry Andric   case ARM::VLD1q16wb_fixed:
32060b57cec5SDimitry Andric   case ARM::VLD1q32wb_fixed:
32070b57cec5SDimitry Andric   case ARM::VLD1q64wb_fixed:
32080b57cec5SDimitry Andric   case ARM::VLD1q8wb_register:
32090b57cec5SDimitry Andric   case ARM::VLD1q16wb_register:
32100b57cec5SDimitry Andric   case ARM::VLD1q32wb_register:
32110b57cec5SDimitry Andric   case ARM::VLD1q64wb_register:
32120b57cec5SDimitry Andric     // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
32130b57cec5SDimitry Andric     // variant encodes Rm == 0xf. Anything else is a register offset post-
32140b57cec5SDimitry Andric     // increment and we need to add the register operand to the instruction.
32150b57cec5SDimitry Andric     if (Rm != 0xD && Rm != 0xF &&
32160b57cec5SDimitry Andric         !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
32170b57cec5SDimitry Andric       return MCDisassembler::Fail;
32180b57cec5SDimitry Andric     break;
32190b57cec5SDimitry Andric   case ARM::VLD2d8wb_fixed:
32200b57cec5SDimitry Andric   case ARM::VLD2d16wb_fixed:
32210b57cec5SDimitry Andric   case ARM::VLD2d32wb_fixed:
32220b57cec5SDimitry Andric   case ARM::VLD2b8wb_fixed:
32230b57cec5SDimitry Andric   case ARM::VLD2b16wb_fixed:
32240b57cec5SDimitry Andric   case ARM::VLD2b32wb_fixed:
32250b57cec5SDimitry Andric   case ARM::VLD2q8wb_fixed:
32260b57cec5SDimitry Andric   case ARM::VLD2q16wb_fixed:
32270b57cec5SDimitry Andric   case ARM::VLD2q32wb_fixed:
32280b57cec5SDimitry Andric     break;
32290b57cec5SDimitry Andric   }
32300b57cec5SDimitry Andric 
32310b57cec5SDimitry Andric   return S;
32320b57cec5SDimitry Andric }
32330b57cec5SDimitry Andric 
DecodeVLDST1Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)32340b57cec5SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
323581ad6265SDimitry Andric                                             uint64_t Address,
323681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32370b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
32380b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
32390b57cec5SDimitry Andric   if (type == 6 && (align & 2)) return MCDisassembler::Fail;
32400b57cec5SDimitry Andric   if (type == 7 && (align & 2)) return MCDisassembler::Fail;
32410b57cec5SDimitry Andric   if (type == 10 && align == 3) return MCDisassembler::Fail;
32420b57cec5SDimitry Andric 
32430b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32440b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32450b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32460b57cec5SDimitry Andric }
32470b57cec5SDimitry Andric 
DecodeVLDST2Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)32480b57cec5SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
324981ad6265SDimitry Andric                                             uint64_t Address,
325081ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32510b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
32520b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
32530b57cec5SDimitry Andric 
32540b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
32550b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
32560b57cec5SDimitry Andric   if (type == 8 && align == 3) return MCDisassembler::Fail;
32570b57cec5SDimitry Andric   if (type == 9 && align == 3) return MCDisassembler::Fail;
32580b57cec5SDimitry Andric 
32590b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32600b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32610b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32620b57cec5SDimitry Andric }
32630b57cec5SDimitry Andric 
DecodeVLDST3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)32640b57cec5SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
326581ad6265SDimitry Andric                                             uint64_t Address,
326681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32670b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
32680b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
32690b57cec5SDimitry Andric 
32700b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
32710b57cec5SDimitry Andric   if (align & 2) return MCDisassembler::Fail;
32720b57cec5SDimitry Andric 
32730b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32740b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32750b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32760b57cec5SDimitry Andric }
32770b57cec5SDimitry Andric 
DecodeVLDST4Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)32780b57cec5SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
327981ad6265SDimitry Andric                                             uint64_t Address,
328081ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32810b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
32820b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
32830b57cec5SDimitry Andric 
32840b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32850b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32860b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32870b57cec5SDimitry Andric }
32880b57cec5SDimitry Andric 
DecodeVSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)32890b57cec5SDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
329081ad6265SDimitry Andric                                          uint64_t Address,
329181ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
32920b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
32930b57cec5SDimitry Andric 
32940b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
32950b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
32960b57cec5SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
32970b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
32980b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
32990b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
33000b57cec5SDimitry Andric 
33010b57cec5SDimitry Andric   // Writeback Operand
33020b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
33030b57cec5SDimitry Andric     case ARM::VST1d8wb_fixed:
33040b57cec5SDimitry Andric     case ARM::VST1d16wb_fixed:
33050b57cec5SDimitry Andric     case ARM::VST1d32wb_fixed:
33060b57cec5SDimitry Andric     case ARM::VST1d64wb_fixed:
33070b57cec5SDimitry Andric     case ARM::VST1d8wb_register:
33080b57cec5SDimitry Andric     case ARM::VST1d16wb_register:
33090b57cec5SDimitry Andric     case ARM::VST1d32wb_register:
33100b57cec5SDimitry Andric     case ARM::VST1d64wb_register:
33110b57cec5SDimitry Andric     case ARM::VST1q8wb_fixed:
33120b57cec5SDimitry Andric     case ARM::VST1q16wb_fixed:
33130b57cec5SDimitry Andric     case ARM::VST1q32wb_fixed:
33140b57cec5SDimitry Andric     case ARM::VST1q64wb_fixed:
33150b57cec5SDimitry Andric     case ARM::VST1q8wb_register:
33160b57cec5SDimitry Andric     case ARM::VST1q16wb_register:
33170b57cec5SDimitry Andric     case ARM::VST1q32wb_register:
33180b57cec5SDimitry Andric     case ARM::VST1q64wb_register:
33190b57cec5SDimitry Andric     case ARM::VST1d8Twb_fixed:
33200b57cec5SDimitry Andric     case ARM::VST1d16Twb_fixed:
33210b57cec5SDimitry Andric     case ARM::VST1d32Twb_fixed:
33220b57cec5SDimitry Andric     case ARM::VST1d64Twb_fixed:
33230b57cec5SDimitry Andric     case ARM::VST1d8Twb_register:
33240b57cec5SDimitry Andric     case ARM::VST1d16Twb_register:
33250b57cec5SDimitry Andric     case ARM::VST1d32Twb_register:
33260b57cec5SDimitry Andric     case ARM::VST1d64Twb_register:
33270b57cec5SDimitry Andric     case ARM::VST1d8Qwb_fixed:
33280b57cec5SDimitry Andric     case ARM::VST1d16Qwb_fixed:
33290b57cec5SDimitry Andric     case ARM::VST1d32Qwb_fixed:
33300b57cec5SDimitry Andric     case ARM::VST1d64Qwb_fixed:
33310b57cec5SDimitry Andric     case ARM::VST1d8Qwb_register:
33320b57cec5SDimitry Andric     case ARM::VST1d16Qwb_register:
33330b57cec5SDimitry Andric     case ARM::VST1d32Qwb_register:
33340b57cec5SDimitry Andric     case ARM::VST1d64Qwb_register:
33350b57cec5SDimitry Andric     case ARM::VST2d8wb_fixed:
33360b57cec5SDimitry Andric     case ARM::VST2d16wb_fixed:
33370b57cec5SDimitry Andric     case ARM::VST2d32wb_fixed:
33380b57cec5SDimitry Andric     case ARM::VST2d8wb_register:
33390b57cec5SDimitry Andric     case ARM::VST2d16wb_register:
33400b57cec5SDimitry Andric     case ARM::VST2d32wb_register:
33410b57cec5SDimitry Andric     case ARM::VST2q8wb_fixed:
33420b57cec5SDimitry Andric     case ARM::VST2q16wb_fixed:
33430b57cec5SDimitry Andric     case ARM::VST2q32wb_fixed:
33440b57cec5SDimitry Andric     case ARM::VST2q8wb_register:
33450b57cec5SDimitry Andric     case ARM::VST2q16wb_register:
33460b57cec5SDimitry Andric     case ARM::VST2q32wb_register:
33470b57cec5SDimitry Andric     case ARM::VST2b8wb_fixed:
33480b57cec5SDimitry Andric     case ARM::VST2b16wb_fixed:
33490b57cec5SDimitry Andric     case ARM::VST2b32wb_fixed:
33500b57cec5SDimitry Andric     case ARM::VST2b8wb_register:
33510b57cec5SDimitry Andric     case ARM::VST2b16wb_register:
33520b57cec5SDimitry Andric     case ARM::VST2b32wb_register:
33530b57cec5SDimitry Andric       if (Rm == 0xF)
33540b57cec5SDimitry Andric         return MCDisassembler::Fail;
33550b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
33560b57cec5SDimitry Andric       break;
33570b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
33580b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
33590b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
33600b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
33610b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
33620b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
33630b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
33640b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
33650b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
33660b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
33670b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
33680b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
33690b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
33700b57cec5SDimitry Andric         return MCDisassembler::Fail;
33710b57cec5SDimitry Andric       break;
33720b57cec5SDimitry Andric     default:
33730b57cec5SDimitry Andric       break;
33740b57cec5SDimitry Andric   }
33750b57cec5SDimitry Andric 
33760b57cec5SDimitry Andric   // AddrMode6 Base (register+alignment)
33770b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
33780b57cec5SDimitry Andric     return MCDisassembler::Fail;
33790b57cec5SDimitry Andric 
33800b57cec5SDimitry Andric   // AddrMode6 Offset (register)
33810b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
33820b57cec5SDimitry Andric     default:
33830b57cec5SDimitry Andric       if (Rm == 0xD)
33840b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createReg(0));
33850b57cec5SDimitry Andric       else if (Rm != 0xF) {
33860b57cec5SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
33870b57cec5SDimitry Andric           return MCDisassembler::Fail;
33880b57cec5SDimitry Andric       }
33890b57cec5SDimitry Andric       break;
33900b57cec5SDimitry Andric     case ARM::VST1d8wb_fixed:
33910b57cec5SDimitry Andric     case ARM::VST1d16wb_fixed:
33920b57cec5SDimitry Andric     case ARM::VST1d32wb_fixed:
33930b57cec5SDimitry Andric     case ARM::VST1d64wb_fixed:
33940b57cec5SDimitry Andric     case ARM::VST1q8wb_fixed:
33950b57cec5SDimitry Andric     case ARM::VST1q16wb_fixed:
33960b57cec5SDimitry Andric     case ARM::VST1q32wb_fixed:
33970b57cec5SDimitry Andric     case ARM::VST1q64wb_fixed:
33980b57cec5SDimitry Andric     case ARM::VST1d8Twb_fixed:
33990b57cec5SDimitry Andric     case ARM::VST1d16Twb_fixed:
34000b57cec5SDimitry Andric     case ARM::VST1d32Twb_fixed:
34010b57cec5SDimitry Andric     case ARM::VST1d64Twb_fixed:
34020b57cec5SDimitry Andric     case ARM::VST1d8Qwb_fixed:
34030b57cec5SDimitry Andric     case ARM::VST1d16Qwb_fixed:
34040b57cec5SDimitry Andric     case ARM::VST1d32Qwb_fixed:
34050b57cec5SDimitry Andric     case ARM::VST1d64Qwb_fixed:
34060b57cec5SDimitry Andric     case ARM::VST2d8wb_fixed:
34070b57cec5SDimitry Andric     case ARM::VST2d16wb_fixed:
34080b57cec5SDimitry Andric     case ARM::VST2d32wb_fixed:
34090b57cec5SDimitry Andric     case ARM::VST2q8wb_fixed:
34100b57cec5SDimitry Andric     case ARM::VST2q16wb_fixed:
34110b57cec5SDimitry Andric     case ARM::VST2q32wb_fixed:
34120b57cec5SDimitry Andric     case ARM::VST2b8wb_fixed:
34130b57cec5SDimitry Andric     case ARM::VST2b16wb_fixed:
34140b57cec5SDimitry Andric     case ARM::VST2b32wb_fixed:
34150b57cec5SDimitry Andric       break;
34160b57cec5SDimitry Andric   }
34170b57cec5SDimitry Andric 
34180b57cec5SDimitry Andric   // First input register
34190b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
34200b57cec5SDimitry Andric   case ARM::VST1q16:
34210b57cec5SDimitry Andric   case ARM::VST1q32:
34220b57cec5SDimitry Andric   case ARM::VST1q64:
34230b57cec5SDimitry Andric   case ARM::VST1q8:
34240b57cec5SDimitry Andric   case ARM::VST1q16wb_fixed:
34250b57cec5SDimitry Andric   case ARM::VST1q16wb_register:
34260b57cec5SDimitry Andric   case ARM::VST1q32wb_fixed:
34270b57cec5SDimitry Andric   case ARM::VST1q32wb_register:
34280b57cec5SDimitry Andric   case ARM::VST1q64wb_fixed:
34290b57cec5SDimitry Andric   case ARM::VST1q64wb_register:
34300b57cec5SDimitry Andric   case ARM::VST1q8wb_fixed:
34310b57cec5SDimitry Andric   case ARM::VST1q8wb_register:
34320b57cec5SDimitry Andric   case ARM::VST2d16:
34330b57cec5SDimitry Andric   case ARM::VST2d32:
34340b57cec5SDimitry Andric   case ARM::VST2d8:
34350b57cec5SDimitry Andric   case ARM::VST2d16wb_fixed:
34360b57cec5SDimitry Andric   case ARM::VST2d16wb_register:
34370b57cec5SDimitry Andric   case ARM::VST2d32wb_fixed:
34380b57cec5SDimitry Andric   case ARM::VST2d32wb_register:
34390b57cec5SDimitry Andric   case ARM::VST2d8wb_fixed:
34400b57cec5SDimitry Andric   case ARM::VST2d8wb_register:
34410b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
34420b57cec5SDimitry Andric       return MCDisassembler::Fail;
34430b57cec5SDimitry Andric     break;
34440b57cec5SDimitry Andric   case ARM::VST2b16:
34450b57cec5SDimitry Andric   case ARM::VST2b32:
34460b57cec5SDimitry Andric   case ARM::VST2b8:
34470b57cec5SDimitry Andric   case ARM::VST2b16wb_fixed:
34480b57cec5SDimitry Andric   case ARM::VST2b16wb_register:
34490b57cec5SDimitry Andric   case ARM::VST2b32wb_fixed:
34500b57cec5SDimitry Andric   case ARM::VST2b32wb_register:
34510b57cec5SDimitry Andric   case ARM::VST2b8wb_fixed:
34520b57cec5SDimitry Andric   case ARM::VST2b8wb_register:
34530b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
34540b57cec5SDimitry Andric       return MCDisassembler::Fail;
34550b57cec5SDimitry Andric     break;
34560b57cec5SDimitry Andric   default:
34570b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
34580b57cec5SDimitry Andric       return MCDisassembler::Fail;
34590b57cec5SDimitry Andric   }
34600b57cec5SDimitry Andric 
34610b57cec5SDimitry Andric   // Second input register
34620b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
34630b57cec5SDimitry Andric     case ARM::VST3d8:
34640b57cec5SDimitry Andric     case ARM::VST3d16:
34650b57cec5SDimitry Andric     case ARM::VST3d32:
34660b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
34670b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
34680b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
34690b57cec5SDimitry Andric     case ARM::VST4d8:
34700b57cec5SDimitry Andric     case ARM::VST4d16:
34710b57cec5SDimitry Andric     case ARM::VST4d32:
34720b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
34730b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
34740b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
34750b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
34760b57cec5SDimitry Andric         return MCDisassembler::Fail;
34770b57cec5SDimitry Andric       break;
34780b57cec5SDimitry Andric     case ARM::VST3q8:
34790b57cec5SDimitry Andric     case ARM::VST3q16:
34800b57cec5SDimitry Andric     case ARM::VST3q32:
34810b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
34820b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
34830b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
34840b57cec5SDimitry Andric     case ARM::VST4q8:
34850b57cec5SDimitry Andric     case ARM::VST4q16:
34860b57cec5SDimitry Andric     case ARM::VST4q32:
34870b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
34880b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
34890b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
34900b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
34910b57cec5SDimitry Andric         return MCDisassembler::Fail;
34920b57cec5SDimitry Andric       break;
34930b57cec5SDimitry Andric     default:
34940b57cec5SDimitry Andric       break;
34950b57cec5SDimitry Andric   }
34960b57cec5SDimitry Andric 
34970b57cec5SDimitry Andric   // Third input register
34980b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
34990b57cec5SDimitry Andric     case ARM::VST3d8:
35000b57cec5SDimitry Andric     case ARM::VST3d16:
35010b57cec5SDimitry Andric     case ARM::VST3d32:
35020b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
35030b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
35040b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
35050b57cec5SDimitry Andric     case ARM::VST4d8:
35060b57cec5SDimitry Andric     case ARM::VST4d16:
35070b57cec5SDimitry Andric     case ARM::VST4d32:
35080b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
35090b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
35100b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
35110b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
35120b57cec5SDimitry Andric         return MCDisassembler::Fail;
35130b57cec5SDimitry Andric       break;
35140b57cec5SDimitry Andric     case ARM::VST3q8:
35150b57cec5SDimitry Andric     case ARM::VST3q16:
35160b57cec5SDimitry Andric     case ARM::VST3q32:
35170b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
35180b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
35190b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
35200b57cec5SDimitry Andric     case ARM::VST4q8:
35210b57cec5SDimitry Andric     case ARM::VST4q16:
35220b57cec5SDimitry Andric     case ARM::VST4q32:
35230b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
35240b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
35250b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
35260b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
35270b57cec5SDimitry Andric         return MCDisassembler::Fail;
35280b57cec5SDimitry Andric       break;
35290b57cec5SDimitry Andric     default:
35300b57cec5SDimitry Andric       break;
35310b57cec5SDimitry Andric   }
35320b57cec5SDimitry Andric 
35330b57cec5SDimitry Andric   // Fourth input register
35340b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
35350b57cec5SDimitry Andric     case ARM::VST4d8:
35360b57cec5SDimitry Andric     case ARM::VST4d16:
35370b57cec5SDimitry Andric     case ARM::VST4d32:
35380b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
35390b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
35400b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
35410b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
35420b57cec5SDimitry Andric         return MCDisassembler::Fail;
35430b57cec5SDimitry Andric       break;
35440b57cec5SDimitry Andric     case ARM::VST4q8:
35450b57cec5SDimitry Andric     case ARM::VST4q16:
35460b57cec5SDimitry Andric     case ARM::VST4q32:
35470b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
35480b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
35490b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
35500b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
35510b57cec5SDimitry Andric         return MCDisassembler::Fail;
35520b57cec5SDimitry Andric       break;
35530b57cec5SDimitry Andric     default:
35540b57cec5SDimitry Andric       break;
35550b57cec5SDimitry Andric   }
35560b57cec5SDimitry Andric 
35570b57cec5SDimitry Andric   return S;
35580b57cec5SDimitry Andric }
35590b57cec5SDimitry Andric 
DecodeVLD1DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)35600b57cec5SDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
356181ad6265SDimitry Andric                                              uint64_t Address,
356281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
35630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
35640b57cec5SDimitry Andric 
35650b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
35660b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
35670b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
35680b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
35690b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
35700b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
35710b57cec5SDimitry Andric 
35720b57cec5SDimitry Andric   if (size == 0 && align == 1)
35730b57cec5SDimitry Andric     return MCDisassembler::Fail;
35740b57cec5SDimitry Andric   align *= (1 << size);
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
35770b57cec5SDimitry Andric   case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
35780b57cec5SDimitry Andric   case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
35790b57cec5SDimitry Andric   case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
35800b57cec5SDimitry Andric   case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
35810b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
35820b57cec5SDimitry Andric       return MCDisassembler::Fail;
35830b57cec5SDimitry Andric     break;
35840b57cec5SDimitry Andric   default:
35850b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
35860b57cec5SDimitry Andric       return MCDisassembler::Fail;
35870b57cec5SDimitry Andric     break;
35880b57cec5SDimitry Andric   }
35890b57cec5SDimitry Andric   if (Rm != 0xF) {
35900b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
35910b57cec5SDimitry Andric       return MCDisassembler::Fail;
35920b57cec5SDimitry Andric   }
35930b57cec5SDimitry Andric 
35940b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
35950b57cec5SDimitry Andric     return MCDisassembler::Fail;
35960b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
35970b57cec5SDimitry Andric 
35980b57cec5SDimitry Andric   // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
35990b57cec5SDimitry Andric   // variant encodes Rm == 0xf. Anything else is a register offset post-
36000b57cec5SDimitry Andric   // increment and we need to add the register operand to the instruction.
36010b57cec5SDimitry Andric   if (Rm != 0xD && Rm != 0xF &&
36020b57cec5SDimitry Andric       !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
36030b57cec5SDimitry Andric     return MCDisassembler::Fail;
36040b57cec5SDimitry Andric 
36050b57cec5SDimitry Andric   return S;
36060b57cec5SDimitry Andric }
36070b57cec5SDimitry Andric 
DecodeVLD2DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)36080b57cec5SDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
360981ad6265SDimitry Andric                                              uint64_t Address,
361081ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
36110b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36120b57cec5SDimitry Andric 
36130b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
36140b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
36150b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
36160b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
36170b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
36180b57cec5SDimitry Andric   unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
36190b57cec5SDimitry Andric   align *= 2*size;
36200b57cec5SDimitry Andric 
36210b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
36220b57cec5SDimitry Andric   case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
36230b57cec5SDimitry Andric   case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
36240b57cec5SDimitry Andric   case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
36250b57cec5SDimitry Andric   case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
36260b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
36270b57cec5SDimitry Andric       return MCDisassembler::Fail;
36280b57cec5SDimitry Andric     break;
36290b57cec5SDimitry Andric   case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
36300b57cec5SDimitry Andric   case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
36310b57cec5SDimitry Andric   case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
36320b57cec5SDimitry Andric   case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
36330b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
36340b57cec5SDimitry Andric       return MCDisassembler::Fail;
36350b57cec5SDimitry Andric     break;
36360b57cec5SDimitry Andric   default:
36370b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
36380b57cec5SDimitry Andric       return MCDisassembler::Fail;
36390b57cec5SDimitry Andric     break;
36400b57cec5SDimitry Andric   }
36410b57cec5SDimitry Andric 
36420b57cec5SDimitry Andric   if (Rm != 0xF)
36430b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
36440b57cec5SDimitry Andric 
36450b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
36460b57cec5SDimitry Andric     return MCDisassembler::Fail;
36470b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
36480b57cec5SDimitry Andric 
36490b57cec5SDimitry Andric   if (Rm != 0xD && Rm != 0xF) {
36500b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
36510b57cec5SDimitry Andric       return MCDisassembler::Fail;
36520b57cec5SDimitry Andric   }
36530b57cec5SDimitry Andric 
36540b57cec5SDimitry Andric   return S;
36550b57cec5SDimitry Andric }
36560b57cec5SDimitry Andric 
DecodeVLD3DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)36570b57cec5SDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
365881ad6265SDimitry Andric                                              uint64_t Address,
365981ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
36600b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36610b57cec5SDimitry Andric 
36620b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
36630b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
36640b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
36650b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
36660b57cec5SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
36670b57cec5SDimitry Andric 
36680b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
36690b57cec5SDimitry Andric     return MCDisassembler::Fail;
36700b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
36710b57cec5SDimitry Andric     return MCDisassembler::Fail;
36720b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
36730b57cec5SDimitry Andric     return MCDisassembler::Fail;
36740b57cec5SDimitry Andric   if (Rm != 0xF) {
36750b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
36760b57cec5SDimitry Andric       return MCDisassembler::Fail;
36770b57cec5SDimitry Andric   }
36780b57cec5SDimitry Andric 
36790b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
36800b57cec5SDimitry Andric     return MCDisassembler::Fail;
36810b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
36820b57cec5SDimitry Andric 
36830b57cec5SDimitry Andric   if (Rm == 0xD)
36840b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
36850b57cec5SDimitry Andric   else if (Rm != 0xF) {
36860b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
36870b57cec5SDimitry Andric       return MCDisassembler::Fail;
36880b57cec5SDimitry Andric   }
36890b57cec5SDimitry Andric 
36900b57cec5SDimitry Andric   return S;
36910b57cec5SDimitry Andric }
36920b57cec5SDimitry Andric 
DecodeVLD4DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)36930b57cec5SDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
369481ad6265SDimitry Andric                                              uint64_t Address,
369581ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
36960b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36970b57cec5SDimitry Andric 
36980b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
36990b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
37000b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
37010b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
37020b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
37030b57cec5SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
37040b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
37050b57cec5SDimitry Andric 
37060b57cec5SDimitry Andric   if (size == 0x3) {
37070b57cec5SDimitry Andric     if (align == 0)
37080b57cec5SDimitry Andric       return MCDisassembler::Fail;
37090b57cec5SDimitry Andric     align = 16;
37100b57cec5SDimitry Andric   } else {
37110b57cec5SDimitry Andric     if (size == 2) {
37120b57cec5SDimitry Andric       align *= 8;
37130b57cec5SDimitry Andric     } else {
37140b57cec5SDimitry Andric       size = 1 << size;
37150b57cec5SDimitry Andric       align *= 4*size;
37160b57cec5SDimitry Andric     }
37170b57cec5SDimitry Andric   }
37180b57cec5SDimitry Andric 
37190b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
37200b57cec5SDimitry Andric     return MCDisassembler::Fail;
37210b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
37220b57cec5SDimitry Andric     return MCDisassembler::Fail;
37230b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
37240b57cec5SDimitry Andric     return MCDisassembler::Fail;
37250b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
37260b57cec5SDimitry Andric     return MCDisassembler::Fail;
37270b57cec5SDimitry Andric   if (Rm != 0xF) {
37280b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37290b57cec5SDimitry Andric       return MCDisassembler::Fail;
37300b57cec5SDimitry Andric   }
37310b57cec5SDimitry Andric 
37320b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37330b57cec5SDimitry Andric     return MCDisassembler::Fail;
37340b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
37350b57cec5SDimitry Andric 
37360b57cec5SDimitry Andric   if (Rm == 0xD)
37370b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
37380b57cec5SDimitry Andric   else if (Rm != 0xF) {
37390b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
37400b57cec5SDimitry Andric       return MCDisassembler::Fail;
37410b57cec5SDimitry Andric   }
37420b57cec5SDimitry Andric 
37430b57cec5SDimitry Andric   return S;
37440b57cec5SDimitry Andric }
37450b57cec5SDimitry Andric 
DecodeVMOVModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)374681ad6265SDimitry Andric static DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst, unsigned Insn,
374781ad6265SDimitry Andric                                                 uint64_t Address,
374881ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
37490b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37500b57cec5SDimitry Andric 
37510b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
37520b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
37530b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
37540b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
37550b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 24, 1) << 7;
37560b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 8, 4) << 8;
37570b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1) << 12;
37580b57cec5SDimitry Andric   unsigned Q = fieldFromInstruction(Insn, 6, 1);
37590b57cec5SDimitry Andric 
37600b57cec5SDimitry Andric   if (Q) {
37610b57cec5SDimitry Andric     if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
37620b57cec5SDimitry Andric     return MCDisassembler::Fail;
37630b57cec5SDimitry Andric   } else {
37640b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
37650b57cec5SDimitry Andric     return MCDisassembler::Fail;
37660b57cec5SDimitry Andric   }
37670b57cec5SDimitry Andric 
37680b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37690b57cec5SDimitry Andric 
37700b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
37710b57cec5SDimitry Andric     case ARM::VORRiv4i16:
37720b57cec5SDimitry Andric     case ARM::VORRiv2i32:
37730b57cec5SDimitry Andric     case ARM::VBICiv4i16:
37740b57cec5SDimitry Andric     case ARM::VBICiv2i32:
37750b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
37760b57cec5SDimitry Andric         return MCDisassembler::Fail;
37770b57cec5SDimitry Andric       break;
37780b57cec5SDimitry Andric     case ARM::VORRiv8i16:
37790b57cec5SDimitry Andric     case ARM::VORRiv4i32:
37800b57cec5SDimitry Andric     case ARM::VBICiv8i16:
37810b57cec5SDimitry Andric     case ARM::VBICiv4i32:
37820b57cec5SDimitry Andric       if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
37830b57cec5SDimitry Andric         return MCDisassembler::Fail;
37840b57cec5SDimitry Andric       break;
37850b57cec5SDimitry Andric     default:
37860b57cec5SDimitry Andric       break;
37870b57cec5SDimitry Andric   }
37880b57cec5SDimitry Andric 
37890b57cec5SDimitry Andric   return S;
37900b57cec5SDimitry Andric }
37910b57cec5SDimitry Andric 
DecodeMVEModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)379281ad6265SDimitry Andric static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
379381ad6265SDimitry Andric                                                uint64_t Address,
379481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
37950b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37960b57cec5SDimitry Andric 
37970b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
37980b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
37990b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
38000b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
38010b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
38020b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 28, 1) << 7;
38030b57cec5SDimitry Andric   imm |= cmode                             << 8;
38040b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1)  << 12;
38050b57cec5SDimitry Andric 
38060b57cec5SDimitry Andric   if (cmode == 0xF && Inst.getOpcode() == ARM::MVE_VMVNimmi32)
38070b57cec5SDimitry Andric     return MCDisassembler::Fail;
38080b57cec5SDimitry Andric 
38090b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
38100b57cec5SDimitry Andric     return MCDisassembler::Fail;
38110b57cec5SDimitry Andric 
38120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
38130b57cec5SDimitry Andric 
38140b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
38150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
38160b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
38170b57cec5SDimitry Andric 
38180b57cec5SDimitry Andric   return S;
38190b57cec5SDimitry Andric }
38200b57cec5SDimitry Andric 
DecodeMVEVADCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)38210b57cec5SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
382281ad6265SDimitry Andric                                              uint64_t Address,
382381ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
38240b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38250b57cec5SDimitry Andric 
38260b57cec5SDimitry Andric   unsigned Qd = fieldFromInstruction(Insn, 13, 3);
38270b57cec5SDimitry Andric   Qd |= fieldFromInstruction(Insn, 22, 1) << 3;
38280b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
38290b57cec5SDimitry Andric     return MCDisassembler::Fail;
38300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
38310b57cec5SDimitry Andric 
38320b57cec5SDimitry Andric   unsigned Qn = fieldFromInstruction(Insn, 17, 3);
38330b57cec5SDimitry Andric   Qn |= fieldFromInstruction(Insn, 7, 1) << 3;
38340b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
38350b57cec5SDimitry Andric     return MCDisassembler::Fail;
38360b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 1, 3);
38370b57cec5SDimitry Andric   Qm |= fieldFromInstruction(Insn, 5, 1) << 3;
38380b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
38390b57cec5SDimitry Andric     return MCDisassembler::Fail;
38400b57cec5SDimitry Andric   if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
38410b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
38420b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Qd));
38430b57cec5SDimitry Andric 
38440b57cec5SDimitry Andric   return S;
38450b57cec5SDimitry Andric }
38460b57cec5SDimitry Andric 
DecodeVSHLMaxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)38470b57cec5SDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
384881ad6265SDimitry Andric                                              uint64_t Address,
384981ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
38500b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38510b57cec5SDimitry Andric 
38520b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
38530b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
38540b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
38550b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
38560b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 18, 2);
38570b57cec5SDimitry Andric 
38580b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
38590b57cec5SDimitry Andric     return MCDisassembler::Fail;
38600b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
38610b57cec5SDimitry Andric     return MCDisassembler::Fail;
38620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 << size));
38630b57cec5SDimitry Andric 
38640b57cec5SDimitry Andric   return S;
38650b57cec5SDimitry Andric }
38660b57cec5SDimitry Andric 
DecodeShiftRight8Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)38670b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
386881ad6265SDimitry Andric                                          uint64_t Address,
386981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
38700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 - Val));
38710b57cec5SDimitry Andric   return MCDisassembler::Success;
38720b57cec5SDimitry Andric }
38730b57cec5SDimitry Andric 
DecodeShiftRight16Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)38740b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
387581ad6265SDimitry Andric                                           uint64_t Address,
387681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
38770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(16 - Val));
38780b57cec5SDimitry Andric   return MCDisassembler::Success;
38790b57cec5SDimitry Andric }
38800b57cec5SDimitry Andric 
DecodeShiftRight32Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)38810b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
388281ad6265SDimitry Andric                                           uint64_t Address,
388381ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
38840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(32 - Val));
38850b57cec5SDimitry Andric   return MCDisassembler::Success;
38860b57cec5SDimitry Andric }
38870b57cec5SDimitry Andric 
DecodeShiftRight64Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)38880b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
388981ad6265SDimitry Andric                                           uint64_t Address,
389081ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
38910b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
38920b57cec5SDimitry Andric   return MCDisassembler::Success;
38930b57cec5SDimitry Andric }
38940b57cec5SDimitry Andric 
DecodeTBLInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)38950b57cec5SDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
389681ad6265SDimitry Andric                                          uint64_t Address,
389781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
38980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38990b57cec5SDimitry Andric 
39000b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
39010b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
39020b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
39030b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
39040b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
39050b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
39060b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 6, 1);
39070b57cec5SDimitry Andric 
39080b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
39090b57cec5SDimitry Andric     return MCDisassembler::Fail;
39100b57cec5SDimitry Andric   if (op) {
39110b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
39120b57cec5SDimitry Andric     return MCDisassembler::Fail; // Writeback
39130b57cec5SDimitry Andric   }
39140b57cec5SDimitry Andric 
39150b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
39160b57cec5SDimitry Andric   case ARM::VTBL2:
39170b57cec5SDimitry Andric   case ARM::VTBX2:
39180b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
39190b57cec5SDimitry Andric       return MCDisassembler::Fail;
39200b57cec5SDimitry Andric     break;
39210b57cec5SDimitry Andric   default:
39220b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
39230b57cec5SDimitry Andric       return MCDisassembler::Fail;
39240b57cec5SDimitry Andric   }
39250b57cec5SDimitry Andric 
39260b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
39270b57cec5SDimitry Andric     return MCDisassembler::Fail;
39280b57cec5SDimitry Andric 
39290b57cec5SDimitry Andric   return S;
39300b57cec5SDimitry Andric }
39310b57cec5SDimitry Andric 
DecodeThumbAddSpecialReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)39320b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
393381ad6265SDimitry Andric                                              uint64_t Address,
393481ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
39350b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39360b57cec5SDimitry Andric 
39370b57cec5SDimitry Andric   unsigned dst = fieldFromInstruction(Insn, 8, 3);
39380b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
39390b57cec5SDimitry Andric 
39400b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
39410b57cec5SDimitry Andric     return MCDisassembler::Fail;
39420b57cec5SDimitry Andric 
39430b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
39440b57cec5SDimitry Andric     default:
39450b57cec5SDimitry Andric       return MCDisassembler::Fail;
39460b57cec5SDimitry Andric     case ARM::tADR:
39470b57cec5SDimitry Andric       break; // tADR does not explicitly represent the PC as an operand.
39480b57cec5SDimitry Andric     case ARM::tADDrSPi:
39490b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::SP));
39500b57cec5SDimitry Andric       break;
39510b57cec5SDimitry Andric   }
39520b57cec5SDimitry Andric 
39530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
39540b57cec5SDimitry Andric   return S;
39550b57cec5SDimitry Andric }
39560b57cec5SDimitry Andric 
DecodeThumbBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)39570b57cec5SDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
395881ad6265SDimitry Andric                                          uint64_t Address,
395981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
39600b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
39610b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
39620b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1)));
39630b57cec5SDimitry Andric   return MCDisassembler::Success;
39640b57cec5SDimitry Andric }
39650b57cec5SDimitry Andric 
DecodeT2BROperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)39660b57cec5SDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
396781ad6265SDimitry Andric                                       uint64_t Address,
396881ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
39690b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
39700b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
39710b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val)));
39720b57cec5SDimitry Andric   return MCDisassembler::Success;
39730b57cec5SDimitry Andric }
39740b57cec5SDimitry Andric 
DecodeThumbCmpBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)39750b57cec5SDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
397681ad6265SDimitry Andric                                             uint64_t Address,
397781ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
39780b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
39790b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
39800b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val << 1));
39810b57cec5SDimitry Andric   return MCDisassembler::Success;
39820b57cec5SDimitry Andric }
39830b57cec5SDimitry Andric 
DecodeThumbAddrModeRR(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)39840b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
398581ad6265SDimitry Andric                                           uint64_t Address,
398681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
39870b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39880b57cec5SDimitry Andric 
39890b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
39900b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 3, 3);
39910b57cec5SDimitry Andric 
39920b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
39930b57cec5SDimitry Andric     return MCDisassembler::Fail;
39940b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
39950b57cec5SDimitry Andric     return MCDisassembler::Fail;
39960b57cec5SDimitry Andric 
39970b57cec5SDimitry Andric   return S;
39980b57cec5SDimitry Andric }
39990b57cec5SDimitry Andric 
DecodeThumbAddrModeIS(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)40000b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
400181ad6265SDimitry Andric                                           uint64_t Address,
400281ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40030b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40040b57cec5SDimitry Andric 
40050b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
40060b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 3, 5);
40070b57cec5SDimitry Andric 
40080b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
40090b57cec5SDimitry Andric     return MCDisassembler::Fail;
40100b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
40110b57cec5SDimitry Andric 
40120b57cec5SDimitry Andric   return S;
40130b57cec5SDimitry Andric }
40140b57cec5SDimitry Andric 
DecodeThumbAddrModePC(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)40150b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
401681ad6265SDimitry Andric                                           uint64_t Address,
401781ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40180b57cec5SDimitry Andric   unsigned imm = Val << 2;
40190b57cec5SDimitry Andric 
40200b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
40210b57cec5SDimitry Andric   tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
40220b57cec5SDimitry Andric 
40230b57cec5SDimitry Andric   return MCDisassembler::Success;
40240b57cec5SDimitry Andric }
40250b57cec5SDimitry Andric 
DecodeThumbAddrModeSP(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)40260b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
402781ad6265SDimitry Andric                                           uint64_t Address,
402881ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40290b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
40300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
40310b57cec5SDimitry Andric 
40320b57cec5SDimitry Andric   return MCDisassembler::Success;
40330b57cec5SDimitry Andric }
40340b57cec5SDimitry Andric 
DecodeT2AddrModeSOReg(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)40350b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
403681ad6265SDimitry Andric                                           uint64_t Address,
403781ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40380b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40390b57cec5SDimitry Andric 
40400b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 6, 4);
40410b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 2, 4);
40420b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 2);
40430b57cec5SDimitry Andric 
40440b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
40450b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
40460b57cec5SDimitry Andric   case ARM::t2STRHs:
40470b57cec5SDimitry Andric   case ARM::t2STRBs:
40480b57cec5SDimitry Andric   case ARM::t2STRs:
40490b57cec5SDimitry Andric     if (Rn == 15)
40500b57cec5SDimitry Andric       return MCDisassembler::Fail;
40510b57cec5SDimitry Andric     break;
40520b57cec5SDimitry Andric   default:
40530b57cec5SDimitry Andric     break;
40540b57cec5SDimitry Andric   }
40550b57cec5SDimitry Andric 
40560b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
40570b57cec5SDimitry Andric     return MCDisassembler::Fail;
40580b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
40590b57cec5SDimitry Andric     return MCDisassembler::Fail;
40600b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
40610b57cec5SDimitry Andric 
40620b57cec5SDimitry Andric   return S;
40630b57cec5SDimitry Andric }
40640b57cec5SDimitry Andric 
DecodeT2LoadShift(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)40650b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
406681ad6265SDimitry Andric                                       uint64_t Address,
406781ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
40680b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40690b57cec5SDimitry Andric 
40700b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
40710b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
40720b57cec5SDimitry Andric 
40730b57cec5SDimitry Andric   const FeatureBitset &featureBits =
40740b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
40750b57cec5SDimitry Andric 
40760b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
40770b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
40780b57cec5SDimitry Andric 
40790b57cec5SDimitry Andric   if (Rn == 15) {
40800b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
40810b57cec5SDimitry Andric     case ARM::t2LDRBs:
40820b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
40830b57cec5SDimitry Andric       break;
40840b57cec5SDimitry Andric     case ARM::t2LDRHs:
40850b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
40860b57cec5SDimitry Andric       break;
40870b57cec5SDimitry Andric     case ARM::t2LDRSHs:
40880b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
40890b57cec5SDimitry Andric       break;
40900b57cec5SDimitry Andric     case ARM::t2LDRSBs:
40910b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
40920b57cec5SDimitry Andric       break;
40930b57cec5SDimitry Andric     case ARM::t2LDRs:
40940b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
40950b57cec5SDimitry Andric       break;
40960b57cec5SDimitry Andric     case ARM::t2PLDs:
40970b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
40980b57cec5SDimitry Andric       break;
40990b57cec5SDimitry Andric     case ARM::t2PLIs:
41000b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
41010b57cec5SDimitry Andric       break;
41020b57cec5SDimitry Andric     default:
41030b57cec5SDimitry Andric       return MCDisassembler::Fail;
41040b57cec5SDimitry Andric     }
41050b57cec5SDimitry Andric 
41060b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
41070b57cec5SDimitry Andric   }
41080b57cec5SDimitry Andric 
41090b57cec5SDimitry Andric   if (Rt == 15) {
41100b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
41110b57cec5SDimitry Andric     case ARM::t2LDRSHs:
41120b57cec5SDimitry Andric       return MCDisassembler::Fail;
41130b57cec5SDimitry Andric     case ARM::t2LDRHs:
41140b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDWs);
41150b57cec5SDimitry Andric       break;
41160b57cec5SDimitry Andric     case ARM::t2LDRSBs:
41170b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIs);
41180b57cec5SDimitry Andric       break;
41190b57cec5SDimitry Andric     default:
41200b57cec5SDimitry Andric       break;
41210b57cec5SDimitry Andric     }
41220b57cec5SDimitry Andric   }
41230b57cec5SDimitry Andric 
41240b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
41250b57cec5SDimitry Andric     case ARM::t2PLDs:
41260b57cec5SDimitry Andric       break;
41270b57cec5SDimitry Andric     case ARM::t2PLIs:
41280b57cec5SDimitry Andric       if (!hasV7Ops)
41290b57cec5SDimitry Andric         return MCDisassembler::Fail;
41300b57cec5SDimitry Andric       break;
41310b57cec5SDimitry Andric     case ARM::t2PLDWs:
41320b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
41330b57cec5SDimitry Andric         return MCDisassembler::Fail;
41340b57cec5SDimitry Andric       break;
41350b57cec5SDimitry Andric     default:
41360b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
41370b57cec5SDimitry Andric         return MCDisassembler::Fail;
41380b57cec5SDimitry Andric   }
41390b57cec5SDimitry Andric 
41400b57cec5SDimitry Andric   unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
41410b57cec5SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
41420b57cec5SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
41430b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
41440b57cec5SDimitry Andric     return MCDisassembler::Fail;
41450b57cec5SDimitry Andric 
41460b57cec5SDimitry Andric   return S;
41470b57cec5SDimitry Andric }
41480b57cec5SDimitry Andric 
DecodeT2LoadImm8(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)41490b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
415081ad6265SDimitry Andric                                      uint64_t Address,
415181ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
41520b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
41530b57cec5SDimitry Andric 
41540b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
41550b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
41560b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 9, 1);
41570b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
41580b57cec5SDimitry Andric   imm |= (U << 8);
41590b57cec5SDimitry Andric   imm |= (Rn << 9);
41600b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 9, 1);
41610b57cec5SDimitry Andric 
41620b57cec5SDimitry Andric   const FeatureBitset &featureBits =
41630b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
41640b57cec5SDimitry Andric 
41650b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
41660b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
41670b57cec5SDimitry Andric 
41680b57cec5SDimitry Andric   if (Rn == 15) {
41690b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
41700b57cec5SDimitry Andric     case ARM::t2LDRi8:
41710b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
41720b57cec5SDimitry Andric       break;
41730b57cec5SDimitry Andric     case ARM::t2LDRBi8:
41740b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
41750b57cec5SDimitry Andric       break;
41760b57cec5SDimitry Andric     case ARM::t2LDRSBi8:
41770b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
41780b57cec5SDimitry Andric       break;
41790b57cec5SDimitry Andric     case ARM::t2LDRHi8:
41800b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
41810b57cec5SDimitry Andric       break;
41820b57cec5SDimitry Andric     case ARM::t2LDRSHi8:
41830b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
41840b57cec5SDimitry Andric       break;
41850b57cec5SDimitry Andric     case ARM::t2PLDi8:
41860b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
41870b57cec5SDimitry Andric       break;
41880b57cec5SDimitry Andric     case ARM::t2PLIi8:
41890b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
41900b57cec5SDimitry Andric       break;
41910b57cec5SDimitry Andric     default:
41920b57cec5SDimitry Andric       return MCDisassembler::Fail;
41930b57cec5SDimitry Andric     }
41940b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
41950b57cec5SDimitry Andric   }
41960b57cec5SDimitry Andric 
41970b57cec5SDimitry Andric   if (Rt == 15) {
41980b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
41990b57cec5SDimitry Andric     case ARM::t2LDRSHi8:
42000b57cec5SDimitry Andric       return MCDisassembler::Fail;
42010b57cec5SDimitry Andric     case ARM::t2LDRHi8:
42020b57cec5SDimitry Andric       if (!add)
42030b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLDWi8);
42040b57cec5SDimitry Andric       break;
42050b57cec5SDimitry Andric     case ARM::t2LDRSBi8:
42060b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIi8);
42070b57cec5SDimitry Andric       break;
42080b57cec5SDimitry Andric     default:
42090b57cec5SDimitry Andric       break;
42100b57cec5SDimitry Andric     }
42110b57cec5SDimitry Andric   }
42120b57cec5SDimitry Andric 
42130b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
42140b57cec5SDimitry Andric   case ARM::t2PLDi8:
42150b57cec5SDimitry Andric     break;
42160b57cec5SDimitry Andric   case ARM::t2PLIi8:
42170b57cec5SDimitry Andric     if (!hasV7Ops)
42180b57cec5SDimitry Andric       return MCDisassembler::Fail;
42190b57cec5SDimitry Andric     break;
42200b57cec5SDimitry Andric   case ARM::t2PLDWi8:
42210b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
42220b57cec5SDimitry Andric         return MCDisassembler::Fail;
42230b57cec5SDimitry Andric       break;
42240b57cec5SDimitry Andric   default:
42250b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
42260b57cec5SDimitry Andric       return MCDisassembler::Fail;
42270b57cec5SDimitry Andric   }
42280b57cec5SDimitry Andric 
42290b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
42300b57cec5SDimitry Andric     return MCDisassembler::Fail;
42310b57cec5SDimitry Andric   return S;
42320b57cec5SDimitry Andric }
42330b57cec5SDimitry Andric 
DecodeT2LoadImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)42340b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
423581ad6265SDimitry Andric                                       uint64_t Address,
423681ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
42370b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42380b57cec5SDimitry Andric 
42390b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
42400b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
42410b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
42420b57cec5SDimitry Andric   imm |= (Rn << 13);
42430b57cec5SDimitry Andric 
42440b57cec5SDimitry Andric   const FeatureBitset &featureBits =
42450b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
42460b57cec5SDimitry Andric 
42470b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
42480b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
42490b57cec5SDimitry Andric 
42500b57cec5SDimitry Andric   if (Rn == 15) {
42510b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
42520b57cec5SDimitry Andric     case ARM::t2LDRi12:
42530b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
42540b57cec5SDimitry Andric       break;
42550b57cec5SDimitry Andric     case ARM::t2LDRHi12:
42560b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
42570b57cec5SDimitry Andric       break;
42580b57cec5SDimitry Andric     case ARM::t2LDRSHi12:
42590b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
42600b57cec5SDimitry Andric       break;
42610b57cec5SDimitry Andric     case ARM::t2LDRBi12:
42620b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
42630b57cec5SDimitry Andric       break;
42640b57cec5SDimitry Andric     case ARM::t2LDRSBi12:
42650b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
42660b57cec5SDimitry Andric       break;
42670b57cec5SDimitry Andric     case ARM::t2PLDi12:
42680b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
42690b57cec5SDimitry Andric       break;
42700b57cec5SDimitry Andric     case ARM::t2PLIi12:
42710b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
42720b57cec5SDimitry Andric       break;
42730b57cec5SDimitry Andric     default:
42740b57cec5SDimitry Andric       return MCDisassembler::Fail;
42750b57cec5SDimitry Andric     }
42760b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
42770b57cec5SDimitry Andric   }
42780b57cec5SDimitry Andric 
42790b57cec5SDimitry Andric   if (Rt == 15) {
42800b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
42810b57cec5SDimitry Andric     case ARM::t2LDRSHi12:
42820b57cec5SDimitry Andric       return MCDisassembler::Fail;
42830b57cec5SDimitry Andric     case ARM::t2LDRHi12:
42840b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDWi12);
42850b57cec5SDimitry Andric       break;
42860b57cec5SDimitry Andric     case ARM::t2LDRSBi12:
42870b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIi12);
42880b57cec5SDimitry Andric       break;
42890b57cec5SDimitry Andric     default:
42900b57cec5SDimitry Andric       break;
42910b57cec5SDimitry Andric     }
42920b57cec5SDimitry Andric   }
42930b57cec5SDimitry Andric 
42940b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
42950b57cec5SDimitry Andric   case ARM::t2PLDi12:
42960b57cec5SDimitry Andric     break;
42970b57cec5SDimitry Andric   case ARM::t2PLIi12:
42980b57cec5SDimitry Andric     if (!hasV7Ops)
42990b57cec5SDimitry Andric       return MCDisassembler::Fail;
43000b57cec5SDimitry Andric     break;
43010b57cec5SDimitry Andric   case ARM::t2PLDWi12:
43020b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
43030b57cec5SDimitry Andric         return MCDisassembler::Fail;
43040b57cec5SDimitry Andric       break;
43050b57cec5SDimitry Andric   default:
43060b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43070b57cec5SDimitry Andric       return MCDisassembler::Fail;
43080b57cec5SDimitry Andric   }
43090b57cec5SDimitry Andric 
43100b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
43110b57cec5SDimitry Andric     return MCDisassembler::Fail;
43120b57cec5SDimitry Andric   return S;
43130b57cec5SDimitry Andric }
43140b57cec5SDimitry Andric 
DecodeT2LoadT(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)431581ad6265SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, uint64_t Address,
431681ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
43170b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43180b57cec5SDimitry Andric 
43190b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
43200b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43210b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
43220b57cec5SDimitry Andric   imm |= (Rn << 9);
43230b57cec5SDimitry Andric 
43240b57cec5SDimitry Andric   if (Rn == 15) {
43250b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
43260b57cec5SDimitry Andric     case ARM::t2LDRT:
43270b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
43280b57cec5SDimitry Andric       break;
43290b57cec5SDimitry Andric     case ARM::t2LDRBT:
43300b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
43310b57cec5SDimitry Andric       break;
43320b57cec5SDimitry Andric     case ARM::t2LDRHT:
43330b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
43340b57cec5SDimitry Andric       break;
43350b57cec5SDimitry Andric     case ARM::t2LDRSBT:
43360b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
43370b57cec5SDimitry Andric       break;
43380b57cec5SDimitry Andric     case ARM::t2LDRSHT:
43390b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
43400b57cec5SDimitry Andric       break;
43410b57cec5SDimitry Andric     default:
43420b57cec5SDimitry Andric       return MCDisassembler::Fail;
43430b57cec5SDimitry Andric     }
43440b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
43450b57cec5SDimitry Andric   }
43460b57cec5SDimitry Andric 
43470b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
43480b57cec5SDimitry Andric     return MCDisassembler::Fail;
43490b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
43500b57cec5SDimitry Andric     return MCDisassembler::Fail;
43510b57cec5SDimitry Andric   return S;
43520b57cec5SDimitry Andric }
43530b57cec5SDimitry Andric 
DecodeT2LoadLabel(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)43540b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
435581ad6265SDimitry Andric                                       uint64_t Address,
435681ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
43570b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43580b57cec5SDimitry Andric 
43590b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43600b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
43610b57cec5SDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 12);
43620b57cec5SDimitry Andric 
43630b57cec5SDimitry Andric   const FeatureBitset &featureBits =
43640b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
43650b57cec5SDimitry Andric 
43660b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
43670b57cec5SDimitry Andric 
43680b57cec5SDimitry Andric   if (Rt == 15) {
43690b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
43700b57cec5SDimitry Andric       case ARM::t2LDRBpci:
43710b57cec5SDimitry Andric       case ARM::t2LDRHpci:
43720b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLDpci);
43730b57cec5SDimitry Andric         break;
43740b57cec5SDimitry Andric       case ARM::t2LDRSBpci:
43750b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
43760b57cec5SDimitry Andric         break;
43770b57cec5SDimitry Andric       case ARM::t2LDRSHpci:
43780b57cec5SDimitry Andric         return MCDisassembler::Fail;
43790b57cec5SDimitry Andric       default:
43800b57cec5SDimitry Andric         break;
43810b57cec5SDimitry Andric     }
43820b57cec5SDimitry Andric   }
43830b57cec5SDimitry Andric 
43840b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
43850b57cec5SDimitry Andric   case ARM::t2PLDpci:
43860b57cec5SDimitry Andric     break;
43870b57cec5SDimitry Andric   case ARM::t2PLIpci:
43880b57cec5SDimitry Andric     if (!hasV7Ops)
43890b57cec5SDimitry Andric       return MCDisassembler::Fail;
43900b57cec5SDimitry Andric     break;
43910b57cec5SDimitry Andric   default:
43920b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43930b57cec5SDimitry Andric       return MCDisassembler::Fail;
43940b57cec5SDimitry Andric   }
43950b57cec5SDimitry Andric 
43960b57cec5SDimitry Andric   if (!U) {
43970b57cec5SDimitry Andric     // Special case for #-0.
43980b57cec5SDimitry Andric     if (imm == 0)
43990b57cec5SDimitry Andric       imm = INT32_MIN;
44000b57cec5SDimitry Andric     else
44010b57cec5SDimitry Andric       imm = -imm;
44020b57cec5SDimitry Andric   }
44030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44040b57cec5SDimitry Andric 
44050b57cec5SDimitry Andric   return S;
44060b57cec5SDimitry Andric }
44070b57cec5SDimitry Andric 
DecodeT2Imm8S4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)440881ad6265SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, uint64_t Address,
440981ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
44100b57cec5SDimitry Andric   if (Val == 0)
44110b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
44120b57cec5SDimitry Andric   else {
44130b57cec5SDimitry Andric     int imm = Val & 0xFF;
44140b57cec5SDimitry Andric 
44150b57cec5SDimitry Andric     if (!(Val & 0x100)) imm *= -1;
44160b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
44170b57cec5SDimitry Andric   }
44180b57cec5SDimitry Andric 
44190b57cec5SDimitry Andric   return MCDisassembler::Success;
44200b57cec5SDimitry Andric }
44210b57cec5SDimitry Andric 
DecodeT2Imm7S4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)44220b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
442381ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
44240b57cec5SDimitry Andric   if (Val == 0)
44250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
44260b57cec5SDimitry Andric   else {
44270b57cec5SDimitry Andric     int imm = Val & 0x7F;
44280b57cec5SDimitry Andric 
44290b57cec5SDimitry Andric     if (!(Val & 0x80))
44300b57cec5SDimitry Andric       imm *= -1;
44310b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
44320b57cec5SDimitry Andric   }
44330b57cec5SDimitry Andric 
44340b57cec5SDimitry Andric   return MCDisassembler::Success;
44350b57cec5SDimitry Andric }
44360b57cec5SDimitry Andric 
DecodeT2AddrModeImm8s4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)44370b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
443881ad6265SDimitry Andric                                            uint64_t Address,
443981ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
44400b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44410b57cec5SDimitry Andric 
44420b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
44430b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
44440b57cec5SDimitry Andric 
44450b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
44460b57cec5SDimitry Andric     return MCDisassembler::Fail;
44470b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
44480b57cec5SDimitry Andric     return MCDisassembler::Fail;
44490b57cec5SDimitry Andric 
44500b57cec5SDimitry Andric   return S;
44510b57cec5SDimitry Andric }
44520b57cec5SDimitry Andric 
DecodeT2AddrModeImm7s4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)44530b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
44540b57cec5SDimitry Andric                                            uint64_t Address,
445581ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
44560b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44570b57cec5SDimitry Andric 
44580b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
44590b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
44600b57cec5SDimitry Andric 
44610b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
44620b57cec5SDimitry Andric     return MCDisassembler::Fail;
44630b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7S4(Inst, imm, Address, Decoder)))
44640b57cec5SDimitry Andric     return MCDisassembler::Fail;
44650b57cec5SDimitry Andric 
44660b57cec5SDimitry Andric   return S;
44670b57cec5SDimitry Andric }
44680b57cec5SDimitry Andric 
DecodeT2AddrModeImm0_1020s4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)44690b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst, unsigned Val,
447081ad6265SDimitry Andric                                                 uint64_t Address,
447181ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
44720b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44730b57cec5SDimitry Andric 
44740b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
44750b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
44760b57cec5SDimitry Andric 
44770b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
44780b57cec5SDimitry Andric     return MCDisassembler::Fail;
44790b57cec5SDimitry Andric 
44800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44810b57cec5SDimitry Andric 
44820b57cec5SDimitry Andric   return S;
44830b57cec5SDimitry Andric }
44840b57cec5SDimitry Andric 
DecodeT2Imm8(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)448581ad6265SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
448681ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
44870b57cec5SDimitry Andric   int imm = Val & 0xFF;
44880b57cec5SDimitry Andric   if (Val == 0)
44890b57cec5SDimitry Andric     imm = INT32_MIN;
44900b57cec5SDimitry Andric   else if (!(Val & 0x100))
44910b57cec5SDimitry Andric     imm *= -1;
44920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44930b57cec5SDimitry Andric 
44940b57cec5SDimitry Andric   return MCDisassembler::Success;
44950b57cec5SDimitry Andric }
44960b57cec5SDimitry Andric 
44970b57cec5SDimitry Andric template <int shift>
DecodeT2Imm7(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)449881ad6265SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, uint64_t Address,
449981ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
45000b57cec5SDimitry Andric   int imm = Val & 0x7F;
45010b57cec5SDimitry Andric   if (Val == 0)
45020b57cec5SDimitry Andric     imm = INT32_MIN;
45030b57cec5SDimitry Andric   else if (!(Val & 0x80))
45040b57cec5SDimitry Andric     imm *= -1;
45050b57cec5SDimitry Andric   if (imm != INT32_MIN)
45060b57cec5SDimitry Andric     imm *= (1U << shift);
45070b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
45080b57cec5SDimitry Andric 
45090b57cec5SDimitry Andric   return MCDisassembler::Success;
45100b57cec5SDimitry Andric }
45110b57cec5SDimitry Andric 
DecodeT2AddrModeImm8(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)45120b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
451381ad6265SDimitry Andric                                          uint64_t Address,
451481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
45150b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45160b57cec5SDimitry Andric 
45170b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
45180b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
45190b57cec5SDimitry Andric 
45200b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
45210b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
45220b57cec5SDimitry Andric   case ARM::t2STRT:
45230b57cec5SDimitry Andric   case ARM::t2STRBT:
45240b57cec5SDimitry Andric   case ARM::t2STRHT:
45250b57cec5SDimitry Andric   case ARM::t2STRi8:
45260b57cec5SDimitry Andric   case ARM::t2STRHi8:
45270b57cec5SDimitry Andric   case ARM::t2STRBi8:
45280b57cec5SDimitry Andric     if (Rn == 15)
45290b57cec5SDimitry Andric       return MCDisassembler::Fail;
45300b57cec5SDimitry Andric     break;
45310b57cec5SDimitry Andric   default:
45320b57cec5SDimitry Andric     break;
45330b57cec5SDimitry Andric   }
45340b57cec5SDimitry Andric 
45350b57cec5SDimitry Andric   // Some instructions always use an additive offset.
45360b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
45370b57cec5SDimitry Andric     case ARM::t2LDRT:
45380b57cec5SDimitry Andric     case ARM::t2LDRBT:
45390b57cec5SDimitry Andric     case ARM::t2LDRHT:
45400b57cec5SDimitry Andric     case ARM::t2LDRSBT:
45410b57cec5SDimitry Andric     case ARM::t2LDRSHT:
45420b57cec5SDimitry Andric     case ARM::t2STRT:
45430b57cec5SDimitry Andric     case ARM::t2STRBT:
45440b57cec5SDimitry Andric     case ARM::t2STRHT:
45450b57cec5SDimitry Andric       imm |= 0x100;
45460b57cec5SDimitry Andric       break;
45470b57cec5SDimitry Andric     default:
45480b57cec5SDimitry Andric       break;
45490b57cec5SDimitry Andric   }
45500b57cec5SDimitry Andric 
45510b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
45520b57cec5SDimitry Andric     return MCDisassembler::Fail;
45530b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
45540b57cec5SDimitry Andric     return MCDisassembler::Fail;
45550b57cec5SDimitry Andric 
45560b57cec5SDimitry Andric   return S;
45570b57cec5SDimitry Andric }
45580b57cec5SDimitry Andric 
45590b57cec5SDimitry Andric template <int shift>
DecodeTAddrModeImm7(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)45600b57cec5SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
45610b57cec5SDimitry Andric                                         uint64_t Address,
456281ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
45630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45640b57cec5SDimitry Andric 
45650b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 3);
45660b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
45670b57cec5SDimitry Andric 
45680b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
45690b57cec5SDimitry Andric     return MCDisassembler::Fail;
45700b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
45710b57cec5SDimitry Andric     return MCDisassembler::Fail;
45720b57cec5SDimitry Andric 
45730b57cec5SDimitry Andric   return S;
45740b57cec5SDimitry Andric }
45750b57cec5SDimitry Andric 
45760b57cec5SDimitry Andric template <int shift, int WriteBack>
DecodeT2AddrModeImm7(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)45770b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
45780b57cec5SDimitry Andric                                          uint64_t Address,
457981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
45800b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45810b57cec5SDimitry Andric 
45820b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
45830b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
45840b57cec5SDimitry Andric   if (WriteBack) {
45850b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
45860b57cec5SDimitry Andric       return MCDisassembler::Fail;
45870b57cec5SDimitry Andric   } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
45880b57cec5SDimitry Andric     return MCDisassembler::Fail;
45890b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
45900b57cec5SDimitry Andric     return MCDisassembler::Fail;
45910b57cec5SDimitry Andric 
45920b57cec5SDimitry Andric   return S;
45930b57cec5SDimitry Andric }
45940b57cec5SDimitry Andric 
DecodeT2LdStPre(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)45950b57cec5SDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
459681ad6265SDimitry Andric                                     uint64_t Address,
459781ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
45980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45990b57cec5SDimitry Andric 
46000b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
46010b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
46020b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
46030b57cec5SDimitry Andric   addr |= fieldFromInstruction(Insn, 9, 1) << 8;
46040b57cec5SDimitry Andric   addr |= Rn << 9;
46050b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 20, 1);
46060b57cec5SDimitry Andric 
46070b57cec5SDimitry Andric   if (Rn == 15) {
46080b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
46090b57cec5SDimitry Andric     case ARM::t2LDR_PRE:
46100b57cec5SDimitry Andric     case ARM::t2LDR_POST:
46110b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
46120b57cec5SDimitry Andric       break;
46130b57cec5SDimitry Andric     case ARM::t2LDRB_PRE:
46140b57cec5SDimitry Andric     case ARM::t2LDRB_POST:
46150b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
46160b57cec5SDimitry Andric       break;
46170b57cec5SDimitry Andric     case ARM::t2LDRH_PRE:
46180b57cec5SDimitry Andric     case ARM::t2LDRH_POST:
46190b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
46200b57cec5SDimitry Andric       break;
46210b57cec5SDimitry Andric     case ARM::t2LDRSB_PRE:
46220b57cec5SDimitry Andric     case ARM::t2LDRSB_POST:
46230b57cec5SDimitry Andric       if (Rt == 15)
46240b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
46250b57cec5SDimitry Andric       else
46260b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2LDRSBpci);
46270b57cec5SDimitry Andric       break;
46280b57cec5SDimitry Andric     case ARM::t2LDRSH_PRE:
46290b57cec5SDimitry Andric     case ARM::t2LDRSH_POST:
46300b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
46310b57cec5SDimitry Andric       break;
46320b57cec5SDimitry Andric     default:
46330b57cec5SDimitry Andric       return MCDisassembler::Fail;
46340b57cec5SDimitry Andric     }
46350b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
46360b57cec5SDimitry Andric   }
46370b57cec5SDimitry Andric 
46380b57cec5SDimitry Andric   if (!load) {
46390b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46400b57cec5SDimitry Andric       return MCDisassembler::Fail;
46410b57cec5SDimitry Andric   }
46420b57cec5SDimitry Andric 
46430b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
46440b57cec5SDimitry Andric     return MCDisassembler::Fail;
46450b57cec5SDimitry Andric 
46460b57cec5SDimitry Andric   if (load) {
46470b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46480b57cec5SDimitry Andric       return MCDisassembler::Fail;
46490b57cec5SDimitry Andric   }
46500b57cec5SDimitry Andric 
46510b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
46520b57cec5SDimitry Andric     return MCDisassembler::Fail;
46530b57cec5SDimitry Andric 
46540b57cec5SDimitry Andric   return S;
46550b57cec5SDimitry Andric }
46560b57cec5SDimitry Andric 
DecodeT2AddrModeImm12(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)46570b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
465881ad6265SDimitry Andric                                           uint64_t Address,
465981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
46600b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
46610b57cec5SDimitry Andric 
46620b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
46630b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
46640b57cec5SDimitry Andric 
46650b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
46660b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
46670b57cec5SDimitry Andric   case ARM::t2STRi12:
46680b57cec5SDimitry Andric   case ARM::t2STRBi12:
46690b57cec5SDimitry Andric   case ARM::t2STRHi12:
46700b57cec5SDimitry Andric     if (Rn == 15)
46710b57cec5SDimitry Andric       return MCDisassembler::Fail;
46720b57cec5SDimitry Andric     break;
46730b57cec5SDimitry Andric   default:
46740b57cec5SDimitry Andric     break;
46750b57cec5SDimitry Andric   }
46760b57cec5SDimitry Andric 
46770b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46780b57cec5SDimitry Andric     return MCDisassembler::Fail;
46790b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
46800b57cec5SDimitry Andric 
46810b57cec5SDimitry Andric   return S;
46820b57cec5SDimitry Andric }
46830b57cec5SDimitry Andric 
DecodeThumbAddSPImm(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)46840b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
468581ad6265SDimitry Andric                                         uint64_t Address,
468681ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
46870b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 7);
46880b57cec5SDimitry Andric 
46890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
46900b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
46910b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
46920b57cec5SDimitry Andric 
46930b57cec5SDimitry Andric   return MCDisassembler::Success;
46940b57cec5SDimitry Andric }
46950b57cec5SDimitry Andric 
DecodeThumbAddSPReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)46960b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
469781ad6265SDimitry Andric                                         uint64_t Address,
469881ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
46990b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47000b57cec5SDimitry Andric 
47010b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::tADDrSP) {
47020b57cec5SDimitry Andric     unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
47030b57cec5SDimitry Andric     Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
47040b57cec5SDimitry Andric 
47050b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
47060b57cec5SDimitry Andric     return MCDisassembler::Fail;
47070b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
47080b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
47090b57cec5SDimitry Andric     return MCDisassembler::Fail;
47100b57cec5SDimitry Andric   } else if (Inst.getOpcode() == ARM::tADDspr) {
47110b57cec5SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 3, 4);
47120b57cec5SDimitry Andric 
47130b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
47140b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
47150b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
47160b57cec5SDimitry Andric     return MCDisassembler::Fail;
47170b57cec5SDimitry Andric   }
47180b57cec5SDimitry Andric 
47190b57cec5SDimitry Andric   return S;
47200b57cec5SDimitry Andric }
47210b57cec5SDimitry Andric 
DecodeThumbCPS(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)47220b57cec5SDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
472381ad6265SDimitry Andric                                    uint64_t Address,
472481ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
47250b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
47260b57cec5SDimitry Andric   unsigned flags = fieldFromInstruction(Insn, 0, 3);
47270b57cec5SDimitry Andric 
47280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imod));
47290b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(flags));
47300b57cec5SDimitry Andric 
47310b57cec5SDimitry Andric   return MCDisassembler::Success;
47320b57cec5SDimitry Andric }
47330b57cec5SDimitry Andric 
DecodePostIdxReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)47340b57cec5SDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
473581ad6265SDimitry Andric                                      uint64_t Address,
473681ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
47370b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47380b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
47390b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 4, 1);
47400b57cec5SDimitry Andric 
47410b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
47420b57cec5SDimitry Andric     return MCDisassembler::Fail;
47430b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(add));
47440b57cec5SDimitry Andric 
47450b57cec5SDimitry Andric   return S;
47460b57cec5SDimitry Andric }
47470b57cec5SDimitry Andric 
DecodeMveAddrModeRQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)47480b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
474981ad6265SDimitry Andric                                         uint64_t Address,
475081ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
47510b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47520b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 3, 4);
47530b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 0, 3);
47540b57cec5SDimitry Andric 
47550b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
47560b57cec5SDimitry Andric     return MCDisassembler::Fail;
47570b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
47580b57cec5SDimitry Andric     return MCDisassembler::Fail;
47590b57cec5SDimitry Andric 
47600b57cec5SDimitry Andric   return S;
47610b57cec5SDimitry Andric }
47620b57cec5SDimitry Andric 
47630b57cec5SDimitry Andric template <int shift>
DecodeMveAddrModeQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)47640b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
476581ad6265SDimitry Andric                                        uint64_t Address,
476681ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
47670b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47680b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 8, 3);
47690b57cec5SDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 7);
47700b57cec5SDimitry Andric 
47710b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
47720b57cec5SDimitry Andric     return MCDisassembler::Fail;
47730b57cec5SDimitry Andric 
47740b57cec5SDimitry Andric   if(!fieldFromInstruction(Insn, 7, 1)) {
47750b57cec5SDimitry Andric     if (imm == 0)
47760b57cec5SDimitry Andric       imm = INT32_MIN;                 // indicate -0
47770b57cec5SDimitry Andric     else
47780b57cec5SDimitry Andric       imm *= -1;
47790b57cec5SDimitry Andric   }
47800b57cec5SDimitry Andric   if (imm != INT32_MIN)
47810b57cec5SDimitry Andric     imm *= (1U << shift);
47820b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
47830b57cec5SDimitry Andric 
47840b57cec5SDimitry Andric   return S;
47850b57cec5SDimitry Andric }
47860b57cec5SDimitry Andric 
DecodeThumbBLXOffset(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)47870b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
478881ad6265SDimitry Andric                                          uint64_t Address,
478981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
47900b57cec5SDimitry Andric   // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
47910b57cec5SDimitry Andric   // Note only one trailing zero not two.  Also the J1 and J2 values are from
47920b57cec5SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
47930b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
47940b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
47950b57cec5SDimitry Andric   // and build the imm32 with two trailing zeros as documented:
47960b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
47970b57cec5SDimitry Andric   unsigned S = (Val >> 23) & 1;
47980b57cec5SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
47990b57cec5SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
48000b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
48010b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
48020b57cec5SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
48030b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
48040b57cec5SDimitry Andric 
48050b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address,
48060b57cec5SDimitry Andric                                 (Address & ~2u) + imm32 + 4,
48070b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
48080b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
48090b57cec5SDimitry Andric   return MCDisassembler::Success;
48100b57cec5SDimitry Andric }
48110b57cec5SDimitry Andric 
DecodeCoprocessor(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)48120b57cec5SDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
481381ad6265SDimitry Andric                                       uint64_t Address,
481481ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
48150b57cec5SDimitry Andric   if (Val == 0xA || Val == 0xB)
48160b57cec5SDimitry Andric     return MCDisassembler::Fail;
48170b57cec5SDimitry Andric 
48180b57cec5SDimitry Andric   const FeatureBitset &featureBits =
48190b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
48200b57cec5SDimitry Andric 
48210b57cec5SDimitry Andric   if (!isValidCoprocessorNumber(Val, featureBits))
48220b57cec5SDimitry Andric     return MCDisassembler::Fail;
48230b57cec5SDimitry Andric 
48240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
48250b57cec5SDimitry Andric   return MCDisassembler::Success;
48260b57cec5SDimitry Andric }
48270b57cec5SDimitry Andric 
DecodeThumbTableBranch(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)482881ad6265SDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
482981ad6265SDimitry Andric                                            uint64_t Address,
483081ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
4831e8d8bef9SDimitry Andric   const FeatureBitset &FeatureBits =
4832e8d8bef9SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
48330b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48340b57cec5SDimitry Andric 
48350b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48360b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
48370b57cec5SDimitry Andric 
4838e8d8bef9SDimitry Andric   if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
48390b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48400b57cec5SDimitry Andric     return MCDisassembler::Fail;
48410b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
48420b57cec5SDimitry Andric     return MCDisassembler::Fail;
48430b57cec5SDimitry Andric   return S;
48440b57cec5SDimitry Andric }
48450b57cec5SDimitry Andric 
DecodeThumb2BCCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)484681ad6265SDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
484781ad6265SDimitry Andric                                                uint64_t Address,
484881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
48490b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48500b57cec5SDimitry Andric 
48510b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 22, 4);
48520b57cec5SDimitry Andric   if (pred == 0xE || pred == 0xF) {
48530b57cec5SDimitry Andric     unsigned opc = fieldFromInstruction(Insn, 4, 28);
48540b57cec5SDimitry Andric     switch (opc) {
48550b57cec5SDimitry Andric       default:
48560b57cec5SDimitry Andric         return MCDisassembler::Fail;
48570b57cec5SDimitry Andric       case 0xf3bf8f4:
48580b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2DSB);
48590b57cec5SDimitry Andric         break;
48600b57cec5SDimitry Andric       case 0xf3bf8f5:
48610b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2DMB);
48620b57cec5SDimitry Andric         break;
48630b57cec5SDimitry Andric       case 0xf3bf8f6:
48640b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2ISB);
48650b57cec5SDimitry Andric         break;
48660b57cec5SDimitry Andric     }
48670b57cec5SDimitry Andric 
48680b57cec5SDimitry Andric     unsigned imm = fieldFromInstruction(Insn, 0, 4);
48690b57cec5SDimitry Andric     return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
48700b57cec5SDimitry Andric   }
48710b57cec5SDimitry Andric 
48720b57cec5SDimitry Andric   unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
48730b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
48740b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
48750b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
48760b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
48770b57cec5SDimitry Andric 
48780b57cec5SDimitry Andric   if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
48790b57cec5SDimitry Andric     return MCDisassembler::Fail;
48800b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
48810b57cec5SDimitry Andric     return MCDisassembler::Fail;
48820b57cec5SDimitry Andric 
48830b57cec5SDimitry Andric   return S;
48840b57cec5SDimitry Andric }
48850b57cec5SDimitry Andric 
48860b57cec5SDimitry Andric // Decode a shifted immediate operand.  These basically consist
48870b57cec5SDimitry Andric // of an 8-bit value, and a 4-bit directive that specifies either
48880b57cec5SDimitry Andric // a splat operation or a rotation.
DecodeT2SOImm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)488981ad6265SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, uint64_t Address,
489081ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
48910b57cec5SDimitry Andric   unsigned ctrl = fieldFromInstruction(Val, 10, 2);
48920b57cec5SDimitry Andric   if (ctrl == 0) {
48930b57cec5SDimitry Andric     unsigned byte = fieldFromInstruction(Val, 8, 2);
48940b57cec5SDimitry Andric     unsigned imm = fieldFromInstruction(Val, 0, 8);
48950b57cec5SDimitry Andric     switch (byte) {
48960b57cec5SDimitry Andric       case 0:
48970b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(imm));
48980b57cec5SDimitry Andric         break;
48990b57cec5SDimitry Andric       case 1:
49000b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 16) | imm));
49010b57cec5SDimitry Andric         break;
49020b57cec5SDimitry Andric       case 2:
49030b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8)));
49040b57cec5SDimitry Andric         break;
49050b57cec5SDimitry Andric       case 3:
49060b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) |
49070b57cec5SDimitry Andric                                              (imm << 8)  |  imm));
49080b57cec5SDimitry Andric         break;
49090b57cec5SDimitry Andric     }
49100b57cec5SDimitry Andric   } else {
49110b57cec5SDimitry Andric     unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
49120b57cec5SDimitry Andric     unsigned rot = fieldFromInstruction(Val, 7, 5);
4913fe013be4SDimitry Andric     unsigned imm = llvm::rotr<uint32_t>(unrot, rot);
49140b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
49150b57cec5SDimitry Andric   }
49160b57cec5SDimitry Andric 
49170b57cec5SDimitry Andric   return MCDisassembler::Success;
49180b57cec5SDimitry Andric }
49190b57cec5SDimitry Andric 
DecodeThumbBCCTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)492081ad6265SDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
492181ad6265SDimitry Andric                                                 uint64_t Address,
492281ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
49230b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
49240b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
49250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1)));
49260b57cec5SDimitry Andric   return MCDisassembler::Success;
49270b57cec5SDimitry Andric }
49280b57cec5SDimitry Andric 
DecodeThumbBLTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)49290b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
49300b57cec5SDimitry Andric                                                uint64_t Address,
493181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
49320b57cec5SDimitry Andric   // Val is passed in as S:J1:J2:imm10:imm11
49330b57cec5SDimitry Andric   // Note no trailing zero after imm11.  Also the J1 and J2 values are from
49340b57cec5SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
49350b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
49360b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
49370b57cec5SDimitry Andric   // and build the imm32 with one trailing zero as documented:
49380b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
49390b57cec5SDimitry Andric   unsigned S = (Val >> 23) & 1;
49400b57cec5SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
49410b57cec5SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
49420b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
49430b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
49440b57cec5SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
49450b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
49460b57cec5SDimitry Andric 
49470b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
49480b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
49490b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
49500b57cec5SDimitry Andric   return MCDisassembler::Success;
49510b57cec5SDimitry Andric }
49520b57cec5SDimitry Andric 
DecodeMemBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)49530b57cec5SDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
495481ad6265SDimitry Andric                                            uint64_t Address,
495581ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
49560b57cec5SDimitry Andric   if (Val & ~0xf)
49570b57cec5SDimitry Andric     return MCDisassembler::Fail;
49580b57cec5SDimitry Andric 
49590b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
49600b57cec5SDimitry Andric   return MCDisassembler::Success;
49610b57cec5SDimitry Andric }
49620b57cec5SDimitry Andric 
DecodeInstSyncBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)49630b57cec5SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
496481ad6265SDimitry Andric                                                 uint64_t Address,
496581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
49660b57cec5SDimitry Andric   if (Val & ~0xf)
49670b57cec5SDimitry Andric     return MCDisassembler::Fail;
49680b57cec5SDimitry Andric 
49690b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
49700b57cec5SDimitry Andric   return MCDisassembler::Success;
49710b57cec5SDimitry Andric }
49720b57cec5SDimitry Andric 
DecodeMSRMask(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)497381ad6265SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, uint64_t Address,
497481ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
49750b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49760b57cec5SDimitry Andric   const FeatureBitset &FeatureBits =
49770b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
49780b57cec5SDimitry Andric 
49790b57cec5SDimitry Andric   if (FeatureBits[ARM::FeatureMClass]) {
49800b57cec5SDimitry Andric     unsigned ValLow = Val & 0xff;
49810b57cec5SDimitry Andric 
49820b57cec5SDimitry Andric     // Validate the SYSm value first.
49830b57cec5SDimitry Andric     switch (ValLow) {
49840b57cec5SDimitry Andric     case  0: // apsr
49850b57cec5SDimitry Andric     case  1: // iapsr
49860b57cec5SDimitry Andric     case  2: // eapsr
49870b57cec5SDimitry Andric     case  3: // xpsr
49880b57cec5SDimitry Andric     case  5: // ipsr
49890b57cec5SDimitry Andric     case  6: // epsr
49900b57cec5SDimitry Andric     case  7: // iepsr
49910b57cec5SDimitry Andric     case  8: // msp
49920b57cec5SDimitry Andric     case  9: // psp
49930b57cec5SDimitry Andric     case 16: // primask
49940b57cec5SDimitry Andric     case 20: // control
49950b57cec5SDimitry Andric       break;
49960b57cec5SDimitry Andric     case 17: // basepri
49970b57cec5SDimitry Andric     case 18: // basepri_max
49980b57cec5SDimitry Andric     case 19: // faultmask
49990b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops]))
50000b57cec5SDimitry Andric         // Values basepri, basepri_max and faultmask are only valid for v7m.
50010b57cec5SDimitry Andric         return MCDisassembler::Fail;
50020b57cec5SDimitry Andric       break;
50030b57cec5SDimitry Andric     case 0x8a: // msplim_ns
50040b57cec5SDimitry Andric     case 0x8b: // psplim_ns
50050b57cec5SDimitry Andric     case 0x91: // basepri_ns
50060b57cec5SDimitry Andric     case 0x93: // faultmask_ns
50070b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV8MMainlineOps]))
50080b57cec5SDimitry Andric         return MCDisassembler::Fail;
5009bdd1243dSDimitry Andric       [[fallthrough]];
50100b57cec5SDimitry Andric     case 10:   // msplim
50110b57cec5SDimitry Andric     case 11:   // psplim
50120b57cec5SDimitry Andric     case 0x88: // msp_ns
50130b57cec5SDimitry Andric     case 0x89: // psp_ns
50140b57cec5SDimitry Andric     case 0x90: // primask_ns
50150b57cec5SDimitry Andric     case 0x94: // control_ns
50160b57cec5SDimitry Andric     case 0x98: // sp_ns
50170b57cec5SDimitry Andric       if (!(FeatureBits[ARM::Feature8MSecExt]))
50180b57cec5SDimitry Andric         return MCDisassembler::Fail;
50190b57cec5SDimitry Andric       break;
50204824e7fdSDimitry Andric     case 0x20: // pac_key_p_0
50214824e7fdSDimitry Andric     case 0x21: // pac_key_p_1
50224824e7fdSDimitry Andric     case 0x22: // pac_key_p_2
50234824e7fdSDimitry Andric     case 0x23: // pac_key_p_3
50244824e7fdSDimitry Andric     case 0x24: // pac_key_u_0
50254824e7fdSDimitry Andric     case 0x25: // pac_key_u_1
50264824e7fdSDimitry Andric     case 0x26: // pac_key_u_2
50274824e7fdSDimitry Andric     case 0x27: // pac_key_u_3
50284824e7fdSDimitry Andric     case 0xa0: // pac_key_p_0_ns
50294824e7fdSDimitry Andric     case 0xa1: // pac_key_p_1_ns
50304824e7fdSDimitry Andric     case 0xa2: // pac_key_p_2_ns
50314824e7fdSDimitry Andric     case 0xa3: // pac_key_p_3_ns
50324824e7fdSDimitry Andric     case 0xa4: // pac_key_u_0_ns
50334824e7fdSDimitry Andric     case 0xa5: // pac_key_u_1_ns
50344824e7fdSDimitry Andric     case 0xa6: // pac_key_u_2_ns
50354824e7fdSDimitry Andric     case 0xa7: // pac_key_u_3_ns
50364824e7fdSDimitry Andric       if (!(FeatureBits[ARM::FeaturePACBTI]))
50374824e7fdSDimitry Andric         return MCDisassembler::Fail;
50384824e7fdSDimitry Andric       break;
50390b57cec5SDimitry Andric     default:
50400b57cec5SDimitry Andric       // Architecturally defined as unpredictable
50410b57cec5SDimitry Andric       S = MCDisassembler::SoftFail;
50420b57cec5SDimitry Andric       break;
50430b57cec5SDimitry Andric     }
50440b57cec5SDimitry Andric 
50450b57cec5SDimitry Andric     if (Inst.getOpcode() == ARM::t2MSR_M) {
50460b57cec5SDimitry Andric       unsigned Mask = fieldFromInstruction(Val, 10, 2);
50470b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops])) {
50480b57cec5SDimitry Andric         // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
50490b57cec5SDimitry Andric         // unpredictable.
50500b57cec5SDimitry Andric         if (Mask != 2)
50510b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
50520b57cec5SDimitry Andric       }
50530b57cec5SDimitry Andric       else {
50540b57cec5SDimitry Andric         // The ARMv7-M architecture stores an additional 2-bit mask value in
50550b57cec5SDimitry Andric         // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
50560b57cec5SDimitry Andric         // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
50570b57cec5SDimitry Andric         // the NZCVQ bits should be moved by the instruction. Bit mask{0}
50580b57cec5SDimitry Andric         // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
50590b57cec5SDimitry Andric         // only if the processor includes the DSP extension.
50600b57cec5SDimitry Andric         if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
50610b57cec5SDimitry Andric             (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1)))
50620b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
50630b57cec5SDimitry Andric       }
50640b57cec5SDimitry Andric     }
50650b57cec5SDimitry Andric   } else {
50660b57cec5SDimitry Andric     // A/R class
50670b57cec5SDimitry Andric     if (Val == 0)
50680b57cec5SDimitry Andric       return MCDisassembler::Fail;
50690b57cec5SDimitry Andric   }
50700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
50710b57cec5SDimitry Andric   return S;
50720b57cec5SDimitry Andric }
50730b57cec5SDimitry Andric 
DecodeBankedReg(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)50740b57cec5SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
507581ad6265SDimitry Andric                                     uint64_t Address,
507681ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
50770b57cec5SDimitry Andric   unsigned R = fieldFromInstruction(Val, 5, 1);
50780b57cec5SDimitry Andric   unsigned SysM = fieldFromInstruction(Val, 0, 5);
50790b57cec5SDimitry Andric 
50800b57cec5SDimitry Andric   // The table of encodings for these banked registers comes from B9.2.3 of the
50810b57cec5SDimitry Andric   // ARM ARM. There are patterns, but nothing regular enough to make this logic
50820b57cec5SDimitry Andric   // neater. So by fiat, these values are UNPREDICTABLE:
50830b57cec5SDimitry Andric   if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM))
50840b57cec5SDimitry Andric     return MCDisassembler::Fail;
50850b57cec5SDimitry Andric 
50860b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
50870b57cec5SDimitry Andric   return MCDisassembler::Success;
50880b57cec5SDimitry Andric }
50890b57cec5SDimitry Andric 
DecodeDoubleRegLoad(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)50900b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
509181ad6265SDimitry Andric                                         uint64_t Address,
509281ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
50930b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
50940b57cec5SDimitry Andric 
50950b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
50960b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
50970b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
50980b57cec5SDimitry Andric 
50990b57cec5SDimitry Andric   if (Rn == 0xF)
51000b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
51010b57cec5SDimitry Andric 
51020b57cec5SDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
51030b57cec5SDimitry Andric     return MCDisassembler::Fail;
51040b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51050b57cec5SDimitry Andric     return MCDisassembler::Fail;
51060b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51070b57cec5SDimitry Andric     return MCDisassembler::Fail;
51080b57cec5SDimitry Andric 
51090b57cec5SDimitry Andric   return S;
51100b57cec5SDimitry Andric }
51110b57cec5SDimitry Andric 
DecodeDoubleRegStore(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)51120b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
51130b57cec5SDimitry Andric                                          uint64_t Address,
511481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
51150b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51160b57cec5SDimitry Andric 
51170b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
51180b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
51190b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51200b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51210b57cec5SDimitry Andric 
51220b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
51230b57cec5SDimitry Andric     return MCDisassembler::Fail;
51240b57cec5SDimitry Andric 
51250b57cec5SDimitry Andric   if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
51260b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
51270b57cec5SDimitry Andric 
51280b57cec5SDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
51290b57cec5SDimitry Andric     return MCDisassembler::Fail;
51300b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51310b57cec5SDimitry Andric     return MCDisassembler::Fail;
51320b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51330b57cec5SDimitry Andric     return MCDisassembler::Fail;
51340b57cec5SDimitry Andric 
51350b57cec5SDimitry Andric   return S;
51360b57cec5SDimitry Andric }
51370b57cec5SDimitry Andric 
DecodeLDRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)51380b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
513981ad6265SDimitry Andric                                     uint64_t Address,
514081ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
51410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51420b57cec5SDimitry Andric 
51430b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51440b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
51450b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
51460b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
51470b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
51480b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51490b57cec5SDimitry Andric 
51500b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
51510b57cec5SDimitry Andric 
51520b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
51530b57cec5SDimitry Andric     return MCDisassembler::Fail;
51540b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51550b57cec5SDimitry Andric     return MCDisassembler::Fail;
51560b57cec5SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
51570b57cec5SDimitry Andric     return MCDisassembler::Fail;
51580b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51590b57cec5SDimitry Andric     return MCDisassembler::Fail;
51600b57cec5SDimitry Andric 
51610b57cec5SDimitry Andric   return S;
51620b57cec5SDimitry Andric }
51630b57cec5SDimitry Andric 
DecodeLDRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)51640b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
516581ad6265SDimitry Andric                                     uint64_t Address,
516681ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
51670b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51680b57cec5SDimitry Andric 
51690b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51700b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
51710b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
51720b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
51730b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
51740b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51750b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
51760b57cec5SDimitry Andric 
51770b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
51780b57cec5SDimitry Andric   if (Rm == 0xF) S = MCDisassembler::SoftFail;
51790b57cec5SDimitry Andric 
51800b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
51810b57cec5SDimitry Andric     return MCDisassembler::Fail;
51820b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51830b57cec5SDimitry Andric     return MCDisassembler::Fail;
51840b57cec5SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
51850b57cec5SDimitry Andric     return MCDisassembler::Fail;
51860b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51870b57cec5SDimitry Andric     return MCDisassembler::Fail;
51880b57cec5SDimitry Andric 
51890b57cec5SDimitry Andric   return S;
51900b57cec5SDimitry Andric }
51910b57cec5SDimitry Andric 
DecodeSTRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)51920b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
519381ad6265SDimitry Andric                                     uint64_t Address,
519481ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
51950b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51960b57cec5SDimitry Andric 
51970b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51980b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
51990b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
52000b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
52010b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
52020b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
52030b57cec5SDimitry Andric 
52040b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
52050b57cec5SDimitry Andric 
52060b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52070b57cec5SDimitry Andric     return MCDisassembler::Fail;
52080b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
52090b57cec5SDimitry Andric     return MCDisassembler::Fail;
52100b57cec5SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
52110b57cec5SDimitry Andric     return MCDisassembler::Fail;
52120b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
52130b57cec5SDimitry Andric     return MCDisassembler::Fail;
52140b57cec5SDimitry Andric 
52150b57cec5SDimitry Andric   return S;
52160b57cec5SDimitry Andric }
52170b57cec5SDimitry Andric 
DecodeSTRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)52180b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
521981ad6265SDimitry Andric                                     uint64_t Address,
522081ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
52210b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
52220b57cec5SDimitry Andric 
52230b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
52240b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
52250b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
52260b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
52270b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
52280b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
52290b57cec5SDimitry Andric 
52300b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
52310b57cec5SDimitry Andric 
52320b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52330b57cec5SDimitry Andric     return MCDisassembler::Fail;
52340b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
52350b57cec5SDimitry Andric     return MCDisassembler::Fail;
52360b57cec5SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
52370b57cec5SDimitry Andric     return MCDisassembler::Fail;
52380b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
52390b57cec5SDimitry Andric     return MCDisassembler::Fail;
52400b57cec5SDimitry Andric 
52410b57cec5SDimitry Andric   return S;
52420b57cec5SDimitry Andric }
52430b57cec5SDimitry Andric 
DecodeVLD1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)524481ad6265SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
524581ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
52460b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
52470b57cec5SDimitry Andric 
52480b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
52490b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
52500b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
52510b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
52520b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
52530b57cec5SDimitry Andric 
52540b57cec5SDimitry Andric   unsigned align = 0;
52550b57cec5SDimitry Andric   unsigned index = 0;
52560b57cec5SDimitry Andric   switch (size) {
52570b57cec5SDimitry Andric     default:
52580b57cec5SDimitry Andric       return MCDisassembler::Fail;
52590b57cec5SDimitry Andric     case 0:
52600b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52610b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52620b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
52630b57cec5SDimitry Andric       break;
52640b57cec5SDimitry Andric     case 1:
52650b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
52660b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52670b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
52680b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52690b57cec5SDimitry Andric         align = 2;
52700b57cec5SDimitry Andric       break;
52710b57cec5SDimitry Andric     case 2:
52720b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
52730b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52740b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
52750b57cec5SDimitry Andric 
52760b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
52770b57cec5SDimitry Andric         case 0 :
52780b57cec5SDimitry Andric           align = 0; break;
52790b57cec5SDimitry Andric         case 3:
52800b57cec5SDimitry Andric           align = 4; break;
52810b57cec5SDimitry Andric         default:
52820b57cec5SDimitry Andric           return MCDisassembler::Fail;
52830b57cec5SDimitry Andric       }
52840b57cec5SDimitry Andric       break;
52850b57cec5SDimitry Andric   }
52860b57cec5SDimitry Andric 
52870b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
52880b57cec5SDimitry Andric     return MCDisassembler::Fail;
52890b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
52900b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52910b57cec5SDimitry Andric       return MCDisassembler::Fail;
52920b57cec5SDimitry Andric   }
52930b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52940b57cec5SDimitry Andric     return MCDisassembler::Fail;
52950b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
52960b57cec5SDimitry Andric   if (Rm != 0xF) {
52970b57cec5SDimitry Andric     if (Rm != 0xD) {
52980b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
52990b57cec5SDimitry Andric         return MCDisassembler::Fail;
53000b57cec5SDimitry Andric     } else
53010b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
53020b57cec5SDimitry Andric   }
53030b57cec5SDimitry Andric 
53040b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53050b57cec5SDimitry Andric     return MCDisassembler::Fail;
53060b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
53070b57cec5SDimitry Andric 
53080b57cec5SDimitry Andric   return S;
53090b57cec5SDimitry Andric }
53100b57cec5SDimitry Andric 
DecodeVST1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)531181ad6265SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
531281ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
53130b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
53140b57cec5SDimitry Andric 
53150b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
53160b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
53170b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
53180b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
53190b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
53200b57cec5SDimitry Andric 
53210b57cec5SDimitry Andric   unsigned align = 0;
53220b57cec5SDimitry Andric   unsigned index = 0;
53230b57cec5SDimitry Andric   switch (size) {
53240b57cec5SDimitry Andric     default:
53250b57cec5SDimitry Andric       return MCDisassembler::Fail;
53260b57cec5SDimitry Andric     case 0:
53270b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53280b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
53290b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
53300b57cec5SDimitry Andric       break;
53310b57cec5SDimitry Andric     case 1:
53320b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
53330b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
53340b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
53350b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53360b57cec5SDimitry Andric         align = 2;
53370b57cec5SDimitry Andric       break;
53380b57cec5SDimitry Andric     case 2:
53390b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
53400b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
53410b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
53420b57cec5SDimitry Andric 
53430b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
53440b57cec5SDimitry Andric         case 0:
53450b57cec5SDimitry Andric           align = 0; break;
53460b57cec5SDimitry Andric         case 3:
53470b57cec5SDimitry Andric           align = 4; break;
53480b57cec5SDimitry Andric         default:
53490b57cec5SDimitry Andric           return MCDisassembler::Fail;
53500b57cec5SDimitry Andric       }
53510b57cec5SDimitry Andric       break;
53520b57cec5SDimitry Andric   }
53530b57cec5SDimitry Andric 
53540b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
53550b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
53560b57cec5SDimitry Andric     return MCDisassembler::Fail;
53570b57cec5SDimitry Andric   }
53580b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
53590b57cec5SDimitry Andric     return MCDisassembler::Fail;
53600b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
53610b57cec5SDimitry Andric   if (Rm != 0xF) {
53620b57cec5SDimitry Andric     if (Rm != 0xD) {
53630b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
53640b57cec5SDimitry Andric     return MCDisassembler::Fail;
53650b57cec5SDimitry Andric     } else
53660b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
53670b57cec5SDimitry Andric   }
53680b57cec5SDimitry Andric 
53690b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53700b57cec5SDimitry Andric     return MCDisassembler::Fail;
53710b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
53720b57cec5SDimitry Andric 
53730b57cec5SDimitry Andric   return S;
53740b57cec5SDimitry Andric }
53750b57cec5SDimitry Andric 
DecodeVLD2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)537681ad6265SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
537781ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
53780b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
53790b57cec5SDimitry Andric 
53800b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
53810b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
53820b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
53830b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
53840b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
53850b57cec5SDimitry Andric 
53860b57cec5SDimitry Andric   unsigned align = 0;
53870b57cec5SDimitry Andric   unsigned index = 0;
53880b57cec5SDimitry Andric   unsigned inc = 1;
53890b57cec5SDimitry Andric   switch (size) {
53900b57cec5SDimitry Andric     default:
53910b57cec5SDimitry Andric       return MCDisassembler::Fail;
53920b57cec5SDimitry Andric     case 0:
53930b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
53940b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53950b57cec5SDimitry Andric         align = 2;
53960b57cec5SDimitry Andric       break;
53970b57cec5SDimitry Andric     case 1:
53980b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
53990b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54000b57cec5SDimitry Andric         align = 4;
54010b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54020b57cec5SDimitry Andric         inc = 2;
54030b57cec5SDimitry Andric       break;
54040b57cec5SDimitry Andric     case 2:
54050b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54060b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
54070b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
54080b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
54090b57cec5SDimitry Andric         align = 8;
54100b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
54110b57cec5SDimitry Andric         inc = 2;
54120b57cec5SDimitry Andric       break;
54130b57cec5SDimitry Andric   }
54140b57cec5SDimitry Andric 
54150b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
54160b57cec5SDimitry Andric     return MCDisassembler::Fail;
54170b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
54180b57cec5SDimitry Andric     return MCDisassembler::Fail;
54190b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
54200b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54210b57cec5SDimitry Andric       return MCDisassembler::Fail;
54220b57cec5SDimitry Andric   }
54230b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54240b57cec5SDimitry Andric     return MCDisassembler::Fail;
54250b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
54260b57cec5SDimitry Andric   if (Rm != 0xF) {
54270b57cec5SDimitry Andric     if (Rm != 0xD) {
54280b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
54290b57cec5SDimitry Andric         return MCDisassembler::Fail;
54300b57cec5SDimitry Andric     } else
54310b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
54320b57cec5SDimitry Andric   }
54330b57cec5SDimitry Andric 
54340b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
54350b57cec5SDimitry Andric     return MCDisassembler::Fail;
54360b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
54370b57cec5SDimitry Andric     return MCDisassembler::Fail;
54380b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
54390b57cec5SDimitry Andric 
54400b57cec5SDimitry Andric   return S;
54410b57cec5SDimitry Andric }
54420b57cec5SDimitry Andric 
DecodeVST2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)544381ad6265SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
544481ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
54450b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
54460b57cec5SDimitry Andric 
54470b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
54480b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
54490b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
54500b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
54510b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
54520b57cec5SDimitry Andric 
54530b57cec5SDimitry Andric   unsigned align = 0;
54540b57cec5SDimitry Andric   unsigned index = 0;
54550b57cec5SDimitry Andric   unsigned inc = 1;
54560b57cec5SDimitry Andric   switch (size) {
54570b57cec5SDimitry Andric     default:
54580b57cec5SDimitry Andric       return MCDisassembler::Fail;
54590b57cec5SDimitry Andric     case 0:
54600b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
54610b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54620b57cec5SDimitry Andric         align = 2;
54630b57cec5SDimitry Andric       break;
54640b57cec5SDimitry Andric     case 1:
54650b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
54660b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54670b57cec5SDimitry Andric         align = 4;
54680b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54690b57cec5SDimitry Andric         inc = 2;
54700b57cec5SDimitry Andric       break;
54710b57cec5SDimitry Andric     case 2:
54720b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54730b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
54740b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
54750b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
54760b57cec5SDimitry Andric         align = 8;
54770b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
54780b57cec5SDimitry Andric         inc = 2;
54790b57cec5SDimitry Andric       break;
54800b57cec5SDimitry Andric   }
54810b57cec5SDimitry Andric 
54820b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
54830b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54840b57cec5SDimitry Andric       return MCDisassembler::Fail;
54850b57cec5SDimitry Andric   }
54860b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54870b57cec5SDimitry Andric     return MCDisassembler::Fail;
54880b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
54890b57cec5SDimitry Andric   if (Rm != 0xF) {
54900b57cec5SDimitry Andric     if (Rm != 0xD) {
54910b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
54920b57cec5SDimitry Andric         return MCDisassembler::Fail;
54930b57cec5SDimitry Andric     } else
54940b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
54950b57cec5SDimitry Andric   }
54960b57cec5SDimitry Andric 
54970b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
54980b57cec5SDimitry Andric     return MCDisassembler::Fail;
54990b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
55000b57cec5SDimitry Andric     return MCDisassembler::Fail;
55010b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
55020b57cec5SDimitry Andric 
55030b57cec5SDimitry Andric   return S;
55040b57cec5SDimitry Andric }
55050b57cec5SDimitry Andric 
DecodeVLD3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)550681ad6265SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
550781ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
55080b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55090b57cec5SDimitry Andric 
55100b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
55110b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
55120b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
55130b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
55140b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
55150b57cec5SDimitry Andric 
55160b57cec5SDimitry Andric   unsigned align = 0;
55170b57cec5SDimitry Andric   unsigned index = 0;
55180b57cec5SDimitry Andric   unsigned inc = 1;
55190b57cec5SDimitry Andric   switch (size) {
55200b57cec5SDimitry Andric     default:
55210b57cec5SDimitry Andric       return MCDisassembler::Fail;
55220b57cec5SDimitry Andric     case 0:
55230b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55240b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55250b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
55260b57cec5SDimitry Andric       break;
55270b57cec5SDimitry Andric     case 1:
55280b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55290b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55300b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
55310b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
55320b57cec5SDimitry Andric         inc = 2;
55330b57cec5SDimitry Andric       break;
55340b57cec5SDimitry Andric     case 2:
55350b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
55360b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55370b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
55380b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
55390b57cec5SDimitry Andric         inc = 2;
55400b57cec5SDimitry Andric       break;
55410b57cec5SDimitry Andric   }
55420b57cec5SDimitry Andric 
55430b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
55440b57cec5SDimitry Andric     return MCDisassembler::Fail;
55450b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
55460b57cec5SDimitry Andric     return MCDisassembler::Fail;
55470b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
55480b57cec5SDimitry Andric     return MCDisassembler::Fail;
55490b57cec5SDimitry Andric 
55500b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
55510b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
55520b57cec5SDimitry Andric     return MCDisassembler::Fail;
55530b57cec5SDimitry Andric   }
55540b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
55550b57cec5SDimitry Andric     return MCDisassembler::Fail;
55560b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
55570b57cec5SDimitry Andric   if (Rm != 0xF) {
55580b57cec5SDimitry Andric     if (Rm != 0xD) {
55590b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
55600b57cec5SDimitry Andric     return MCDisassembler::Fail;
55610b57cec5SDimitry Andric     } else
55620b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
55630b57cec5SDimitry Andric   }
55640b57cec5SDimitry Andric 
55650b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
55660b57cec5SDimitry Andric     return MCDisassembler::Fail;
55670b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
55680b57cec5SDimitry Andric     return MCDisassembler::Fail;
55690b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
55700b57cec5SDimitry Andric     return MCDisassembler::Fail;
55710b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
55720b57cec5SDimitry Andric 
55730b57cec5SDimitry Andric   return S;
55740b57cec5SDimitry Andric }
55750b57cec5SDimitry Andric 
DecodeVST3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)557681ad6265SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
557781ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
55780b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55790b57cec5SDimitry Andric 
55800b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
55810b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
55820b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
55830b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
55840b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
55850b57cec5SDimitry Andric 
55860b57cec5SDimitry Andric   unsigned align = 0;
55870b57cec5SDimitry Andric   unsigned index = 0;
55880b57cec5SDimitry Andric   unsigned inc = 1;
55890b57cec5SDimitry Andric   switch (size) {
55900b57cec5SDimitry Andric     default:
55910b57cec5SDimitry Andric       return MCDisassembler::Fail;
55920b57cec5SDimitry Andric     case 0:
55930b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55940b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55950b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
55960b57cec5SDimitry Andric       break;
55970b57cec5SDimitry Andric     case 1:
55980b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55990b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
56000b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
56010b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
56020b57cec5SDimitry Andric         inc = 2;
56030b57cec5SDimitry Andric       break;
56040b57cec5SDimitry Andric     case 2:
56050b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
56060b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
56070b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
56080b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
56090b57cec5SDimitry Andric         inc = 2;
56100b57cec5SDimitry Andric       break;
56110b57cec5SDimitry Andric   }
56120b57cec5SDimitry Andric 
56130b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
56140b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56150b57cec5SDimitry Andric     return MCDisassembler::Fail;
56160b57cec5SDimitry Andric   }
56170b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56180b57cec5SDimitry Andric     return MCDisassembler::Fail;
56190b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
56200b57cec5SDimitry Andric   if (Rm != 0xF) {
56210b57cec5SDimitry Andric     if (Rm != 0xD) {
56220b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
56230b57cec5SDimitry Andric     return MCDisassembler::Fail;
56240b57cec5SDimitry Andric     } else
56250b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
56260b57cec5SDimitry Andric   }
56270b57cec5SDimitry Andric 
56280b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
56290b57cec5SDimitry Andric     return MCDisassembler::Fail;
56300b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
56310b57cec5SDimitry Andric     return MCDisassembler::Fail;
56320b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
56330b57cec5SDimitry Andric     return MCDisassembler::Fail;
56340b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
56350b57cec5SDimitry Andric 
56360b57cec5SDimitry Andric   return S;
56370b57cec5SDimitry Andric }
56380b57cec5SDimitry Andric 
DecodeVLD4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)563981ad6265SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
564081ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
56410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
56420b57cec5SDimitry Andric 
56430b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
56440b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
56450b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
56460b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
56470b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
56480b57cec5SDimitry Andric 
56490b57cec5SDimitry Andric   unsigned align = 0;
56500b57cec5SDimitry Andric   unsigned index = 0;
56510b57cec5SDimitry Andric   unsigned inc = 1;
56520b57cec5SDimitry Andric   switch (size) {
56530b57cec5SDimitry Andric     default:
56540b57cec5SDimitry Andric       return MCDisassembler::Fail;
56550b57cec5SDimitry Andric     case 0:
56560b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
56570b57cec5SDimitry Andric         align = 4;
56580b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
56590b57cec5SDimitry Andric       break;
56600b57cec5SDimitry Andric     case 1:
56610b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
56620b57cec5SDimitry Andric         align = 8;
56630b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
56640b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
56650b57cec5SDimitry Andric         inc = 2;
56660b57cec5SDimitry Andric       break;
56670b57cec5SDimitry Andric     case 2:
56680b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
56690b57cec5SDimitry Andric         case 0:
56700b57cec5SDimitry Andric           align = 0; break;
56710b57cec5SDimitry Andric         case 3:
56720b57cec5SDimitry Andric           return MCDisassembler::Fail;
56730b57cec5SDimitry Andric         default:
56740b57cec5SDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
56750b57cec5SDimitry Andric       }
56760b57cec5SDimitry Andric 
56770b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
56780b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
56790b57cec5SDimitry Andric         inc = 2;
56800b57cec5SDimitry Andric       break;
56810b57cec5SDimitry Andric   }
56820b57cec5SDimitry Andric 
56830b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
56840b57cec5SDimitry Andric     return MCDisassembler::Fail;
56850b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
56860b57cec5SDimitry Andric     return MCDisassembler::Fail;
56870b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
56880b57cec5SDimitry Andric     return MCDisassembler::Fail;
56890b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
56900b57cec5SDimitry Andric     return MCDisassembler::Fail;
56910b57cec5SDimitry Andric 
56920b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
56930b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56940b57cec5SDimitry Andric       return MCDisassembler::Fail;
56950b57cec5SDimitry Andric   }
56960b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56970b57cec5SDimitry Andric     return MCDisassembler::Fail;
56980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
56990b57cec5SDimitry Andric   if (Rm != 0xF) {
57000b57cec5SDimitry Andric     if (Rm != 0xD) {
57010b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
57020b57cec5SDimitry Andric         return MCDisassembler::Fail;
57030b57cec5SDimitry Andric     } else
57040b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
57050b57cec5SDimitry Andric   }
57060b57cec5SDimitry Andric 
57070b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
57080b57cec5SDimitry Andric     return MCDisassembler::Fail;
57090b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
57100b57cec5SDimitry Andric     return MCDisassembler::Fail;
57110b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
57120b57cec5SDimitry Andric     return MCDisassembler::Fail;
57130b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
57140b57cec5SDimitry Andric     return MCDisassembler::Fail;
57150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
57160b57cec5SDimitry Andric 
57170b57cec5SDimitry Andric   return S;
57180b57cec5SDimitry Andric }
57190b57cec5SDimitry Andric 
DecodeVST4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)572081ad6265SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
572181ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
57220b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
57230b57cec5SDimitry Andric 
57240b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
57250b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
57260b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
57270b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
57280b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
57290b57cec5SDimitry Andric 
57300b57cec5SDimitry Andric   unsigned align = 0;
57310b57cec5SDimitry Andric   unsigned index = 0;
57320b57cec5SDimitry Andric   unsigned inc = 1;
57330b57cec5SDimitry Andric   switch (size) {
57340b57cec5SDimitry Andric     default:
57350b57cec5SDimitry Andric       return MCDisassembler::Fail;
57360b57cec5SDimitry Andric     case 0:
57370b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
57380b57cec5SDimitry Andric         align = 4;
57390b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
57400b57cec5SDimitry Andric       break;
57410b57cec5SDimitry Andric     case 1:
57420b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
57430b57cec5SDimitry Andric         align = 8;
57440b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
57450b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
57460b57cec5SDimitry Andric         inc = 2;
57470b57cec5SDimitry Andric       break;
57480b57cec5SDimitry Andric     case 2:
57490b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
57500b57cec5SDimitry Andric         case 0:
57510b57cec5SDimitry Andric           align = 0; break;
57520b57cec5SDimitry Andric         case 3:
57530b57cec5SDimitry Andric           return MCDisassembler::Fail;
57540b57cec5SDimitry Andric         default:
57550b57cec5SDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
57560b57cec5SDimitry Andric       }
57570b57cec5SDimitry Andric 
57580b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
57590b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
57600b57cec5SDimitry Andric         inc = 2;
57610b57cec5SDimitry Andric       break;
57620b57cec5SDimitry Andric   }
57630b57cec5SDimitry Andric 
57640b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
57650b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
57660b57cec5SDimitry Andric     return MCDisassembler::Fail;
57670b57cec5SDimitry Andric   }
57680b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
57690b57cec5SDimitry Andric     return MCDisassembler::Fail;
57700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
57710b57cec5SDimitry Andric   if (Rm != 0xF) {
57720b57cec5SDimitry Andric     if (Rm != 0xD) {
57730b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
57740b57cec5SDimitry Andric     return MCDisassembler::Fail;
57750b57cec5SDimitry Andric     } else
57760b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
57770b57cec5SDimitry Andric   }
57780b57cec5SDimitry Andric 
57790b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
57800b57cec5SDimitry Andric     return MCDisassembler::Fail;
57810b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
57820b57cec5SDimitry Andric     return MCDisassembler::Fail;
57830b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
57840b57cec5SDimitry Andric     return MCDisassembler::Fail;
57850b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
57860b57cec5SDimitry Andric     return MCDisassembler::Fail;
57870b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
57880b57cec5SDimitry Andric 
57890b57cec5SDimitry Andric   return S;
57900b57cec5SDimitry Andric }
57910b57cec5SDimitry Andric 
DecodeVMOVSRR(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)579281ad6265SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, uint64_t Address,
579381ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
57940b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
57950b57cec5SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
57960b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
57970b57cec5SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
57980b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
57990b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
58000b57cec5SDimitry Andric 
58010b57cec5SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
58020b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58030b57cec5SDimitry Andric 
58040b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
58050b57cec5SDimitry Andric     return MCDisassembler::Fail;
58060b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
58070b57cec5SDimitry Andric     return MCDisassembler::Fail;
58080b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
58090b57cec5SDimitry Andric     return MCDisassembler::Fail;
58100b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
58110b57cec5SDimitry Andric     return MCDisassembler::Fail;
58120b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
58130b57cec5SDimitry Andric     return MCDisassembler::Fail;
58140b57cec5SDimitry Andric 
58150b57cec5SDimitry Andric   return S;
58160b57cec5SDimitry Andric }
58170b57cec5SDimitry Andric 
DecodeVMOVRRS(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)581881ad6265SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, uint64_t Address,
581981ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
58200b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58210b57cec5SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
58220b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
58230b57cec5SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
58240b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
58250b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
58260b57cec5SDimitry Andric 
58270b57cec5SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
58280b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58290b57cec5SDimitry Andric 
58300b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
58310b57cec5SDimitry Andric     return MCDisassembler::Fail;
58320b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
58330b57cec5SDimitry Andric     return MCDisassembler::Fail;
58340b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
58350b57cec5SDimitry Andric     return MCDisassembler::Fail;
58360b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
58370b57cec5SDimitry Andric     return MCDisassembler::Fail;
58380b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
58390b57cec5SDimitry Andric     return MCDisassembler::Fail;
58400b57cec5SDimitry Andric 
58410b57cec5SDimitry Andric   return S;
58420b57cec5SDimitry Andric }
58430b57cec5SDimitry Andric 
DecodeIT(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)584481ad6265SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, uint64_t Address,
584581ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
58460b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58470b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 4, 4);
58480b57cec5SDimitry Andric   unsigned mask = fieldFromInstruction(Insn, 0, 4);
58490b57cec5SDimitry Andric 
58500b57cec5SDimitry Andric   if (pred == 0xF) {
58510b57cec5SDimitry Andric     pred = 0xE;
58520b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58530b57cec5SDimitry Andric   }
58540b57cec5SDimitry Andric 
58550b57cec5SDimitry Andric   if (mask == 0x0)
58560b57cec5SDimitry Andric     return MCDisassembler::Fail;
58570b57cec5SDimitry Andric 
58580b57cec5SDimitry Andric   // IT masks are encoded as a sequence of replacement low-order bits
58590b57cec5SDimitry Andric   // for the condition code. So if the low bit of the starting
58600b57cec5SDimitry Andric   // condition code is 1, then we have to flip all the bits above the
58610b57cec5SDimitry Andric   // terminating bit (which is the lowest 1 bit).
58620b57cec5SDimitry Andric   if (pred & 1) {
58630b57cec5SDimitry Andric     unsigned LowBit = mask & -mask;
58640b57cec5SDimitry Andric     unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
58650b57cec5SDimitry Andric     mask ^= BitsAboveLowBit;
58660b57cec5SDimitry Andric   }
58670b57cec5SDimitry Andric 
58680b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(pred));
58690b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(mask));
58700b57cec5SDimitry Andric   return S;
58710b57cec5SDimitry Andric }
58720b57cec5SDimitry Andric 
DecodeT2LDRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)587381ad6265SDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
587481ad6265SDimitry Andric                                                uint64_t Address,
587581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
58760b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58770b57cec5SDimitry Andric 
58780b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
58790b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
58800b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
58810b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
58820b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
58830b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
58840b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
58850b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
58860b57cec5SDimitry Andric 
58870b57cec5SDimitry Andric   addr |= (U << 8) | (Rn << 9);
58880b57cec5SDimitry Andric 
58890b57cec5SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
58900b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
58910b57cec5SDimitry Andric   if (Rt == Rt2)
58920b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
58930b57cec5SDimitry Andric 
58940b57cec5SDimitry Andric   // Rt
58950b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
58960b57cec5SDimitry Andric     return MCDisassembler::Fail;
58970b57cec5SDimitry Andric   // Rt2
58980b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
58990b57cec5SDimitry Andric     return MCDisassembler::Fail;
59000b57cec5SDimitry Andric   // Writeback operand
59010b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
59020b57cec5SDimitry Andric     return MCDisassembler::Fail;
59030b57cec5SDimitry Andric   // addr
59040b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
59050b57cec5SDimitry Andric     return MCDisassembler::Fail;
59060b57cec5SDimitry Andric 
59070b57cec5SDimitry Andric   return S;
59080b57cec5SDimitry Andric }
59090b57cec5SDimitry Andric 
DecodeT2STRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)591081ad6265SDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
591181ad6265SDimitry Andric                                                uint64_t Address,
591281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
59130b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59140b57cec5SDimitry Andric 
59150b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
59160b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
59170b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
59180b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
59190b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
59200b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
59210b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
59220b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
59230b57cec5SDimitry Andric 
59240b57cec5SDimitry Andric   addr |= (U << 8) | (Rn << 9);
59250b57cec5SDimitry Andric 
59260b57cec5SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
59270b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
59280b57cec5SDimitry Andric 
59290b57cec5SDimitry Andric   // Writeback operand
59300b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
59310b57cec5SDimitry Andric     return MCDisassembler::Fail;
59320b57cec5SDimitry Andric   // Rt
59330b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
59340b57cec5SDimitry Andric     return MCDisassembler::Fail;
59350b57cec5SDimitry Andric   // Rt2
59360b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
59370b57cec5SDimitry Andric     return MCDisassembler::Fail;
59380b57cec5SDimitry Andric   // addr
59390b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
59400b57cec5SDimitry Andric     return MCDisassembler::Fail;
59410b57cec5SDimitry Andric 
59420b57cec5SDimitry Andric   return S;
59430b57cec5SDimitry Andric }
59440b57cec5SDimitry Andric 
DecodeT2Adr(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)594581ad6265SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, uint64_t Address,
594681ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
59470b57cec5SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
59480b57cec5SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
59490b57cec5SDimitry Andric   if (sign1 != sign2) return MCDisassembler::Fail;
5950480093f4SDimitry Andric   const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
5951480093f4SDimitry Andric   assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst");
5952480093f4SDimitry Andric   DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder);
59530b57cec5SDimitry Andric 
59540b57cec5SDimitry Andric   unsigned Val = fieldFromInstruction(Insn, 0, 8);
59550b57cec5SDimitry Andric   Val |= fieldFromInstruction(Insn, 12, 3) << 8;
59560b57cec5SDimitry Andric   Val |= fieldFromInstruction(Insn, 26, 1) << 11;
5957480093f4SDimitry Andric   // If sign, then it is decreasing the address.
5958480093f4SDimitry Andric   if (sign1) {
5959480093f4SDimitry Andric     // Following ARMv7 Architecture Manual, when the offset
5960480093f4SDimitry Andric     // is zero, it is decoded as a subw, not as a adr.w
5961480093f4SDimitry Andric     if (!Val) {
5962480093f4SDimitry Andric       Inst.setOpcode(ARM::t2SUBri12);
5963480093f4SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::PC));
5964480093f4SDimitry Andric     } else
5965480093f4SDimitry Andric       Val = -Val;
5966480093f4SDimitry Andric   }
5967480093f4SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
5968480093f4SDimitry Andric   return S;
59690b57cec5SDimitry Andric }
59700b57cec5SDimitry Andric 
DecodeT2ShifterImmOperand(MCInst & Inst,uint32_t Val,uint64_t Address,const MCDisassembler * Decoder)59710b57cec5SDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
59720b57cec5SDimitry Andric                                               uint64_t Address,
597381ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
59740b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59750b57cec5SDimitry Andric 
59760b57cec5SDimitry Andric   // Shift of "asr #32" is not allowed in Thumb2 mode.
59770b57cec5SDimitry Andric   if (Val == 0x20) S = MCDisassembler::Fail;
59780b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
59790b57cec5SDimitry Andric   return S;
59800b57cec5SDimitry Andric }
59810b57cec5SDimitry Andric 
DecodeSwap(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)598281ad6265SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, uint64_t Address,
598381ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
59840b57cec5SDimitry Andric   unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
59850b57cec5SDimitry Andric   unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
59860b57cec5SDimitry Andric   unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
59870b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
59880b57cec5SDimitry Andric 
59890b57cec5SDimitry Andric   if (pred == 0xF)
59900b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
59910b57cec5SDimitry Andric 
59920b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59930b57cec5SDimitry Andric 
59940b57cec5SDimitry Andric   if (Rt == Rn || Rn == Rt2)
59950b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
59960b57cec5SDimitry Andric 
59970b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
59980b57cec5SDimitry Andric     return MCDisassembler::Fail;
59990b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
60000b57cec5SDimitry Andric     return MCDisassembler::Fail;
60010b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
60020b57cec5SDimitry Andric     return MCDisassembler::Fail;
60030b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
60040b57cec5SDimitry Andric     return MCDisassembler::Fail;
60050b57cec5SDimitry Andric 
60060b57cec5SDimitry Andric   return S;
60070b57cec5SDimitry Andric }
60080b57cec5SDimitry Andric 
DecodeVCVTD(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)600981ad6265SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, uint64_t Address,
601081ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
60110b57cec5SDimitry Andric   const FeatureBitset &featureBits =
60120b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
60130b57cec5SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
60140b57cec5SDimitry Andric 
60150b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
60160b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
60170b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
60180b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
60190b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
60200b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
60210b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
60220b57cec5SDimitry Andric 
60230b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
60240b57cec5SDimitry Andric 
60250b57cec5SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
60260b57cec5SDimitry Andric   if (!(imm & 0x38)) {
60270b57cec5SDimitry Andric     if (cmode == 0xF) {
60280b57cec5SDimitry Andric       if (op == 1) return MCDisassembler::Fail;
60290b57cec5SDimitry Andric       Inst.setOpcode(ARM::VMOVv2f32);
60300b57cec5SDimitry Andric     }
60310b57cec5SDimitry Andric     if (hasFullFP16) {
60320b57cec5SDimitry Andric       if (cmode == 0xE) {
60330b57cec5SDimitry Andric         if (op == 1) {
60340b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv1i64);
60350b57cec5SDimitry Andric         } else {
60360b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv8i8);
60370b57cec5SDimitry Andric         }
60380b57cec5SDimitry Andric       }
60390b57cec5SDimitry Andric       if (cmode == 0xD) {
60400b57cec5SDimitry Andric         if (op == 1) {
60410b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
60420b57cec5SDimitry Andric         } else {
60430b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
60440b57cec5SDimitry Andric         }
60450b57cec5SDimitry Andric       }
60460b57cec5SDimitry Andric       if (cmode == 0xC) {
60470b57cec5SDimitry Andric         if (op == 1) {
60480b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
60490b57cec5SDimitry Andric         } else {
60500b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
60510b57cec5SDimitry Andric         }
60520b57cec5SDimitry Andric       }
60530b57cec5SDimitry Andric     }
60548bcb0991SDimitry Andric     return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
60550b57cec5SDimitry Andric   }
60560b57cec5SDimitry Andric 
60570b57cec5SDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
60580b57cec5SDimitry Andric 
60590b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
60600b57cec5SDimitry Andric     return MCDisassembler::Fail;
60610b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
60620b57cec5SDimitry Andric     return MCDisassembler::Fail;
60630b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
60640b57cec5SDimitry Andric 
60650b57cec5SDimitry Andric   return S;
60660b57cec5SDimitry Andric }
60670b57cec5SDimitry Andric 
DecodeVCVTQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)606881ad6265SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, uint64_t Address,
606981ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
60700b57cec5SDimitry Andric   const FeatureBitset &featureBits =
60710b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
60720b57cec5SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
60730b57cec5SDimitry Andric 
60740b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
60750b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
60760b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
60770b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
60780b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
60790b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
60800b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
60810b57cec5SDimitry Andric 
60820b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
60830b57cec5SDimitry Andric 
60840b57cec5SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
60850b57cec5SDimitry Andric   if (!(imm & 0x38)) {
60860b57cec5SDimitry Andric     if (cmode == 0xF) {
60870b57cec5SDimitry Andric       if (op == 1) return MCDisassembler::Fail;
60880b57cec5SDimitry Andric       Inst.setOpcode(ARM::VMOVv4f32);
60890b57cec5SDimitry Andric     }
60900b57cec5SDimitry Andric     if (hasFullFP16) {
60910b57cec5SDimitry Andric       if (cmode == 0xE) {
60920b57cec5SDimitry Andric         if (op == 1) {
60930b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i64);
60940b57cec5SDimitry Andric         } else {
60950b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv16i8);
60960b57cec5SDimitry Andric         }
60970b57cec5SDimitry Andric       }
60980b57cec5SDimitry Andric       if (cmode == 0xD) {
60990b57cec5SDimitry Andric         if (op == 1) {
61000b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
61010b57cec5SDimitry Andric         } else {
61020b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
61030b57cec5SDimitry Andric         }
61040b57cec5SDimitry Andric       }
61050b57cec5SDimitry Andric       if (cmode == 0xC) {
61060b57cec5SDimitry Andric         if (op == 1) {
61070b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
61080b57cec5SDimitry Andric         } else {
61090b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
61100b57cec5SDimitry Andric         }
61110b57cec5SDimitry Andric       }
61120b57cec5SDimitry Andric     }
61138bcb0991SDimitry Andric     return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
61140b57cec5SDimitry Andric   }
61150b57cec5SDimitry Andric 
61160b57cec5SDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
61170b57cec5SDimitry Andric 
61180b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
61190b57cec5SDimitry Andric     return MCDisassembler::Fail;
61200b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
61210b57cec5SDimitry Andric     return MCDisassembler::Fail;
61220b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
61230b57cec5SDimitry Andric 
61240b57cec5SDimitry Andric   return S;
61250b57cec5SDimitry Andric }
61260b57cec5SDimitry Andric 
612781ad6265SDimitry Andric static DecodeStatus
DecodeNEONComplexLane64Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)612881ad6265SDimitry Andric DecodeNEONComplexLane64Instruction(MCInst &Inst, unsigned Insn,
61290b57cec5SDimitry Andric                                    uint64_t Address,
613081ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
61310b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
61320b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
61330b57cec5SDimitry Andric   unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
61340b57cec5SDimitry Andric   Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
61350b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
61360b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
61370b57cec5SDimitry Andric   unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
61380b57cec5SDimitry Andric   unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
61390b57cec5SDimitry Andric 
61400b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61410b57cec5SDimitry Andric 
61420b57cec5SDimitry Andric   auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
61430b57cec5SDimitry Andric 
61440b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
61450b57cec5SDimitry Andric     return MCDisassembler::Fail;
61460b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
61470b57cec5SDimitry Andric     return MCDisassembler::Fail;
61480b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
61490b57cec5SDimitry Andric     return MCDisassembler::Fail;
61500b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
61510b57cec5SDimitry Andric     return MCDisassembler::Fail;
61520b57cec5SDimitry Andric   // The lane index does not have any bits in the encoding, because it can only
61530b57cec5SDimitry Andric   // be 0.
61540b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
61550b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(rotate));
61560b57cec5SDimitry Andric 
61570b57cec5SDimitry Andric   return S;
61580b57cec5SDimitry Andric }
61590b57cec5SDimitry Andric 
DecodeLDR(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)616081ad6265SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address,
616181ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
61620b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61630b57cec5SDimitry Andric 
61640b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
61650b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
61660b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
61670b57cec5SDimitry Andric   Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
61680b57cec5SDimitry Andric   unsigned Cond = fieldFromInstruction(Val, 28, 4);
61690b57cec5SDimitry Andric 
61700b57cec5SDimitry Andric   if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
61710b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
61720b57cec5SDimitry Andric 
61730b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
61740b57cec5SDimitry Andric     return MCDisassembler::Fail;
61750b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
61760b57cec5SDimitry Andric     return MCDisassembler::Fail;
61770b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
61780b57cec5SDimitry Andric     return MCDisassembler::Fail;
61790b57cec5SDimitry Andric   if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
61800b57cec5SDimitry Andric     return MCDisassembler::Fail;
61810b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
61820b57cec5SDimitry Andric     return MCDisassembler::Fail;
61830b57cec5SDimitry Andric 
61840b57cec5SDimitry Andric   return S;
61850b57cec5SDimitry Andric }
61860b57cec5SDimitry Andric 
DecoderForMRRC2AndMCRR2(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)61870b57cec5SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
618881ad6265SDimitry Andric                                             uint64_t Address,
618981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
61900b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61910b57cec5SDimitry Andric 
61920b57cec5SDimitry Andric   unsigned CRm = fieldFromInstruction(Val, 0, 4);
61930b57cec5SDimitry Andric   unsigned opc1 = fieldFromInstruction(Val, 4, 4);
61940b57cec5SDimitry Andric   unsigned cop = fieldFromInstruction(Val, 8, 4);
61950b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
61960b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
61970b57cec5SDimitry Andric 
61980b57cec5SDimitry Andric   if ((cop & ~0x1) == 0xa)
61990b57cec5SDimitry Andric     return MCDisassembler::Fail;
62000b57cec5SDimitry Andric 
62010b57cec5SDimitry Andric   if (Rt == Rt2)
62020b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
62030b57cec5SDimitry Andric 
62040b57cec5SDimitry Andric   // We have to check if the instruction is MRRC2
62050b57cec5SDimitry Andric   // or MCRR2 when constructing the operands for
62060b57cec5SDimitry Andric   // Inst. Reason is because MRRC2 stores to two
6207*c9157d92SDimitry Andric   // registers so it's tablegen desc has two
62080b57cec5SDimitry Andric   // outputs whereas MCRR doesn't store to any
62090b57cec5SDimitry Andric   // registers so all of it's operands are listed
62100b57cec5SDimitry Andric   // as inputs, therefore the operand order for
62110b57cec5SDimitry Andric   // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
62120b57cec5SDimitry Andric   // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
62130b57cec5SDimitry Andric 
62140b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MRRC2) {
62150b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
62160b57cec5SDimitry Andric       return MCDisassembler::Fail;
62170b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
62180b57cec5SDimitry Andric       return MCDisassembler::Fail;
62190b57cec5SDimitry Andric   }
62200b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(cop));
62210b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(opc1));
62220b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MCRR2) {
62230b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
62240b57cec5SDimitry Andric       return MCDisassembler::Fail;
62250b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
62260b57cec5SDimitry Andric       return MCDisassembler::Fail;
62270b57cec5SDimitry Andric   }
62280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRm));
62290b57cec5SDimitry Andric 
62300b57cec5SDimitry Andric   return S;
62310b57cec5SDimitry Andric }
62320b57cec5SDimitry Andric 
DecodeForVMRSandVMSR(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)62330b57cec5SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
62340b57cec5SDimitry Andric                                          uint64_t Address,
623581ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
62360b57cec5SDimitry Andric   const FeatureBitset &featureBits =
62370b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
62380b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
62390b57cec5SDimitry Andric 
62400b57cec5SDimitry Andric   // Add explicit operand for the destination sysreg, for cases where
62410b57cec5SDimitry Andric   // we have to model it for code generation purposes.
62420b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
62430b57cec5SDimitry Andric   case ARM::VMSR_FPSCR_NZCVQC:
62440b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
62450b57cec5SDimitry Andric     break;
62460b57cec5SDimitry Andric   case ARM::VMSR_P0:
62470b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::VPR));
62480b57cec5SDimitry Andric     break;
62490b57cec5SDimitry Andric   }
62500b57cec5SDimitry Andric 
62510b57cec5SDimitry Andric   if (Inst.getOpcode() != ARM::FMSTAT) {
62520b57cec5SDimitry Andric     unsigned Rt = fieldFromInstruction(Val, 12, 4);
62530b57cec5SDimitry Andric 
62540b57cec5SDimitry Andric     if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
62550b57cec5SDimitry Andric       if (Rt == 13 || Rt == 15)
62560b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
62570b57cec5SDimitry Andric       Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
62580b57cec5SDimitry Andric     } else
62590b57cec5SDimitry Andric       Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
62600b57cec5SDimitry Andric   }
62610b57cec5SDimitry Andric 
62620b57cec5SDimitry Andric   // Add explicit operand for the source sysreg, similarly to above.
62630b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
62640b57cec5SDimitry Andric   case ARM::VMRS_FPSCR_NZCVQC:
62650b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
62660b57cec5SDimitry Andric     break;
62670b57cec5SDimitry Andric   case ARM::VMRS_P0:
62680b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::VPR));
62690b57cec5SDimitry Andric     break;
62700b57cec5SDimitry Andric   }
62710b57cec5SDimitry Andric 
62720b57cec5SDimitry Andric   if (featureBits[ARM::ModeThumb]) {
62730b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARMCC::AL));
62740b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
62750b57cec5SDimitry Andric   } else {
62760b57cec5SDimitry Andric     unsigned pred = fieldFromInstruction(Val, 28, 4);
62770b57cec5SDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
62780b57cec5SDimitry Andric       return MCDisassembler::Fail;
62790b57cec5SDimitry Andric   }
62800b57cec5SDimitry Andric 
62810b57cec5SDimitry Andric   return S;
62820b57cec5SDimitry Andric }
62830b57cec5SDimitry Andric 
62840b57cec5SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
DecodeBFLabelOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)62850b57cec5SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned Val,
62860b57cec5SDimitry Andric                                          uint64_t Address,
628781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
62880b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
62890b57cec5SDimitry Andric   if (Val == 0 && !zeroPermitted)
62900b57cec5SDimitry Andric     S = MCDisassembler::Fail;
62910b57cec5SDimitry Andric 
62920b57cec5SDimitry Andric   uint64_t DecVal;
62930b57cec5SDimitry Andric   if (isSigned)
62940b57cec5SDimitry Andric     DecVal = SignExtend32<size + 1>(Val << 1);
62950b57cec5SDimitry Andric   else
62960b57cec5SDimitry Andric     DecVal = (Val << 1);
62970b57cec5SDimitry Andric 
62980b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + DecVal + 4, true, 4, Inst,
62990b57cec5SDimitry Andric                                 Decoder))
63000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(isNeg ? -DecVal : DecVal));
63010b57cec5SDimitry Andric   return S;
63020b57cec5SDimitry Andric }
63030b57cec5SDimitry Andric 
DecodeBFAfterTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)63040b57cec5SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned Val,
63050b57cec5SDimitry Andric                                                uint64_t Address,
630681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
63070b57cec5SDimitry Andric 
63080b57cec5SDimitry Andric   uint64_t LocImm = Inst.getOperand(0).getImm();
63090b57cec5SDimitry Andric   Val = LocImm + (2 << Val);
63100b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + Val + 4, true, 4, Inst,
63110b57cec5SDimitry Andric                                 Decoder))
63120b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val));
63130b57cec5SDimitry Andric   return MCDisassembler::Success;
63140b57cec5SDimitry Andric }
63150b57cec5SDimitry Andric 
DecodePredNoALOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)63160b57cec5SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
63170b57cec5SDimitry Andric                                           uint64_t Address,
631881ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
63190b57cec5SDimitry Andric   if (Val >= ARMCC::AL)  // also exclude the non-condition NV
63200b57cec5SDimitry Andric     return MCDisassembler::Fail;
63210b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
63220b57cec5SDimitry Andric   return MCDisassembler::Success;
63230b57cec5SDimitry Andric }
63240b57cec5SDimitry Andric 
DecodeLOLoop(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)63250b57cec5SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
632681ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
63270b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63280b57cec5SDimitry Andric 
63290b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MVE_LCTP)
63300b57cec5SDimitry Andric     return S;
63310b57cec5SDimitry Andric 
63320b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 11, 1) |
63330b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 1, 10) << 1;
63340b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
63350b57cec5SDimitry Andric   case ARM::t2LEUpdate:
63360b57cec5SDimitry Andric   case ARM::MVE_LETP:
63370b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
63380b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
6339bdd1243dSDimitry Andric     [[fallthrough]];
63400b57cec5SDimitry Andric   case ARM::t2LE:
63410b57cec5SDimitry Andric     if (!Check(S, DecodeBFLabelOperand<false, true, true, 11>(
63420b57cec5SDimitry Andric                    Inst, Imm, Address, Decoder)))
63430b57cec5SDimitry Andric       return MCDisassembler::Fail;
63440b57cec5SDimitry Andric     break;
63450b57cec5SDimitry Andric   case ARM::t2WLS:
63460b57cec5SDimitry Andric   case ARM::MVE_WLSTP_8:
63470b57cec5SDimitry Andric   case ARM::MVE_WLSTP_16:
63480b57cec5SDimitry Andric   case ARM::MVE_WLSTP_32:
63490b57cec5SDimitry Andric   case ARM::MVE_WLSTP_64:
63500b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
63510b57cec5SDimitry Andric     if (!Check(S,
63520b57cec5SDimitry Andric                DecoderGPRRegisterClass(Inst, fieldFromInstruction(Insn, 16, 4),
63530b57cec5SDimitry Andric                                        Address, Decoder)) ||
63540b57cec5SDimitry Andric         !Check(S, DecodeBFLabelOperand<false, false, true, 11>(
63550b57cec5SDimitry Andric                    Inst, Imm, Address, Decoder)))
63560b57cec5SDimitry Andric       return MCDisassembler::Fail;
63570b57cec5SDimitry Andric     break;
63580b57cec5SDimitry Andric   case ARM::t2DLS:
63590b57cec5SDimitry Andric   case ARM::MVE_DLSTP_8:
63600b57cec5SDimitry Andric   case ARM::MVE_DLSTP_16:
63610b57cec5SDimitry Andric   case ARM::MVE_DLSTP_32:
63620b57cec5SDimitry Andric   case ARM::MVE_DLSTP_64:
63630b57cec5SDimitry Andric     unsigned Rn = fieldFromInstruction(Insn, 16, 4);
63640b57cec5SDimitry Andric     if (Rn == 0xF) {
63650b57cec5SDimitry Andric       // Enforce all the rest of the instruction bits in LCTP, which
63660b57cec5SDimitry Andric       // won't have been reliably checked based on LCTP's own tablegen
63670b57cec5SDimitry Andric       // record, because we came to this decode by a roundabout route.
63680b57cec5SDimitry Andric       uint32_t CanonicalLCTP = 0xF00FE001, SBZMask = 0x00300FFE;
63690b57cec5SDimitry Andric       if ((Insn & ~SBZMask) != CanonicalLCTP)
63700b57cec5SDimitry Andric         return MCDisassembler::Fail;   // a mandatory bit is wrong: hard fail
63710b57cec5SDimitry Andric       if (Insn != CanonicalLCTP)
63720b57cec5SDimitry Andric         Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail
63730b57cec5SDimitry Andric 
63740b57cec5SDimitry Andric       Inst.setOpcode(ARM::MVE_LCTP);
63750b57cec5SDimitry Andric     } else {
63760b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::LR));
63770b57cec5SDimitry Andric       if (!Check(S, DecoderGPRRegisterClass(Inst,
63780b57cec5SDimitry Andric                                             fieldFromInstruction(Insn, 16, 4),
63790b57cec5SDimitry Andric                                             Address, Decoder)))
63800b57cec5SDimitry Andric         return MCDisassembler::Fail;
63810b57cec5SDimitry Andric     }
63820b57cec5SDimitry Andric     break;
63830b57cec5SDimitry Andric   }
63840b57cec5SDimitry Andric   return S;
63850b57cec5SDimitry Andric }
63860b57cec5SDimitry Andric 
DecodeLongShiftOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)63870b57cec5SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
63880b57cec5SDimitry Andric                                            uint64_t Address,
638981ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
63900b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63910b57cec5SDimitry Andric 
63920b57cec5SDimitry Andric   if (Val == 0)
63930b57cec5SDimitry Andric     Val = 32;
63940b57cec5SDimitry Andric 
63950b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
63960b57cec5SDimitry Andric 
63970b57cec5SDimitry Andric   return S;
63980b57cec5SDimitry Andric }
63990b57cec5SDimitry Andric 
DecodetGPROddRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)64000b57cec5SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
640181ad6265SDimitry Andric                                                uint64_t Address,
640281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
64030b57cec5SDimitry Andric   if ((RegNo) + 1 > 11)
64040b57cec5SDimitry Andric     return MCDisassembler::Fail;
64050b57cec5SDimitry Andric 
64060b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[(RegNo) + 1];
64070b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64080b57cec5SDimitry Andric   return MCDisassembler::Success;
64090b57cec5SDimitry Andric }
64100b57cec5SDimitry Andric 
DecodetGPREvenRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)64110b57cec5SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
641281ad6265SDimitry Andric                                                 uint64_t Address,
641381ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
64140b57cec5SDimitry Andric   if ((RegNo) > 14)
64150b57cec5SDimitry Andric     return MCDisassembler::Fail;
64160b57cec5SDimitry Andric 
64170b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[(RegNo)];
64180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64190b57cec5SDimitry Andric   return MCDisassembler::Success;
64200b57cec5SDimitry Andric }
64210b57cec5SDimitry Andric 
64225ffd83dbSDimitry Andric static DecodeStatus
DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)64235ffd83dbSDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
642481ad6265SDimitry Andric                                         uint64_t Address,
642581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
64265ffd83dbSDimitry Andric   if (RegNo == 15) {
64275ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
64285ffd83dbSDimitry Andric     return MCDisassembler::Success;
64295ffd83dbSDimitry Andric   }
64305ffd83dbSDimitry Andric 
64315ffd83dbSDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
64325ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64335ffd83dbSDimitry Andric 
64345ffd83dbSDimitry Andric   if (RegNo == 13)
64355ffd83dbSDimitry Andric     return MCDisassembler::SoftFail;
64365ffd83dbSDimitry Andric 
64375ffd83dbSDimitry Andric   return MCDisassembler::Success;
64385ffd83dbSDimitry Andric }
64395ffd83dbSDimitry Andric 
DecodeVSCCLRM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)64400b57cec5SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
644181ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
64420b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
64430b57cec5SDimitry Andric 
64440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMCC::AL));
64450b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
64460b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::VSCCLRMD) {
64470b57cec5SDimitry Andric     unsigned reglist = (fieldFromInstruction(Insn, 1, 7) << 1) |
64480b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 12, 4) << 8) |
64490b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 22, 1) << 12);
64500b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegListOperand(Inst, reglist, Address, Decoder))) {
64510b57cec5SDimitry Andric       return MCDisassembler::Fail;
64520b57cec5SDimitry Andric     }
64530b57cec5SDimitry Andric   } else {
64540b57cec5SDimitry Andric     unsigned reglist = fieldFromInstruction(Insn, 0, 8) |
64550b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 22, 1) << 8) |
64560b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 12, 4) << 9);
64570b57cec5SDimitry Andric     if (!Check(S, DecodeSPRRegListOperand(Inst, reglist, Address, Decoder))) {
64580b57cec5SDimitry Andric       return MCDisassembler::Fail;
64590b57cec5SDimitry Andric     }
64600b57cec5SDimitry Andric   }
64610b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
64620b57cec5SDimitry Andric 
64630b57cec5SDimitry Andric   return S;
64640b57cec5SDimitry Andric }
64650b57cec5SDimitry Andric 
DecodeMQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)64660b57cec5SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
64670b57cec5SDimitry Andric                                             uint64_t Address,
646881ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
64690b57cec5SDimitry Andric   if (RegNo > 7)
64700b57cec5SDimitry Andric     return MCDisassembler::Fail;
64710b57cec5SDimitry Andric 
64720b57cec5SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
64730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64740b57cec5SDimitry Andric   return MCDisassembler::Success;
64750b57cec5SDimitry Andric }
64760b57cec5SDimitry Andric 
64770b57cec5SDimitry Andric static const uint16_t QQPRDecoderTable[] = {
64780b57cec5SDimitry Andric      ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
64790b57cec5SDimitry Andric      ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
64800b57cec5SDimitry Andric };
64810b57cec5SDimitry Andric 
DecodeMQQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6482349cc55cSDimitry Andric static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
64830b57cec5SDimitry Andric                                              uint64_t Address,
648481ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
64850b57cec5SDimitry Andric   if (RegNo > 6)
64860b57cec5SDimitry Andric     return MCDisassembler::Fail;
64870b57cec5SDimitry Andric 
64880b57cec5SDimitry Andric   unsigned Register = QQPRDecoderTable[RegNo];
64890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64900b57cec5SDimitry Andric   return MCDisassembler::Success;
64910b57cec5SDimitry Andric }
64920b57cec5SDimitry Andric 
64930b57cec5SDimitry Andric static const uint16_t QQQQPRDecoderTable[] = {
64940b57cec5SDimitry Andric      ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
64950b57cec5SDimitry Andric      ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
64960b57cec5SDimitry Andric };
64970b57cec5SDimitry Andric 
DecodeMQQQQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6498349cc55cSDimitry Andric static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
64990b57cec5SDimitry Andric                                                uint64_t Address,
650081ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
65010b57cec5SDimitry Andric   if (RegNo > 4)
65020b57cec5SDimitry Andric     return MCDisassembler::Fail;
65030b57cec5SDimitry Andric 
65040b57cec5SDimitry Andric   unsigned Register = QQQQPRDecoderTable[RegNo];
65050b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
65060b57cec5SDimitry Andric   return MCDisassembler::Success;
65070b57cec5SDimitry Andric }
65080b57cec5SDimitry Andric 
DecodeVPTMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)65090b57cec5SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
65100b57cec5SDimitry Andric                                          uint64_t Address,
651181ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
65120b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
65130b57cec5SDimitry Andric 
65140b57cec5SDimitry Andric   // Parse VPT mask and encode it in the MCInst as an immediate with the same
65150b57cec5SDimitry Andric   // format as the it_mask.  That is, from the second 'e|t' encode 'e' as 1 and
65160b57cec5SDimitry Andric   // 't' as 0 and finish with a 1.
65170b57cec5SDimitry Andric   unsigned Imm = 0;
65180b57cec5SDimitry Andric   // We always start with a 't'.
65190b57cec5SDimitry Andric   unsigned CurBit = 0;
65200b57cec5SDimitry Andric   for (int i = 3; i >= 0; --i) {
65210b57cec5SDimitry Andric     // If the bit we are looking at is not the same as last one, invert the
65220b57cec5SDimitry Andric     // CurBit, if it is the same leave it as is.
65230b57cec5SDimitry Andric     CurBit ^= (Val >> i) & 1U;
65240b57cec5SDimitry Andric 
65250b57cec5SDimitry Andric     // Encode the CurBit at the right place in the immediate.
65260b57cec5SDimitry Andric     Imm |= (CurBit << i);
65270b57cec5SDimitry Andric 
65280b57cec5SDimitry Andric     // If we are done, finish the encoding with a 1.
65290b57cec5SDimitry Andric     if ((Val & ~(~0U << i)) == 0) {
65300b57cec5SDimitry Andric       Imm |= 1U << i;
65310b57cec5SDimitry Andric       break;
65320b57cec5SDimitry Andric     }
65330b57cec5SDimitry Andric   }
65340b57cec5SDimitry Andric 
65350b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
65360b57cec5SDimitry Andric 
65370b57cec5SDimitry Andric   return S;
65380b57cec5SDimitry Andric }
65390b57cec5SDimitry Andric 
DecodeVpredROperand(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)65400b57cec5SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
654181ad6265SDimitry Andric                                         uint64_t Address,
654281ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
65430b57cec5SDimitry Andric   // The vpred_r operand type includes an MQPR register field derived
65440b57cec5SDimitry Andric   // from the encoding. But we don't actually want to add an operand
65450b57cec5SDimitry Andric   // to the MCInst at this stage, because AddThumbPredicate will do it
65460b57cec5SDimitry Andric   // later, and will infer the register number from the TIED_TO
65470b57cec5SDimitry Andric   // constraint. So this is a deliberately empty decoder method that
65480b57cec5SDimitry Andric   // will inhibit the auto-generated disassembly code from adding an
65490b57cec5SDimitry Andric   // operand at all.
65500b57cec5SDimitry Andric   return MCDisassembler::Success;
65510b57cec5SDimitry Andric }
65520b57cec5SDimitry Andric 
6553bdd1243dSDimitry Andric [[maybe_unused]] static DecodeStatus
DecodeVpredNOperand(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6554bdd1243dSDimitry Andric DecodeVpredNOperand(MCInst &Inst, unsigned RegNo, uint64_t Address,
6555bdd1243dSDimitry Andric                     const MCDisassembler *Decoder) {
6556bdd1243dSDimitry Andric   // Similar to above, we want to ensure that no operands are added for the
6557bdd1243dSDimitry Andric   // vpred operands. (This is marked "maybe_unused" for the moment; because
6558bdd1243dSDimitry Andric   // DecoderEmitter currently (wrongly) omits operands with no instruction bits,
6559bdd1243dSDimitry Andric   // the decoder doesn't actually call it yet. That will be addressed in a
6560bdd1243dSDimitry Andric   // future change.)
6561bdd1243dSDimitry Andric   return MCDisassembler::Success;
6562bdd1243dSDimitry Andric }
6563bdd1243dSDimitry Andric 
656481ad6265SDimitry Andric static DecodeStatus
DecodeRestrictedIPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)656581ad6265SDimitry Andric DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
656681ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
65670b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE));
65680b57cec5SDimitry Andric   return MCDisassembler::Success;
65690b57cec5SDimitry Andric }
65700b57cec5SDimitry Andric 
657181ad6265SDimitry Andric static DecodeStatus
DecodeRestrictedSPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)657281ad6265SDimitry Andric DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
657381ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
65740b57cec5SDimitry Andric   unsigned Code;
65750b57cec5SDimitry Andric   switch (Val & 0x3) {
65760b57cec5SDimitry Andric   case 0:
65770b57cec5SDimitry Andric     Code = ARMCC::GE;
65780b57cec5SDimitry Andric     break;
65790b57cec5SDimitry Andric   case 1:
65800b57cec5SDimitry Andric     Code = ARMCC::LT;
65810b57cec5SDimitry Andric     break;
65820b57cec5SDimitry Andric   case 2:
65830b57cec5SDimitry Andric     Code = ARMCC::GT;
65840b57cec5SDimitry Andric     break;
65850b57cec5SDimitry Andric   case 3:
65860b57cec5SDimitry Andric     Code = ARMCC::LE;
65870b57cec5SDimitry Andric     break;
65880b57cec5SDimitry Andric   }
65890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Code));
65900b57cec5SDimitry Andric   return MCDisassembler::Success;
65910b57cec5SDimitry Andric }
65920b57cec5SDimitry Andric 
659381ad6265SDimitry Andric static DecodeStatus
DecodeRestrictedUPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)659481ad6265SDimitry Andric DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
659581ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
65960b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI));
65970b57cec5SDimitry Andric   return MCDisassembler::Success;
65980b57cec5SDimitry Andric }
65990b57cec5SDimitry Andric 
660081ad6265SDimitry Andric static DecodeStatus
DecodeRestrictedFPPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)660181ad6265SDimitry Andric DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
660281ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
66030b57cec5SDimitry Andric   unsigned Code;
66040b57cec5SDimitry Andric   switch (Val) {
66050b57cec5SDimitry Andric   default:
66060b57cec5SDimitry Andric     return MCDisassembler::Fail;
66070b57cec5SDimitry Andric   case 0:
66080b57cec5SDimitry Andric     Code = ARMCC::EQ;
66090b57cec5SDimitry Andric     break;
66100b57cec5SDimitry Andric   case 1:
66110b57cec5SDimitry Andric     Code = ARMCC::NE;
66120b57cec5SDimitry Andric     break;
66130b57cec5SDimitry Andric   case 4:
66140b57cec5SDimitry Andric     Code = ARMCC::GE;
66150b57cec5SDimitry Andric     break;
66160b57cec5SDimitry Andric   case 5:
66170b57cec5SDimitry Andric     Code = ARMCC::LT;
66180b57cec5SDimitry Andric     break;
66190b57cec5SDimitry Andric   case 6:
66200b57cec5SDimitry Andric     Code = ARMCC::GT;
66210b57cec5SDimitry Andric     break;
66220b57cec5SDimitry Andric   case 7:
66230b57cec5SDimitry Andric     Code = ARMCC::LE;
66240b57cec5SDimitry Andric     break;
66250b57cec5SDimitry Andric   }
66260b57cec5SDimitry Andric 
66270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Code));
66280b57cec5SDimitry Andric   return MCDisassembler::Success;
66290b57cec5SDimitry Andric }
66300b57cec5SDimitry Andric 
DecodeVCVTImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)66310b57cec5SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Val,
663281ad6265SDimitry Andric                                          uint64_t Address,
663381ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
66340b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
66350b57cec5SDimitry Andric 
66360b57cec5SDimitry Andric   unsigned DecodedVal = 64 - Val;
66370b57cec5SDimitry Andric 
66380b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
66390b57cec5SDimitry Andric   case ARM::MVE_VCVTf16s16_fix:
66400b57cec5SDimitry Andric   case ARM::MVE_VCVTs16f16_fix:
66410b57cec5SDimitry Andric   case ARM::MVE_VCVTf16u16_fix:
66420b57cec5SDimitry Andric   case ARM::MVE_VCVTu16f16_fix:
66430b57cec5SDimitry Andric     if (DecodedVal > 16)
66440b57cec5SDimitry Andric       return MCDisassembler::Fail;
66450b57cec5SDimitry Andric     break;
66460b57cec5SDimitry Andric   case ARM::MVE_VCVTf32s32_fix:
66470b57cec5SDimitry Andric   case ARM::MVE_VCVTs32f32_fix:
66480b57cec5SDimitry Andric   case ARM::MVE_VCVTf32u32_fix:
66490b57cec5SDimitry Andric   case ARM::MVE_VCVTu32f32_fix:
66500b57cec5SDimitry Andric     if (DecodedVal > 32)
66510b57cec5SDimitry Andric       return MCDisassembler::Fail;
66520b57cec5SDimitry Andric     break;
66530b57cec5SDimitry Andric   }
66540b57cec5SDimitry Andric 
66550b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
66560b57cec5SDimitry Andric 
66570b57cec5SDimitry Andric   return S;
66580b57cec5SDimitry Andric }
66590b57cec5SDimitry Andric 
FixedRegForVSTRVLDR_SYSREG(unsigned Opcode)66600b57cec5SDimitry Andric static unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) {
66610b57cec5SDimitry Andric   switch (Opcode) {
66620b57cec5SDimitry Andric   case ARM::VSTR_P0_off:
66630b57cec5SDimitry Andric   case ARM::VSTR_P0_pre:
66640b57cec5SDimitry Andric   case ARM::VSTR_P0_post:
66650b57cec5SDimitry Andric   case ARM::VLDR_P0_off:
66660b57cec5SDimitry Andric   case ARM::VLDR_P0_pre:
66670b57cec5SDimitry Andric   case ARM::VLDR_P0_post:
66680b57cec5SDimitry Andric     return ARM::P0;
66690b57cec5SDimitry Andric   default:
66700b57cec5SDimitry Andric     return 0;
66710b57cec5SDimitry Andric   }
66720b57cec5SDimitry Andric }
66730b57cec5SDimitry Andric 
66740b57cec5SDimitry Andric template <bool Writeback>
DecodeVSTRVLDR_SYSREG(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)66750b57cec5SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val,
66760b57cec5SDimitry Andric                                           uint64_t Address,
667781ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
66780b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
66790b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_pre:
66800b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_pre:
66810b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_pre:
66820b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_pre:
66830b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_off:
66840b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_off:
66850b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_off:
66860b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_off:
66870b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_post:
66880b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_post:
66890b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_post:
66900b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_post:
66910b57cec5SDimitry Andric     const FeatureBitset &featureBits =
66920b57cec5SDimitry Andric         ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
66930b57cec5SDimitry Andric 
66940b57cec5SDimitry Andric     if (!featureBits[ARM::HasMVEIntegerOps] && !featureBits[ARM::FeatureVFP2])
66950b57cec5SDimitry Andric       return MCDisassembler::Fail;
66960b57cec5SDimitry Andric   }
66970b57cec5SDimitry Andric 
66980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
66990b57cec5SDimitry Andric   if (unsigned Sysreg = FixedRegForVSTRVLDR_SYSREG(Inst.getOpcode()))
67000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Sysreg));
67010b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
67020b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Val, 0, 7) |
67030b57cec5SDimitry Andric                   (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
67040b57cec5SDimitry Andric 
67050b57cec5SDimitry Andric   if (Writeback) {
67060b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
67070b57cec5SDimitry Andric       return MCDisassembler::Fail;
67080b57cec5SDimitry Andric   }
67090b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm7s4(Inst, addr, Address, Decoder)))
67100b57cec5SDimitry Andric     return MCDisassembler::Fail;
67110b57cec5SDimitry Andric 
67120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMCC::AL));
67130b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
67140b57cec5SDimitry Andric 
67150b57cec5SDimitry Andric   return S;
67160b57cec5SDimitry Andric }
67170b57cec5SDimitry Andric 
671881ad6265SDimitry Andric static inline DecodeStatus
DecodeMVE_MEM_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder,unsigned Rn,OperandDecoder RnDecoder,OperandDecoder AddrDecoder)671981ad6265SDimitry Andric DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
672081ad6265SDimitry Andric                   const MCDisassembler *Decoder, unsigned Rn,
672181ad6265SDimitry Andric                   OperandDecoder RnDecoder, OperandDecoder AddrDecoder) {
67220b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67230b57cec5SDimitry Andric 
67240b57cec5SDimitry Andric   unsigned Qd = fieldFromInstruction(Val, 13, 3);
67250b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Val, 0, 7) |
67260b57cec5SDimitry Andric                   (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
67270b57cec5SDimitry Andric 
67280b57cec5SDimitry Andric   if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder)))
67290b57cec5SDimitry Andric     return MCDisassembler::Fail;
67300b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
67310b57cec5SDimitry Andric     return MCDisassembler::Fail;
67320b57cec5SDimitry Andric   if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
67330b57cec5SDimitry Andric     return MCDisassembler::Fail;
67340b57cec5SDimitry Andric 
67350b57cec5SDimitry Andric   return S;
67360b57cec5SDimitry Andric }
67370b57cec5SDimitry Andric 
67380b57cec5SDimitry Andric template <int shift>
DecodeMVE_MEM_1_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)67390b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
674081ad6265SDimitry Andric                                         uint64_t Address,
674181ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
67420b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
67430b57cec5SDimitry Andric                            fieldFromInstruction(Val, 16, 3),
67440b57cec5SDimitry Andric                            DecodetGPRRegisterClass,
67450b57cec5SDimitry Andric                            DecodeTAddrModeImm7<shift>);
67460b57cec5SDimitry Andric }
67470b57cec5SDimitry Andric 
67480b57cec5SDimitry Andric template <int shift>
DecodeMVE_MEM_2_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)67490b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
675081ad6265SDimitry Andric                                         uint64_t Address,
675181ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
67520b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
67530b57cec5SDimitry Andric                            fieldFromInstruction(Val, 16, 4),
67540b57cec5SDimitry Andric                            DecoderGPRRegisterClass,
67550b57cec5SDimitry Andric                            DecodeT2AddrModeImm7<shift,1>);
67560b57cec5SDimitry Andric }
67570b57cec5SDimitry Andric 
67580b57cec5SDimitry Andric template <int shift>
DecodeMVE_MEM_3_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)67590b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
676081ad6265SDimitry Andric                                         uint64_t Address,
676181ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
67620b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
67630b57cec5SDimitry Andric                            fieldFromInstruction(Val, 17, 3),
67640b57cec5SDimitry Andric                            DecodeMQPRRegisterClass,
67650b57cec5SDimitry Andric                            DecodeMveAddrModeQ<shift>);
67660b57cec5SDimitry Andric }
67670b57cec5SDimitry Andric 
67680b57cec5SDimitry Andric template <unsigned MinLog, unsigned MaxLog>
DecodePowerTwoOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)67690b57cec5SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
67700b57cec5SDimitry Andric                                           uint64_t Address,
677181ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
67720b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67730b57cec5SDimitry Andric 
67740b57cec5SDimitry Andric   if (Val < MinLog || Val > MaxLog)
67750b57cec5SDimitry Andric     return MCDisassembler::Fail;
67760b57cec5SDimitry Andric 
67770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(1LL << Val));
67780b57cec5SDimitry Andric   return S;
67790b57cec5SDimitry Andric }
67800b57cec5SDimitry Andric 
67810b57cec5SDimitry Andric template <unsigned start>
678281ad6265SDimitry Andric static DecodeStatus
DecodeMVEPairVectorIndexOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)678381ad6265SDimitry Andric DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, uint64_t Address,
678481ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
67850b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67860b57cec5SDimitry Andric 
67870b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(start + Val));
67880b57cec5SDimitry Andric 
67890b57cec5SDimitry Andric   return S;
67900b57cec5SDimitry Andric }
67910b57cec5SDimitry Andric 
DecodeMVEVMOVQtoDReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)67920b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
679381ad6265SDimitry Andric                                          uint64_t Address,
679481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
67950b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67960b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
67970b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
67980b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
67990b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
68000b57cec5SDimitry Andric   unsigned index = fieldFromInstruction(Insn, 4, 1);
68010b57cec5SDimitry Andric 
68020b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
68030b57cec5SDimitry Andric     return MCDisassembler::Fail;
68040b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
68050b57cec5SDimitry Andric     return MCDisassembler::Fail;
68060b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
68070b57cec5SDimitry Andric     return MCDisassembler::Fail;
68080b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
68090b57cec5SDimitry Andric     return MCDisassembler::Fail;
68100b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
68110b57cec5SDimitry Andric     return MCDisassembler::Fail;
68120b57cec5SDimitry Andric 
68130b57cec5SDimitry Andric   return S;
68140b57cec5SDimitry Andric }
68150b57cec5SDimitry Andric 
DecodeMVEVMOVDRegtoQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)68160b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
681781ad6265SDimitry Andric                                          uint64_t Address,
681881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
68190b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
68200b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
68210b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
68220b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
68230b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
68240b57cec5SDimitry Andric   unsigned index = fieldFromInstruction(Insn, 4, 1);
68250b57cec5SDimitry Andric 
68260b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
68270b57cec5SDimitry Andric     return MCDisassembler::Fail;
68280b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
68290b57cec5SDimitry Andric     return MCDisassembler::Fail;
68300b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
68310b57cec5SDimitry Andric     return MCDisassembler::Fail;
68320b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
68330b57cec5SDimitry Andric     return MCDisassembler::Fail;
68340b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
68350b57cec5SDimitry Andric     return MCDisassembler::Fail;
68360b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
68370b57cec5SDimitry Andric     return MCDisassembler::Fail;
68380b57cec5SDimitry Andric 
68390b57cec5SDimitry Andric   return S;
68400b57cec5SDimitry Andric }
68410b57cec5SDimitry Andric 
684281ad6265SDimitry Andric static DecodeStatus
DecodeMVEOverlappingLongShift(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)684381ad6265SDimitry Andric DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, uint64_t Address,
684481ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
68450b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
68460b57cec5SDimitry Andric 
68470b57cec5SDimitry Andric   unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1;
68480b57cec5SDimitry Andric   unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1;
68490b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 12, 4);
68500b57cec5SDimitry Andric 
68510b57cec5SDimitry Andric   if (RdaHi == 14) {
68520b57cec5SDimitry Andric     // This value of RdaHi (really indicating pc, because RdaHi has to
68530b57cec5SDimitry Andric     // be an odd-numbered register, so the low bit will be set by the
68540b57cec5SDimitry Andric     // decode function below) indicates that we must decode as SQRSHR
68550b57cec5SDimitry Andric     // or UQRSHL, which both have a single Rda register field with all
68560b57cec5SDimitry Andric     // four bits.
68570b57cec5SDimitry Andric     unsigned Rda = fieldFromInstruction(Insn, 16, 4);
68580b57cec5SDimitry Andric 
68590b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
68600b57cec5SDimitry Andric       case ARM::MVE_ASRLr:
68610b57cec5SDimitry Andric       case ARM::MVE_SQRSHRL:
68620b57cec5SDimitry Andric         Inst.setOpcode(ARM::MVE_SQRSHR);
68630b57cec5SDimitry Andric         break;
68640b57cec5SDimitry Andric       case ARM::MVE_LSLLr:
68650b57cec5SDimitry Andric       case ARM::MVE_UQRSHLL:
68660b57cec5SDimitry Andric         Inst.setOpcode(ARM::MVE_UQRSHL);
68670b57cec5SDimitry Andric         break;
68680b57cec5SDimitry Andric       default:
68690b57cec5SDimitry Andric         llvm_unreachable("Unexpected starting opcode!");
68700b57cec5SDimitry Andric     }
68710b57cec5SDimitry Andric 
68720b57cec5SDimitry Andric     // Rda as output parameter
68730b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
68740b57cec5SDimitry Andric       return MCDisassembler::Fail;
68750b57cec5SDimitry Andric 
68760b57cec5SDimitry Andric     // Rda again as input parameter
68770b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
68780b57cec5SDimitry Andric       return MCDisassembler::Fail;
68790b57cec5SDimitry Andric 
68800b57cec5SDimitry Andric     // Rm, the amount to shift by
68810b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
68820b57cec5SDimitry Andric       return MCDisassembler::Fail;
68830b57cec5SDimitry Andric 
68848bcb0991SDimitry Andric     if (fieldFromInstruction (Insn, 6, 3) != 4)
68858bcb0991SDimitry Andric       return MCDisassembler::SoftFail;
68868bcb0991SDimitry Andric 
68878bcb0991SDimitry Andric     if (Rda == Rm)
68888bcb0991SDimitry Andric       return MCDisassembler::SoftFail;
68898bcb0991SDimitry Andric 
68900b57cec5SDimitry Andric     return S;
68910b57cec5SDimitry Andric   }
68920b57cec5SDimitry Andric 
68930b57cec5SDimitry Andric   // Otherwise, we decode as whichever opcode our caller has already
68940b57cec5SDimitry Andric   // put into Inst. Those all look the same:
68950b57cec5SDimitry Andric 
68960b57cec5SDimitry Andric   // RdaLo,RdaHi as output parameters
68970b57cec5SDimitry Andric   if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
68980b57cec5SDimitry Andric     return MCDisassembler::Fail;
68990b57cec5SDimitry Andric   if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
69000b57cec5SDimitry Andric     return MCDisassembler::Fail;
69010b57cec5SDimitry Andric 
69020b57cec5SDimitry Andric   // RdaLo,RdaHi again as input parameters
69030b57cec5SDimitry Andric   if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
69040b57cec5SDimitry Andric     return MCDisassembler::Fail;
69050b57cec5SDimitry Andric   if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
69060b57cec5SDimitry Andric     return MCDisassembler::Fail;
69070b57cec5SDimitry Andric 
69080b57cec5SDimitry Andric   // Rm, the amount to shift by
69090b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
69100b57cec5SDimitry Andric     return MCDisassembler::Fail;
69110b57cec5SDimitry Andric 
69128bcb0991SDimitry Andric   if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
69138bcb0991SDimitry Andric       Inst.getOpcode() == ARM::MVE_UQRSHLL) {
69148bcb0991SDimitry Andric     unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
69158bcb0991SDimitry Andric     // Saturate, the bit position for saturation
69168bcb0991SDimitry Andric     Inst.addOperand(MCOperand::createImm(Saturate));
69178bcb0991SDimitry Andric   }
69188bcb0991SDimitry Andric 
69190b57cec5SDimitry Andric   return S;
69200b57cec5SDimitry Andric }
69210b57cec5SDimitry Andric 
DecodeMVEVCVTt1fp(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)692281ad6265SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
692381ad6265SDimitry Andric                                       uint64_t Address,
692481ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
69250b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69260b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
69270b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
69280b57cec5SDimitry Andric   unsigned Qm = ((fieldFromInstruction(Insn, 5, 1) << 3) |
69290b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 1, 3));
69300b57cec5SDimitry Andric   unsigned imm6 = fieldFromInstruction(Insn, 16, 6);
69310b57cec5SDimitry Andric 
69320b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
69330b57cec5SDimitry Andric     return MCDisassembler::Fail;
69340b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
69350b57cec5SDimitry Andric     return MCDisassembler::Fail;
69360b57cec5SDimitry Andric   if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
69370b57cec5SDimitry Andric     return MCDisassembler::Fail;
69380b57cec5SDimitry Andric 
69390b57cec5SDimitry Andric   return S;
69400b57cec5SDimitry Andric }
69410b57cec5SDimitry Andric 
69420b57cec5SDimitry Andric template <bool scalar, OperandDecoder predicate_decoder>
DecodeMVEVCMP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)69430b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
694481ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
69450b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69470b57cec5SDimitry Andric   unsigned Qn = fieldFromInstruction(Insn, 17, 3);
69480b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
69490b57cec5SDimitry Andric     return MCDisassembler::Fail;
69500b57cec5SDimitry Andric 
69510b57cec5SDimitry Andric   unsigned fc;
69520b57cec5SDimitry Andric 
69530b57cec5SDimitry Andric   if (scalar) {
69540b57cec5SDimitry Andric     fc = fieldFromInstruction(Insn, 12, 1) << 2 |
69550b57cec5SDimitry Andric          fieldFromInstruction(Insn, 7, 1) |
69560b57cec5SDimitry Andric          fieldFromInstruction(Insn, 5, 1) << 1;
69570b57cec5SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 0, 4);
69580b57cec5SDimitry Andric     if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder)))
69590b57cec5SDimitry Andric       return MCDisassembler::Fail;
69600b57cec5SDimitry Andric   } else {
69610b57cec5SDimitry Andric     fc = fieldFromInstruction(Insn, 12, 1) << 2 |
69620b57cec5SDimitry Andric          fieldFromInstruction(Insn, 7, 1) |
69630b57cec5SDimitry Andric          fieldFromInstruction(Insn, 0, 1) << 1;
69640b57cec5SDimitry Andric     unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 |
69650b57cec5SDimitry Andric                   fieldFromInstruction(Insn, 1, 3);
69660b57cec5SDimitry Andric     if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
69670b57cec5SDimitry Andric       return MCDisassembler::Fail;
69680b57cec5SDimitry Andric   }
69690b57cec5SDimitry Andric 
69700b57cec5SDimitry Andric   if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
69710b57cec5SDimitry Andric     return MCDisassembler::Fail;
69720b57cec5SDimitry Andric 
69730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
69740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
69750b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
69760b57cec5SDimitry Andric 
69770b57cec5SDimitry Andric   return S;
69780b57cec5SDimitry Andric }
69790b57cec5SDimitry Andric 
DecodeMveVCTP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)69800b57cec5SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
698181ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
69820b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69830b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69840b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
69850b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
69860b57cec5SDimitry Andric     return MCDisassembler::Fail;
69870b57cec5SDimitry Andric   return S;
69880b57cec5SDimitry Andric }
69898bcb0991SDimitry Andric 
DecodeMVEVPNOT(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)699081ad6265SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
699181ad6265SDimitry Andric                                    uint64_t Address,
699281ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
69938bcb0991SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69948bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69958bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69968bcb0991SDimitry Andric   return S;
69978bcb0991SDimitry Andric }
6998480093f4SDimitry Andric 
DecodeT2AddSubSPImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6999480093f4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
700081ad6265SDimitry Andric                                         uint64_t Address,
700181ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
7002480093f4SDimitry Andric   const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
7003480093f4SDimitry Andric   const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
7004480093f4SDimitry Andric   const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 |
7005480093f4SDimitry Andric                          fieldFromInstruction(Insn, 12, 3) << 8 |
7006480093f4SDimitry Andric                          fieldFromInstruction(Insn, 0, 8);
7007480093f4SDimitry Andric   const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1);
7008480093f4SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
7009480093f4SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
7010480093f4SDimitry Andric   unsigned S = fieldFromInstruction(Insn, 20, 1);
7011480093f4SDimitry Andric   if (sign1 != sign2)
7012480093f4SDimitry Andric     return MCDisassembler::Fail;
7013480093f4SDimitry Andric 
7014480093f4SDimitry Andric   // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm)
7015480093f4SDimitry Andric   DecodeStatus DS = MCDisassembler::Success;
7016480093f4SDimitry Andric   if ((!Check(DS,
7017480093f4SDimitry Andric               DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst
7018480093f4SDimitry Andric       (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder))))
7019480093f4SDimitry Andric     return MCDisassembler::Fail;
7020480093f4SDimitry Andric   if (TypeT3) {
7021480093f4SDimitry Andric     Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
7022480093f4SDimitry Andric     Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
7023480093f4SDimitry Andric   } else {
7024480093f4SDimitry Andric     Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
7025480093f4SDimitry Andric     if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
7026480093f4SDimitry Andric       return MCDisassembler::Fail;
7027480093f4SDimitry Andric     if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
7028480093f4SDimitry Andric       return MCDisassembler::Fail;
7029fe6060f1SDimitry Andric   }
7030480093f4SDimitry Andric 
7031480093f4SDimitry Andric   return DS;
7032480093f4SDimitry Andric }
7033