xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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"
2706c3fb27SDimitry 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
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
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
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
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'.
720b57cec5SDimitry Andric       void setITState(char Firstcond, char Mask) {
730b57cec5SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
7406c3fb27SDimitry 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:
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 
990b57cec5SDimitry Andric       void advanceVPTState() {
1000b57cec5SDimitry Andric         VPTStates.pop_back();
1010b57cec5SDimitry Andric       }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric       bool instrInVPTBlock() {
1040b57cec5SDimitry Andric         return !VPTStates.empty();
1050b57cec5SDimitry Andric       }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric       bool instrLastInVPTBlock() {
1080b57cec5SDimitry Andric         return VPTStates.size() == 1;
1090b57cec5SDimitry Andric       }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric       void setVPTState(char Mask) {
1120b57cec5SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
11306c3fb27SDimitry 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 
135bdd1243dSDimitry Andric   ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
136bdd1243dSDimitry Andric                   const MCInstrInfo *MCII)
137bdd1243dSDimitry Andric       : MCDisassembler(STI, Ctx), MCII(MCII) {
13806c3fb27SDimitry Andric         InstructionEndianness = STI.hasFeature(ARM::ModeBigEndianInstructions)
1395f757f3fSDimitry Andric                                     ? llvm::endianness::big
1405f757f3fSDimitry 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 
1695f757f3fSDimitry 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);
703*0fca6ea1SDimitry Andric static DecodeStatus DecodeLazyLoadStoreMul(MCInst &Inst, unsigned Insn,
704*0fca6ea1SDimitry Andric                                            uint64_t Address,
705*0fca6ea1SDimitry Andric                                            const MCDisassembler *Decoder);
706480093f4SDimitry Andric 
7070b57cec5SDimitry Andric #include "ARMGenDisassemblerTables.inc"
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric static MCDisassembler *createARMDisassembler(const Target &T,
7100b57cec5SDimitry Andric                                              const MCSubtargetInfo &STI,
7110b57cec5SDimitry Andric                                              MCContext &Ctx) {
712bdd1243dSDimitry Andric   return new ARMDisassembler(STI, Ctx, T.createMCInstrInfo());
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric // Post-decoding checks
7160b57cec5SDimitry Andric static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
717480093f4SDimitry Andric                                             uint64_t Address, raw_ostream &CS,
7180b57cec5SDimitry Andric                                             uint32_t Insn,
7190b57cec5SDimitry Andric                                             DecodeStatus Result) {
7200b57cec5SDimitry Andric   switch (MI.getOpcode()) {
7210b57cec5SDimitry Andric     case ARM::HVC: {
7220b57cec5SDimitry Andric       // HVC is undefined if condition = 0xf otherwise upredictable
7230b57cec5SDimitry Andric       // if condition != 0xe
7240b57cec5SDimitry Andric       uint32_t Cond = (Insn >> 28) & 0xF;
7250b57cec5SDimitry Andric       if (Cond == 0xF)
7260b57cec5SDimitry Andric         return MCDisassembler::Fail;
7270b57cec5SDimitry Andric       if (Cond != 0xE)
7280b57cec5SDimitry Andric         return MCDisassembler::SoftFail;
7290b57cec5SDimitry Andric       return Result;
7300b57cec5SDimitry Andric     }
7310b57cec5SDimitry Andric     case ARM::t2ADDri:
7320b57cec5SDimitry Andric     case ARM::t2ADDri12:
7330b57cec5SDimitry Andric     case ARM::t2ADDrr:
7340b57cec5SDimitry Andric     case ARM::t2ADDrs:
7350b57cec5SDimitry Andric     case ARM::t2SUBri:
7360b57cec5SDimitry Andric     case ARM::t2SUBri12:
7370b57cec5SDimitry Andric     case ARM::t2SUBrr:
7380b57cec5SDimitry Andric     case ARM::t2SUBrs:
7390b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == ARM::SP &&
7400b57cec5SDimitry Andric           MI.getOperand(1).getReg() != ARM::SP)
7410b57cec5SDimitry Andric         return MCDisassembler::SoftFail;
7420b57cec5SDimitry Andric       return Result;
7430b57cec5SDimitry Andric     default: return Result;
7440b57cec5SDimitry Andric   }
7450b57cec5SDimitry Andric }
7460b57cec5SDimitry Andric 
747972a253aSDimitry Andric uint64_t ARMDisassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
748972a253aSDimitry Andric                                              uint64_t Address) const {
749972a253aSDimitry Andric   // In Arm state, instructions are always 4 bytes wide, so there's no
750972a253aSDimitry Andric   // point in skipping any smaller number of bytes if an instruction
751972a253aSDimitry Andric   // can't be decoded.
75206c3fb27SDimitry Andric   if (!STI.hasFeature(ARM::ModeThumb))
753972a253aSDimitry Andric     return 4;
754972a253aSDimitry Andric 
755972a253aSDimitry Andric   // In a Thumb instruction stream, a halfword is a standalone 2-byte
756972a253aSDimitry Andric   // instruction if and only if its value is less than 0xE800.
757972a253aSDimitry Andric   // Otherwise, it's the first halfword of a 4-byte instruction.
758972a253aSDimitry Andric   //
759972a253aSDimitry Andric   // So, if we can see the upcoming halfword, we can judge on that
760972a253aSDimitry Andric   // basis, and maybe skip a whole 4-byte instruction that we don't
761972a253aSDimitry Andric   // know how to decode, without accidentally trying to interpret its
762972a253aSDimitry Andric   // second half as something else.
763972a253aSDimitry Andric   //
764972a253aSDimitry Andric   // If we don't have the instruction data available, we just have to
765972a253aSDimitry Andric   // recommend skipping the minimum sensible distance, which is 2
766972a253aSDimitry Andric   // bytes.
767972a253aSDimitry Andric   if (Bytes.size() < 2)
768972a253aSDimitry Andric     return 2;
769972a253aSDimitry Andric 
770bdd1243dSDimitry Andric   uint16_t Insn16 = llvm::support::endian::read<uint16_t>(
771bdd1243dSDimitry Andric       Bytes.data(), InstructionEndianness);
772972a253aSDimitry Andric   return Insn16 < 0xE800 ? 2 : 4;
773972a253aSDimitry Andric }
774972a253aSDimitry Andric 
7750b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
7760b57cec5SDimitry Andric                                              ArrayRef<uint8_t> Bytes,
777480093f4SDimitry Andric                                              uint64_t Address,
7780b57cec5SDimitry Andric                                              raw_ostream &CS) const {
77906c3fb27SDimitry Andric   if (STI.hasFeature(ARM::ModeThumb))
780480093f4SDimitry Andric     return getThumbInstruction(MI, Size, Bytes, Address, CS);
781480093f4SDimitry Andric   return getARMInstruction(MI, Size, Bytes, Address, CS);
7820b57cec5SDimitry Andric }
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
7850b57cec5SDimitry Andric                                                 ArrayRef<uint8_t> Bytes,
7860b57cec5SDimitry Andric                                                 uint64_t Address,
7870b57cec5SDimitry Andric                                                 raw_ostream &CS) const {
7880b57cec5SDimitry Andric   CommentStream = &CS;
7890b57cec5SDimitry Andric 
79006c3fb27SDimitry Andric   assert(!STI.hasFeature(ARM::ModeThumb) &&
7910b57cec5SDimitry Andric          "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
7920b57cec5SDimitry Andric          "mode!");
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
7950b57cec5SDimitry Andric   if (Bytes.size() < 4) {
7960b57cec5SDimitry Andric     Size = 0;
7970b57cec5SDimitry Andric     return MCDisassembler::Fail;
7980b57cec5SDimitry Andric   }
7990b57cec5SDimitry Andric 
800bdd1243dSDimitry Andric   // Encoded as a 32-bit word in the stream.
801bdd1243dSDimitry Andric   uint32_t Insn = llvm::support::endian::read<uint32_t>(Bytes.data(),
802bdd1243dSDimitry Andric                                                         InstructionEndianness);
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   // Calling the auto-generated decoder function.
8050b57cec5SDimitry Andric   DecodeStatus Result =
8060b57cec5SDimitry Andric       decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
8070b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
8080b57cec5SDimitry Andric     Size = 4;
809480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
8100b57cec5SDimitry Andric   }
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric   struct DecodeTable {
8130b57cec5SDimitry Andric     const uint8_t *P;
8140b57cec5SDimitry Andric     bool DecodePred;
8150b57cec5SDimitry Andric   };
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric   const DecodeTable Tables[] = {
8180b57cec5SDimitry Andric       {DecoderTableVFP32, false},      {DecoderTableVFPV832, false},
8190b57cec5SDimitry Andric       {DecoderTableNEONData32, true},  {DecoderTableNEONLoadStore32, true},
8200b57cec5SDimitry Andric       {DecoderTableNEONDup32, true},   {DecoderTablev8NEON32, false},
8210b57cec5SDimitry Andric       {DecoderTablev8Crypto32, false},
8220b57cec5SDimitry Andric   };
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric   for (auto Table : Tables) {
8250b57cec5SDimitry Andric     Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
8260b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
8270b57cec5SDimitry Andric       Size = 4;
8280b57cec5SDimitry Andric       // Add a fake predicate operand, because we share these instruction
8290b57cec5SDimitry Andric       // definitions with Thumb2 where these instructions are predicable.
8300b57cec5SDimitry Andric       if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
8310b57cec5SDimitry Andric         return MCDisassembler::Fail;
8320b57cec5SDimitry Andric       return Result;
8330b57cec5SDimitry Andric     }
8340b57cec5SDimitry Andric   }
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   Result =
8370b57cec5SDimitry Andric       decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
8380b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
8390b57cec5SDimitry Andric     Size = 4;
840480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
8410b57cec5SDimitry Andric   }
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric   Size = 4;
8440b57cec5SDimitry Andric   return MCDisassembler::Fail;
8450b57cec5SDimitry Andric }
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
8480b57cec5SDimitry Andric /// immediate Value in the MCInst.  The immediate Value has had any PC
8490b57cec5SDimitry Andric /// adjustment made by the caller.  If the instruction is a branch instruction
8500b57cec5SDimitry Andric /// then isBranch is true, else false.  If the getOpInfo() function was set as
8510b57cec5SDimitry Andric /// part of the setupForSymbolicDisassembly() call then that function is called
8520b57cec5SDimitry Andric /// to get any symbolic information at the Address for this instruction.  If
8530b57cec5SDimitry Andric /// that returns non-zero then the symbolic information it returns is used to
8540b57cec5SDimitry Andric /// create an MCExpr and that is added as an operand to the MCInst.  If
8550b57cec5SDimitry Andric /// getOpInfo() returns zero and isBranch is true then a symbol look up for
8560b57cec5SDimitry Andric /// Value is done and if a symbol is found an MCExpr is created with that, else
8570b57cec5SDimitry Andric /// an MCExpr with Value is created.  This function returns true if it adds an
8580b57cec5SDimitry Andric /// operand to the MCInst and false otherwise.
8590b57cec5SDimitry Andric static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
8600b57cec5SDimitry Andric                                      bool isBranch, uint64_t InstSize,
86181ad6265SDimitry Andric                                      MCInst &MI,
86281ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
8630b57cec5SDimitry Andric   // FIXME: Does it make sense for value to be negative?
86481ad6265SDimitry Andric   return Decoder->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address,
86581ad6265SDimitry Andric                                            isBranch, /*Offset=*/0, /*OpSize=*/0,
86681ad6265SDimitry Andric                                            InstSize);
8670b57cec5SDimitry Andric }
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
8700b57cec5SDimitry Andric /// referenced by a load instruction with the base register that is the Pc.
8710b57cec5SDimitry Andric /// These can often be values in a literal pool near the Address of the
8720b57cec5SDimitry Andric /// instruction.  The Address of the instruction and its immediate Value are
8730b57cec5SDimitry Andric /// used as a possible literal pool entry.  The SymbolLookUp call back will
8740b57cec5SDimitry Andric /// return the name of a symbol referenced by the literal pool's entry if
8750b57cec5SDimitry Andric /// the referenced address is that of a symbol.  Or it will return a pointer to
8760b57cec5SDimitry Andric /// a literal 'C' string if the referenced address of the literal pool's entry
8770b57cec5SDimitry Andric /// is an address into a section with 'C' string literals.
8780b57cec5SDimitry Andric static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
87981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
8800b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
8810b57cec5SDimitry Andric   Dis->tryAddingPcLoadReferenceComment(Value, Address);
8820b57cec5SDimitry Andric }
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric // Thumb1 instructions don't have explicit S bits.  Rather, they
8850b57cec5SDimitry Andric // implicitly set CPSR.  Since it's not represented in the encoding, the
8860b57cec5SDimitry Andric // auto-generated decoder won't inject the CPSR operand.  We need to fix
8870b57cec5SDimitry Andric // that as a post-pass.
888bdd1243dSDimitry Andric void ARMDisassembler::AddThumb1SBit(MCInst &MI, bool InITBlock) const {
889bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
8900b57cec5SDimitry Andric   MCInst::iterator I = MI.begin();
891bdd1243dSDimitry Andric   for (unsigned i = 0; i < MCID.NumOperands; ++i, ++I) {
8920b57cec5SDimitry Andric     if (I == MI.end()) break;
893bdd1243dSDimitry Andric     if (MCID.operands()[i].isOptionalDef() &&
894bdd1243dSDimitry Andric         MCID.operands()[i].RegClass == ARM::CCRRegClassID) {
895bdd1243dSDimitry Andric       if (i > 0 && MCID.operands()[i - 1].isPredicate())
896bdd1243dSDimitry Andric         continue;
8970b57cec5SDimitry Andric       MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
8980b57cec5SDimitry Andric       return;
8990b57cec5SDimitry Andric     }
9000b57cec5SDimitry Andric   }
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric   MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
9030b57cec5SDimitry Andric }
9040b57cec5SDimitry Andric 
905bdd1243dSDimitry Andric bool ARMDisassembler::isVectorPredicable(const MCInst &MI) const {
906bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
907bdd1243dSDimitry Andric   for (unsigned i = 0; i < MCID.NumOperands; ++i) {
908bdd1243dSDimitry Andric     if (ARM::isVpred(MCID.operands()[i].OperandType))
9090b57cec5SDimitry Andric       return true;
9100b57cec5SDimitry Andric   }
9110b57cec5SDimitry Andric   return false;
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric // Most Thumb instructions don't have explicit predicates in the
9150b57cec5SDimitry Andric // encoding, but rather get their predicates from IT context.  We need
9160b57cec5SDimitry Andric // to fix up the predicate operands using this context information as a
9170b57cec5SDimitry Andric // post-pass.
9180b57cec5SDimitry Andric MCDisassembler::DecodeStatus
9190b57cec5SDimitry Andric ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
9200b57cec5SDimitry Andric   MCDisassembler::DecodeStatus S = Success;
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric   // A few instructions actually have predicates encoded in them.  Don't
9250b57cec5SDimitry Andric   // try to overwrite it if we're seeing one of those.
9260b57cec5SDimitry Andric   switch (MI.getOpcode()) {
9270b57cec5SDimitry Andric     case ARM::tBcc:
9280b57cec5SDimitry Andric     case ARM::t2Bcc:
9290b57cec5SDimitry Andric     case ARM::tCBZ:
9300b57cec5SDimitry Andric     case ARM::tCBNZ:
9310b57cec5SDimitry Andric     case ARM::tCPS:
9320b57cec5SDimitry Andric     case ARM::t2CPS3p:
9330b57cec5SDimitry Andric     case ARM::t2CPS2p:
9340b57cec5SDimitry Andric     case ARM::t2CPS1p:
9350b57cec5SDimitry Andric     case ARM::t2CSEL:
9360b57cec5SDimitry Andric     case ARM::t2CSINC:
9370b57cec5SDimitry Andric     case ARM::t2CSINV:
9380b57cec5SDimitry Andric     case ARM::t2CSNEG:
9390b57cec5SDimitry Andric     case ARM::tMOVSr:
9400b57cec5SDimitry Andric     case ARM::tSETEND:
9410b57cec5SDimitry Andric       // Some instructions (mostly conditional branches) are not
9420b57cec5SDimitry Andric       // allowed in IT blocks.
9430b57cec5SDimitry Andric       if (ITBlock.instrInITBlock())
9440b57cec5SDimitry Andric         S = SoftFail;
9450b57cec5SDimitry Andric       else
9460b57cec5SDimitry Andric         return Success;
9470b57cec5SDimitry Andric       break;
9480b57cec5SDimitry Andric     case ARM::t2HINT:
9490b57cec5SDimitry Andric       if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
9500b57cec5SDimitry Andric         S = SoftFail;
9510b57cec5SDimitry Andric       break;
9520b57cec5SDimitry Andric     case ARM::tB:
9530b57cec5SDimitry Andric     case ARM::t2B:
9540b57cec5SDimitry Andric     case ARM::t2TBB:
9550b57cec5SDimitry Andric     case ARM::t2TBH:
9560b57cec5SDimitry Andric       // Some instructions (mostly unconditional branches) can
9570b57cec5SDimitry Andric       // only appears at the end of, or outside of, an IT.
9580b57cec5SDimitry Andric       if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
9590b57cec5SDimitry Andric         S = SoftFail;
9600b57cec5SDimitry Andric       break;
9610b57cec5SDimitry Andric     default:
9620b57cec5SDimitry Andric       break;
9630b57cec5SDimitry Andric   }
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric   // Warn on non-VPT predicable instruction in a VPT block and a VPT
9660b57cec5SDimitry Andric   // predicable instruction in an IT block
967bdd1243dSDimitry Andric   if ((!isVectorPredicable(MI) && VPTBlock.instrInVPTBlock()) ||
968bdd1243dSDimitry Andric       (isVectorPredicable(MI) && ITBlock.instrInITBlock()))
9690b57cec5SDimitry Andric     S = SoftFail;
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // If we're in an IT/VPT block, base the predicate on that.  Otherwise,
9720b57cec5SDimitry Andric   // assume a predicate of AL.
9730b57cec5SDimitry Andric   unsigned CC = ARMCC::AL;
9740b57cec5SDimitry Andric   unsigned VCC = ARMVCC::None;
9750b57cec5SDimitry Andric   if (ITBlock.instrInITBlock()) {
9760b57cec5SDimitry Andric     CC = ITBlock.getITCC();
9770b57cec5SDimitry Andric     ITBlock.advanceITState();
9780b57cec5SDimitry Andric   } else if (VPTBlock.instrInVPTBlock()) {
9790b57cec5SDimitry Andric     VCC = VPTBlock.getVPTPred();
9800b57cec5SDimitry Andric     VPTBlock.advanceVPTState();
9810b57cec5SDimitry Andric   }
9820b57cec5SDimitry Andric 
983bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   MCInst::iterator CCI = MI.begin();
986bdd1243dSDimitry Andric   for (unsigned i = 0; i < MCID.NumOperands; ++i, ++CCI) {
987bdd1243dSDimitry Andric     if (MCID.operands()[i].isPredicate() || CCI == MI.end())
988bdd1243dSDimitry Andric       break;
9890b57cec5SDimitry Andric   }
9900b57cec5SDimitry Andric 
991bdd1243dSDimitry Andric   if (MCID.isPredicable()) {
9920b57cec5SDimitry Andric     CCI = MI.insert(CCI, MCOperand::createImm(CC));
9930b57cec5SDimitry Andric     ++CCI;
9940b57cec5SDimitry Andric     if (CC == ARMCC::AL)
9950b57cec5SDimitry Andric       MI.insert(CCI, MCOperand::createReg(0));
9960b57cec5SDimitry Andric     else
9970b57cec5SDimitry Andric       MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
9980b57cec5SDimitry Andric   } else if (CC != ARMCC::AL) {
9990b57cec5SDimitry Andric     Check(S, SoftFail);
10000b57cec5SDimitry Andric   }
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   MCInst::iterator VCCI = MI.begin();
10030b57cec5SDimitry Andric   unsigned VCCPos;
1004bdd1243dSDimitry Andric   for (VCCPos = 0; VCCPos < MCID.NumOperands; ++VCCPos, ++VCCI) {
1005bdd1243dSDimitry Andric     if (ARM::isVpred(MCID.operands()[VCCPos].OperandType) || VCCI == MI.end())
1006bdd1243dSDimitry Andric       break;
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric 
1009bdd1243dSDimitry Andric   if (isVectorPredicable(MI)) {
10100b57cec5SDimitry Andric     VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
10110b57cec5SDimitry Andric     ++VCCI;
10120b57cec5SDimitry Andric     if (VCC == ARMVCC::None)
1013349cc55cSDimitry Andric       VCCI = MI.insert(VCCI, MCOperand::createReg(0));
10140b57cec5SDimitry Andric     else
1015349cc55cSDimitry Andric       VCCI = MI.insert(VCCI, MCOperand::createReg(ARM::P0));
1016349cc55cSDimitry Andric     ++VCCI;
1017349cc55cSDimitry Andric     VCCI = MI.insert(VCCI, MCOperand::createReg(0));
1018349cc55cSDimitry Andric     ++VCCI;
1019bdd1243dSDimitry Andric     if (MCID.operands()[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
1020bdd1243dSDimitry Andric       int TiedOp = MCID.getOperandConstraint(VCCPos + 3, MCOI::TIED_TO);
10210b57cec5SDimitry Andric       assert(TiedOp >= 0 &&
10220b57cec5SDimitry Andric              "Inactive register in vpred_r is not tied to an output!");
1023e8d8bef9SDimitry Andric       // Copy the operand to ensure it's not invalidated when MI grows.
1024e8d8bef9SDimitry Andric       MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
10250b57cec5SDimitry Andric     }
10260b57cec5SDimitry Andric   } else if (VCC != ARMVCC::None) {
10270b57cec5SDimitry Andric     Check(S, SoftFail);
10280b57cec5SDimitry Andric   }
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric   return S;
10310b57cec5SDimitry Andric }
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric // Thumb VFP instructions are a special case.  Because we share their
10340b57cec5SDimitry Andric // encodings between ARM and Thumb modes, and they are predicable in ARM
10350b57cec5SDimitry Andric // mode, the auto-generated decoder will give them an (incorrect)
10360b57cec5SDimitry Andric // predicate operand.  We need to rewrite these operands based on the IT
10370b57cec5SDimitry Andric // context as a post-pass.
10380b57cec5SDimitry Andric void ARMDisassembler::UpdateThumbVFPPredicate(
10390b57cec5SDimitry Andric   DecodeStatus &S, MCInst &MI) const {
10400b57cec5SDimitry Andric   unsigned CC;
10410b57cec5SDimitry Andric   CC = ITBlock.getITCC();
10420b57cec5SDimitry Andric   if (CC == 0xF)
10430b57cec5SDimitry Andric     CC = ARMCC::AL;
10440b57cec5SDimitry Andric   if (ITBlock.instrInITBlock())
10450b57cec5SDimitry Andric     ITBlock.advanceITState();
10460b57cec5SDimitry Andric   else if (VPTBlock.instrInVPTBlock()) {
10470b57cec5SDimitry Andric     CC = VPTBlock.getVPTPred();
10480b57cec5SDimitry Andric     VPTBlock.advanceVPTState();
10490b57cec5SDimitry Andric   }
10500b57cec5SDimitry Andric 
1051bdd1243dSDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
1052bdd1243dSDimitry Andric   ArrayRef<MCOperandInfo> OpInfo = MCID.operands();
10530b57cec5SDimitry Andric   MCInst::iterator I = MI.begin();
1054bdd1243dSDimitry Andric   unsigned short NumOps = MCID.NumOperands;
10550b57cec5SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
10560b57cec5SDimitry Andric     if (OpInfo[i].isPredicate() ) {
1057bdd1243dSDimitry Andric       if (CC != ARMCC::AL && !MCID.isPredicable())
10580b57cec5SDimitry Andric         Check(S, SoftFail);
10590b57cec5SDimitry Andric       I->setImm(CC);
10600b57cec5SDimitry Andric       ++I;
10610b57cec5SDimitry Andric       if (CC == ARMCC::AL)
10620b57cec5SDimitry Andric         I->setReg(0);
10630b57cec5SDimitry Andric       else
10640b57cec5SDimitry Andric         I->setReg(ARM::CPSR);
10650b57cec5SDimitry Andric       return;
10660b57cec5SDimitry Andric     }
10670b57cec5SDimitry Andric   }
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
10710b57cec5SDimitry Andric                                                   ArrayRef<uint8_t> Bytes,
10720b57cec5SDimitry Andric                                                   uint64_t Address,
10730b57cec5SDimitry Andric                                                   raw_ostream &CS) const {
10740b57cec5SDimitry Andric   CommentStream = &CS;
10750b57cec5SDimitry Andric 
107606c3fb27SDimitry Andric   assert(STI.hasFeature(ARM::ModeThumb) &&
10770b57cec5SDimitry Andric          "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   // We want to read exactly 2 bytes of data.
10800b57cec5SDimitry Andric   if (Bytes.size() < 2) {
10810b57cec5SDimitry Andric     Size = 0;
10820b57cec5SDimitry Andric     return MCDisassembler::Fail;
10830b57cec5SDimitry Andric   }
10840b57cec5SDimitry Andric 
1085bdd1243dSDimitry Andric   uint16_t Insn16 = llvm::support::endian::read<uint16_t>(
1086bdd1243dSDimitry Andric       Bytes.data(), InstructionEndianness);
10870b57cec5SDimitry Andric   DecodeStatus Result =
10880b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
10890b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
10900b57cec5SDimitry Andric     Size = 2;
10910b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
10920b57cec5SDimitry Andric     return Result;
10930b57cec5SDimitry Andric   }
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric   Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
10960b57cec5SDimitry Andric                              STI);
10970b57cec5SDimitry Andric   if (Result) {
10980b57cec5SDimitry Andric     Size = 2;
10990b57cec5SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
11000b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11010b57cec5SDimitry Andric     AddThumb1SBit(MI, InITBlock);
11020b57cec5SDimitry Andric     return Result;
11030b57cec5SDimitry Andric   }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   Result =
11060b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
11070b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11080b57cec5SDimitry Andric     Size = 2;
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric     // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
11110b57cec5SDimitry Andric     // the Thumb predicate.
11120b57cec5SDimitry Andric     if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
11130b57cec5SDimitry Andric       Result = MCDisassembler::SoftFail;
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric     // If we find an IT instruction, we need to parse its condition
11180b57cec5SDimitry Andric     // code and mask operands so that we can apply them correctly
11190b57cec5SDimitry Andric     // to the subsequent instructions.
11200b57cec5SDimitry Andric     if (MI.getOpcode() == ARM::t2IT) {
11210b57cec5SDimitry Andric       unsigned Firstcond = MI.getOperand(0).getImm();
11220b57cec5SDimitry Andric       unsigned Mask = MI.getOperand(1).getImm();
11230b57cec5SDimitry Andric       ITBlock.setITState(Firstcond, Mask);
11240b57cec5SDimitry Andric 
11250b57cec5SDimitry Andric       // An IT instruction that would give a 'NV' predicate is unpredictable.
11260b57cec5SDimitry Andric       if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
11270b57cec5SDimitry Andric         CS << "unpredictable IT predicate sequence";
11280b57cec5SDimitry Andric     }
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric     return Result;
11310b57cec5SDimitry Andric   }
11320b57cec5SDimitry Andric 
11330b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
11340b57cec5SDimitry Andric   if (Bytes.size() < 4) {
11350b57cec5SDimitry Andric     Size = 0;
11360b57cec5SDimitry Andric     return MCDisassembler::Fail;
11370b57cec5SDimitry Andric   }
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   uint32_t Insn32 =
1140bdd1243dSDimitry Andric       (uint32_t(Insn16) << 16) | llvm::support::endian::read<uint16_t>(
1141bdd1243dSDimitry Andric                                      Bytes.data() + 2, InstructionEndianness);
11420b57cec5SDimitry Andric 
11430b57cec5SDimitry Andric   Result =
11440b57cec5SDimitry Andric       decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI);
11450b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11460b57cec5SDimitry Andric     Size = 4;
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric     // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add
11490b57cec5SDimitry Andric     // the VPT predicate.
11500b57cec5SDimitry Andric     if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock())
11510b57cec5SDimitry Andric       Result = MCDisassembler::SoftFail;
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric     if (isVPTOpcode(MI.getOpcode())) {
11560b57cec5SDimitry Andric       unsigned Mask = MI.getOperand(0).getImm();
11570b57cec5SDimitry Andric       VPTBlock.setVPTState(Mask);
11580b57cec5SDimitry Andric     }
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric     return Result;
11610b57cec5SDimitry Andric   }
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric   Result =
11640b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
11650b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11660b57cec5SDimitry Andric     Size = 4;
11670b57cec5SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
11680b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
11690b57cec5SDimitry Andric     AddThumb1SBit(MI, InITBlock);
11700b57cec5SDimitry Andric     return Result;
11710b57cec5SDimitry Andric   }
11720b57cec5SDimitry Andric 
11730b57cec5SDimitry Andric   Result =
11740b57cec5SDimitry Andric       decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
11750b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11760b57cec5SDimitry Andric     Size = 4;
11770b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
1178480093f4SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, CS, Insn32, Result);
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
11820b57cec5SDimitry Andric     Result =
11830b57cec5SDimitry Andric         decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
11840b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
11850b57cec5SDimitry Andric       Size = 4;
11860b57cec5SDimitry Andric       UpdateThumbVFPPredicate(Result, MI);
11870b57cec5SDimitry Andric       return Result;
11880b57cec5SDimitry Andric     }
11890b57cec5SDimitry Andric   }
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric   Result =
11920b57cec5SDimitry Andric       decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
11930b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
11940b57cec5SDimitry Andric     Size = 4;
11950b57cec5SDimitry Andric     return Result;
11960b57cec5SDimitry Andric   }
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
11990b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
12000b57cec5SDimitry Andric                                STI);
12010b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12020b57cec5SDimitry Andric       Size = 4;
12030b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
12040b57cec5SDimitry Andric       return Result;
12050b57cec5SDimitry Andric     }
12060b57cec5SDimitry Andric   }
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
12090b57cec5SDimitry Andric     uint32_t NEONLdStInsn = Insn32;
12100b57cec5SDimitry Andric     NEONLdStInsn &= 0xF0FFFFFF;
12110b57cec5SDimitry Andric     NEONLdStInsn |= 0x04000000;
12120b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
12130b57cec5SDimitry Andric                                Address, this, STI);
12140b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12150b57cec5SDimitry Andric       Size = 4;
12160b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
12170b57cec5SDimitry Andric       return Result;
12180b57cec5SDimitry Andric     }
12190b57cec5SDimitry Andric   }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
12220b57cec5SDimitry Andric     uint32_t NEONDataInsn = Insn32;
12230b57cec5SDimitry Andric     NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
12240b57cec5SDimitry Andric     NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
12250b57cec5SDimitry Andric     NEONDataInsn |= 0x12000000; // Set bits 28 and 25
12260b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
12270b57cec5SDimitry Andric                                Address, this, STI);
12280b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12290b57cec5SDimitry Andric       Size = 4;
12300b57cec5SDimitry Andric       Check(Result, AddThumbPredicate(MI));
12310b57cec5SDimitry Andric       return Result;
12320b57cec5SDimitry Andric     }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric     uint32_t NEONCryptoInsn = Insn32;
12350b57cec5SDimitry Andric     NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
12360b57cec5SDimitry Andric     NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
12370b57cec5SDimitry Andric     NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
12380b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
12390b57cec5SDimitry Andric                                Address, this, STI);
12400b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12410b57cec5SDimitry Andric       Size = 4;
12420b57cec5SDimitry Andric       return Result;
12430b57cec5SDimitry Andric     }
12440b57cec5SDimitry Andric 
12450b57cec5SDimitry Andric     uint32_t NEONv8Insn = Insn32;
12460b57cec5SDimitry Andric     NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
12470b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
12480b57cec5SDimitry Andric                                this, STI);
12490b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12500b57cec5SDimitry Andric       Size = 4;
12510b57cec5SDimitry Andric       return Result;
12520b57cec5SDimitry Andric     }
12530b57cec5SDimitry Andric   }
12540b57cec5SDimitry Andric 
12555ffd83dbSDimitry Andric   uint32_t Coproc = fieldFromInstruction(Insn32, 8, 4);
12565ffd83dbSDimitry Andric   const uint8_t *DecoderTable = ARM::isCDECoproc(Coproc, STI)
12575ffd83dbSDimitry Andric                                     ? DecoderTableThumb2CDE32
12585ffd83dbSDimitry Andric                                     : DecoderTableThumb2CoProc32;
12590b57cec5SDimitry Andric   Result =
12605ffd83dbSDimitry Andric       decodeInstruction(DecoderTable, MI, Insn32, Address, this, STI);
12610b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail) {
12620b57cec5SDimitry Andric     Size = 4;
12630b57cec5SDimitry Andric     Check(Result, AddThumbPredicate(MI));
12640b57cec5SDimitry Andric     return Result;
12650b57cec5SDimitry Andric   }
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   Size = 0;
12680b57cec5SDimitry Andric   return MCDisassembler::Fail;
12690b57cec5SDimitry Andric }
12700b57cec5SDimitry Andric 
1271480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMDisassembler() {
12720b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(),
12730b57cec5SDimitry Andric                                          createARMDisassembler);
12740b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(),
12750b57cec5SDimitry Andric                                          createARMDisassembler);
12760b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(),
12770b57cec5SDimitry Andric                                          createARMDisassembler);
12780b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(),
12790b57cec5SDimitry Andric                                          createARMDisassembler);
12800b57cec5SDimitry Andric }
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric static const uint16_t GPRDecoderTable[] = {
12830b57cec5SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
12840b57cec5SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
12850b57cec5SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
12860b57cec5SDimitry Andric   ARM::R12, ARM::SP, ARM::LR, ARM::PC
12870b57cec5SDimitry Andric };
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric static const uint16_t CLRMGPRDecoderTable[] = {
12900b57cec5SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
12910b57cec5SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
12920b57cec5SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
12930b57cec5SDimitry Andric   ARM::R12, 0, ARM::LR, ARM::APSR
12940b57cec5SDimitry Andric };
12950b57cec5SDimitry Andric 
12960b57cec5SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
129781ad6265SDimitry Andric                                            uint64_t Address,
129881ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
12990b57cec5SDimitry Andric   if (RegNo > 15)
13000b57cec5SDimitry Andric     return MCDisassembler::Fail;
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
13030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13040b57cec5SDimitry Andric   return MCDisassembler::Success;
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric 
13070b57cec5SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
13080b57cec5SDimitry Andric                                                uint64_t Address,
130981ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13100b57cec5SDimitry Andric   if (RegNo > 15)
13110b57cec5SDimitry Andric     return MCDisassembler::Fail;
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric   unsigned Register = CLRMGPRDecoderTable[RegNo];
13140b57cec5SDimitry Andric   if (Register == 0)
13150b57cec5SDimitry Andric     return MCDisassembler::Fail;
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
13180b57cec5SDimitry Andric   return MCDisassembler::Success;
13190b57cec5SDimitry Andric }
13200b57cec5SDimitry Andric 
132181ad6265SDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
132281ad6265SDimitry Andric                                                uint64_t Address,
132381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13240b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   if (RegNo == 15)
13270b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric   return S;
13320b57cec5SDimitry Andric }
13330b57cec5SDimitry Andric 
13344824e7fdSDimitry Andric static DecodeStatus DecodeGPRnospRegisterClass(MCInst &Inst, unsigned RegNo,
13354824e7fdSDimitry Andric                                                uint64_t Address,
133681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13374824e7fdSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13384824e7fdSDimitry Andric 
13394824e7fdSDimitry Andric   if (RegNo == 13)
13404824e7fdSDimitry Andric     S = MCDisassembler::SoftFail;
13414824e7fdSDimitry Andric 
13424824e7fdSDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13434824e7fdSDimitry Andric 
13444824e7fdSDimitry Andric   return S;
13454824e7fdSDimitry Andric }
13464824e7fdSDimitry Andric 
13470b57cec5SDimitry Andric static DecodeStatus
134881ad6265SDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
134981ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
13500b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric   if (RegNo == 15)
13530b57cec5SDimitry Andric   {
13540b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
13550b57cec5SDimitry Andric     return MCDisassembler::Success;
13560b57cec5SDimitry Andric   }
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13590b57cec5SDimitry Andric   return S;
13600b57cec5SDimitry Andric }
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric static DecodeStatus
136381ad6265SDimitry Andric DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
136481ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
13650b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric   if (RegNo == 15)
13680b57cec5SDimitry Andric   {
13690b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::ZR));
13700b57cec5SDimitry Andric     return MCDisassembler::Success;
13710b57cec5SDimitry Andric   }
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   if (RegNo == 13)
13740b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
13770b57cec5SDimitry Andric   return S;
13780b57cec5SDimitry Andric }
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric static DecodeStatus
138181ad6265SDimitry Andric DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
138281ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
13830b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13840b57cec5SDimitry Andric   if (RegNo == 13)
13850b57cec5SDimitry Andric     return MCDisassembler::Fail;
13860b57cec5SDimitry Andric   Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder));
13870b57cec5SDimitry Andric   return S;
13880b57cec5SDimitry Andric }
13890b57cec5SDimitry Andric 
13900b57cec5SDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
139181ad6265SDimitry Andric                                             uint64_t Address,
139281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
13930b57cec5SDimitry Andric   if (RegNo > 7)
13940b57cec5SDimitry Andric     return MCDisassembler::Fail;
13950b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
13960b57cec5SDimitry Andric }
13970b57cec5SDimitry Andric 
13980b57cec5SDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
13990b57cec5SDimitry Andric   ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
14000b57cec5SDimitry Andric   ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
14010b57cec5SDimitry Andric };
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
140481ad6265SDimitry Andric                                                uint64_t Address,
140581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
14060b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14070b57cec5SDimitry Andric 
14085ffd83dbSDimitry Andric   // According to the Arm ARM RegNo = 14 is undefined, but we return fail
14095ffd83dbSDimitry Andric   // rather than SoftFail as there is no GPRPair table entry for index 7.
14100b57cec5SDimitry Andric   if (RegNo > 13)
14110b57cec5SDimitry Andric     return MCDisassembler::Fail;
14120b57cec5SDimitry Andric 
14135ffd83dbSDimitry Andric   if (RegNo & 1)
14140b57cec5SDimitry Andric      S = MCDisassembler::SoftFail;
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
14170b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
14180b57cec5SDimitry Andric   return S;
14190b57cec5SDimitry Andric }
14200b57cec5SDimitry Andric 
142181ad6265SDimitry Andric static DecodeStatus
142281ad6265SDimitry Andric DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
142381ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
14245ffd83dbSDimitry Andric   if (RegNo > 13)
14255ffd83dbSDimitry Andric     return MCDisassembler::Fail;
14265ffd83dbSDimitry Andric 
14275ffd83dbSDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
14285ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
14295ffd83dbSDimitry Andric 
14305ffd83dbSDimitry Andric   if ((RegNo & 1) || RegNo > 10)
14315ffd83dbSDimitry Andric      return MCDisassembler::SoftFail;
14325ffd83dbSDimitry Andric   return MCDisassembler::Success;
14335ffd83dbSDimitry Andric }
14345ffd83dbSDimitry Andric 
1435480093f4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
1436480093f4SDimitry Andric                                              uint64_t Address,
143781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
1438480093f4SDimitry Andric   if (RegNo != 13)
1439480093f4SDimitry Andric     return MCDisassembler::Fail;
1440480093f4SDimitry Andric 
1441480093f4SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
1442480093f4SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
1443480093f4SDimitry Andric   return MCDisassembler::Success;
1444480093f4SDimitry Andric }
1445480093f4SDimitry Andric 
14460b57cec5SDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
144781ad6265SDimitry Andric                                              uint64_t Address,
144881ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
14490b57cec5SDimitry Andric   unsigned Register = 0;
14500b57cec5SDimitry Andric   switch (RegNo) {
14510b57cec5SDimitry Andric     case 0:
14520b57cec5SDimitry Andric       Register = ARM::R0;
14530b57cec5SDimitry Andric       break;
14540b57cec5SDimitry Andric     case 1:
14550b57cec5SDimitry Andric       Register = ARM::R1;
14560b57cec5SDimitry Andric       break;
14570b57cec5SDimitry Andric     case 2:
14580b57cec5SDimitry Andric       Register = ARM::R2;
14590b57cec5SDimitry Andric       break;
14600b57cec5SDimitry Andric     case 3:
14610b57cec5SDimitry Andric       Register = ARM::R3;
14620b57cec5SDimitry Andric       break;
14630b57cec5SDimitry Andric     case 9:
14640b57cec5SDimitry Andric       Register = ARM::R9;
14650b57cec5SDimitry Andric       break;
14660b57cec5SDimitry Andric     case 12:
14670b57cec5SDimitry Andric       Register = ARM::R12;
14680b57cec5SDimitry Andric       break;
14690b57cec5SDimitry Andric     default:
14700b57cec5SDimitry Andric       return MCDisassembler::Fail;
14710b57cec5SDimitry Andric     }
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
14740b57cec5SDimitry Andric   return MCDisassembler::Success;
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric 
14770b57cec5SDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
147881ad6265SDimitry Andric                                             uint64_t Address,
147981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
14800b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric   const FeatureBitset &featureBits =
14830b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric   if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15)
14860b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
14890b57cec5SDimitry Andric   return S;
14900b57cec5SDimitry Andric }
14910b57cec5SDimitry Andric 
14920b57cec5SDimitry Andric static const uint16_t SPRDecoderTable[] = {
14930b57cec5SDimitry Andric      ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
14940b57cec5SDimitry Andric      ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
14950b57cec5SDimitry Andric      ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
14960b57cec5SDimitry Andric     ARM::S12, ARM::S13, ARM::S14, ARM::S15,
14970b57cec5SDimitry Andric     ARM::S16, ARM::S17, ARM::S18, ARM::S19,
14980b57cec5SDimitry Andric     ARM::S20, ARM::S21, ARM::S22, ARM::S23,
14990b57cec5SDimitry Andric     ARM::S24, ARM::S25, ARM::S26, ARM::S27,
15000b57cec5SDimitry Andric     ARM::S28, ARM::S29, ARM::S30, ARM::S31
15010b57cec5SDimitry Andric };
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
150481ad6265SDimitry Andric                                            uint64_t Address,
150581ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15060b57cec5SDimitry Andric   if (RegNo > 31)
15070b57cec5SDimitry Andric     return MCDisassembler::Fail;
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric   unsigned Register = SPRDecoderTable[RegNo];
15100b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
15110b57cec5SDimitry Andric   return MCDisassembler::Success;
15120b57cec5SDimitry Andric }
15130b57cec5SDimitry Andric 
15140b57cec5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
151581ad6265SDimitry Andric                                            uint64_t Address,
151681ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15170b57cec5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
15180b57cec5SDimitry Andric }
15190b57cec5SDimitry Andric 
15200b57cec5SDimitry Andric static const uint16_t DPRDecoderTable[] = {
15210b57cec5SDimitry Andric      ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
15220b57cec5SDimitry Andric      ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
15230b57cec5SDimitry Andric      ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
15240b57cec5SDimitry Andric     ARM::D12, ARM::D13, ARM::D14, ARM::D15,
15250b57cec5SDimitry Andric     ARM::D16, ARM::D17, ARM::D18, ARM::D19,
15260b57cec5SDimitry Andric     ARM::D20, ARM::D21, ARM::D22, ARM::D23,
15270b57cec5SDimitry Andric     ARM::D24, ARM::D25, ARM::D26, ARM::D27,
15280b57cec5SDimitry Andric     ARM::D28, ARM::D29, ARM::D30, ARM::D31
15290b57cec5SDimitry Andric };
15300b57cec5SDimitry Andric 
15310b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
153281ad6265SDimitry Andric                                            uint64_t Address,
153381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15340b57cec5SDimitry Andric   const FeatureBitset &featureBits =
15350b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric   bool hasD32 = featureBits[ARM::FeatureD32];
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric   if (RegNo > 31 || (!hasD32 && RegNo > 15))
15400b57cec5SDimitry Andric     return MCDisassembler::Fail;
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric   unsigned Register = DPRDecoderTable[RegNo];
15430b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
15440b57cec5SDimitry Andric   return MCDisassembler::Success;
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
154881ad6265SDimitry Andric                                              uint64_t Address,
154981ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
15500b57cec5SDimitry Andric   if (RegNo > 7)
15510b57cec5SDimitry Andric     return MCDisassembler::Fail;
15520b57cec5SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
15530b57cec5SDimitry Andric }
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
155681ad6265SDimitry Andric                                              uint64_t Address,
155781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
15580b57cec5SDimitry Andric   if (RegNo > 15)
15590b57cec5SDimitry Andric     return MCDisassembler::Fail;
15600b57cec5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
15610b57cec5SDimitry Andric }
15620b57cec5SDimitry Andric 
156381ad6265SDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
156481ad6265SDimitry Andric                                                 uint64_t Address,
156581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
15660b57cec5SDimitry Andric   if (RegNo > 15)
15670b57cec5SDimitry Andric     return MCDisassembler::Fail;
15680b57cec5SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
15690b57cec5SDimitry Andric }
15700b57cec5SDimitry Andric 
15710b57cec5SDimitry Andric static const uint16_t QPRDecoderTable[] = {
15720b57cec5SDimitry Andric      ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
15730b57cec5SDimitry Andric      ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
15740b57cec5SDimitry Andric      ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
15750b57cec5SDimitry Andric     ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
15760b57cec5SDimitry Andric };
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
157981ad6265SDimitry Andric                                            uint64_t Address,
158081ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
15810b57cec5SDimitry Andric   if (RegNo > 31 || (RegNo & 1) != 0)
15820b57cec5SDimitry Andric     return MCDisassembler::Fail;
15830b57cec5SDimitry Andric   RegNo >>= 1;
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
15860b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
15870b57cec5SDimitry Andric   return MCDisassembler::Success;
15880b57cec5SDimitry Andric }
15890b57cec5SDimitry Andric 
15900b57cec5SDimitry Andric static const uint16_t DPairDecoderTable[] = {
15910b57cec5SDimitry Andric   ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
15920b57cec5SDimitry Andric   ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
15930b57cec5SDimitry Andric   ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
15940b57cec5SDimitry Andric   ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
15950b57cec5SDimitry Andric   ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
15960b57cec5SDimitry Andric   ARM::Q15
15970b57cec5SDimitry Andric };
15980b57cec5SDimitry Andric 
15990b57cec5SDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
160081ad6265SDimitry Andric                                              uint64_t Address,
160181ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
16020b57cec5SDimitry Andric   if (RegNo > 30)
16030b57cec5SDimitry Andric     return MCDisassembler::Fail;
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric   unsigned Register = DPairDecoderTable[RegNo];
16060b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
16070b57cec5SDimitry Andric   return MCDisassembler::Success;
16080b57cec5SDimitry Andric }
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric static const uint16_t DPairSpacedDecoderTable[] = {
16110b57cec5SDimitry Andric   ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
16120b57cec5SDimitry Andric   ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
16130b57cec5SDimitry Andric   ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
16140b57cec5SDimitry Andric   ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
16150b57cec5SDimitry Andric   ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
16160b57cec5SDimitry Andric   ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
16170b57cec5SDimitry Andric   ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
16180b57cec5SDimitry Andric   ARM::D28_D30, ARM::D29_D31
16190b57cec5SDimitry Andric };
16200b57cec5SDimitry Andric 
162181ad6265SDimitry Andric static DecodeStatus
162281ad6265SDimitry Andric DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
162381ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
16240b57cec5SDimitry Andric   if (RegNo > 29)
16250b57cec5SDimitry Andric     return MCDisassembler::Fail;
16260b57cec5SDimitry Andric 
16270b57cec5SDimitry Andric   unsigned Register = DPairSpacedDecoderTable[RegNo];
16280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
16290b57cec5SDimitry Andric   return MCDisassembler::Success;
16300b57cec5SDimitry Andric }
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
163381ad6265SDimitry Andric                                            uint64_t Address,
163481ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
16350b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16360b57cec5SDimitry Andric   if (Val == 0xF) return MCDisassembler::Fail;
16370b57cec5SDimitry Andric   // AL predicate is not allowed on Thumb1 branches.
16380b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
16390b57cec5SDimitry Andric     return MCDisassembler::Fail;
1640bdd1243dSDimitry Andric   const MCInstrInfo *MCII =
1641bdd1243dSDimitry Andric       static_cast<const ARMDisassembler *>(Decoder)->MCII.get();
1642bdd1243dSDimitry Andric   if (Val != ARMCC::AL && !MCII->get(Inst.getOpcode()).isPredicable())
16430b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
16440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
16450b57cec5SDimitry Andric   if (Val == ARMCC::AL) {
16460b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
16470b57cec5SDimitry Andric   } else
16480b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
16490b57cec5SDimitry Andric   return S;
16500b57cec5SDimitry Andric }
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
165381ad6265SDimitry Andric                                        uint64_t Address,
165481ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
16550b57cec5SDimitry Andric   if (Val)
16560b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
16570b57cec5SDimitry Andric   else
16580b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
16590b57cec5SDimitry Andric   return MCDisassembler::Success;
16600b57cec5SDimitry Andric }
16610b57cec5SDimitry Andric 
16620b57cec5SDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
166381ad6265SDimitry Andric                                           uint64_t Address,
166481ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
16650b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16660b57cec5SDimitry Andric 
16670b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
16680b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
16690b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric   // Register-immediate
16720b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
16730b57cec5SDimitry Andric     return MCDisassembler::Fail;
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
16760b57cec5SDimitry Andric   switch (type) {
16770b57cec5SDimitry Andric     case 0:
16780b57cec5SDimitry Andric       Shift = ARM_AM::lsl;
16790b57cec5SDimitry Andric       break;
16800b57cec5SDimitry Andric     case 1:
16810b57cec5SDimitry Andric       Shift = ARM_AM::lsr;
16820b57cec5SDimitry Andric       break;
16830b57cec5SDimitry Andric     case 2:
16840b57cec5SDimitry Andric       Shift = ARM_AM::asr;
16850b57cec5SDimitry Andric       break;
16860b57cec5SDimitry Andric     case 3:
16870b57cec5SDimitry Andric       Shift = ARM_AM::ror;
16880b57cec5SDimitry Andric       break;
16890b57cec5SDimitry Andric   }
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric   if (Shift == ARM_AM::ror && imm == 0)
16920b57cec5SDimitry Andric     Shift = ARM_AM::rrx;
16930b57cec5SDimitry Andric 
16940b57cec5SDimitry Andric   unsigned Op = Shift | (imm << 3);
16950b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Op));
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric   return S;
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
170181ad6265SDimitry Andric                                           uint64_t Address,
170281ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
17030b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
17040b57cec5SDimitry Andric 
17050b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
17060b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
17070b57cec5SDimitry Andric   unsigned Rs = fieldFromInstruction(Val, 8, 4);
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric   // Register-register
17100b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
17110b57cec5SDimitry Andric     return MCDisassembler::Fail;
17120b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
17130b57cec5SDimitry Andric     return MCDisassembler::Fail;
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
17160b57cec5SDimitry Andric   switch (type) {
17170b57cec5SDimitry Andric     case 0:
17180b57cec5SDimitry Andric       Shift = ARM_AM::lsl;
17190b57cec5SDimitry Andric       break;
17200b57cec5SDimitry Andric     case 1:
17210b57cec5SDimitry Andric       Shift = ARM_AM::lsr;
17220b57cec5SDimitry Andric       break;
17230b57cec5SDimitry Andric     case 2:
17240b57cec5SDimitry Andric       Shift = ARM_AM::asr;
17250b57cec5SDimitry Andric       break;
17260b57cec5SDimitry Andric     case 3:
17270b57cec5SDimitry Andric       Shift = ARM_AM::ror;
17280b57cec5SDimitry Andric       break;
17290b57cec5SDimitry Andric   }
17300b57cec5SDimitry Andric 
17310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Shift));
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric   return S;
17340b57cec5SDimitry Andric }
17350b57cec5SDimitry Andric 
17360b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
173781ad6265SDimitry Andric                                          uint64_t Address,
173881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
17390b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric   bool NeedDisjointWriteback = false;
17420b57cec5SDimitry Andric   unsigned WritebackReg = 0;
17430b57cec5SDimitry Andric   bool CLRM = false;
17440b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
17450b57cec5SDimitry Andric   default:
17460b57cec5SDimitry Andric     break;
17470b57cec5SDimitry Andric   case ARM::LDMIA_UPD:
17480b57cec5SDimitry Andric   case ARM::LDMDB_UPD:
17490b57cec5SDimitry Andric   case ARM::LDMIB_UPD:
17500b57cec5SDimitry Andric   case ARM::LDMDA_UPD:
17510b57cec5SDimitry Andric   case ARM::t2LDMIA_UPD:
17520b57cec5SDimitry Andric   case ARM::t2LDMDB_UPD:
17530b57cec5SDimitry Andric   case ARM::t2STMIA_UPD:
17540b57cec5SDimitry Andric   case ARM::t2STMDB_UPD:
17550b57cec5SDimitry Andric     NeedDisjointWriteback = true;
17560b57cec5SDimitry Andric     WritebackReg = Inst.getOperand(0).getReg();
17570b57cec5SDimitry Andric     break;
17580b57cec5SDimitry Andric   case ARM::t2CLRM:
17590b57cec5SDimitry Andric     CLRM = true;
17600b57cec5SDimitry Andric     break;
17610b57cec5SDimitry Andric   }
17620b57cec5SDimitry Andric 
17630b57cec5SDimitry Andric   // Empty register lists are not allowed.
17640b57cec5SDimitry Andric   if (Val == 0) return MCDisassembler::Fail;
17650b57cec5SDimitry Andric   for (unsigned i = 0; i < 16; ++i) {
17660b57cec5SDimitry Andric     if (Val & (1 << i)) {
17670b57cec5SDimitry Andric       if (CLRM) {
17680b57cec5SDimitry Andric         if (!Check(S, DecodeCLRMGPRRegisterClass(Inst, i, Address, Decoder))) {
17690b57cec5SDimitry Andric           return MCDisassembler::Fail;
17700b57cec5SDimitry Andric         }
17710b57cec5SDimitry Andric       } else {
17720b57cec5SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
17730b57cec5SDimitry Andric           return MCDisassembler::Fail;
17740b57cec5SDimitry Andric         // Writeback not allowed if Rn is in the target list.
17750b57cec5SDimitry Andric         if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
17760b57cec5SDimitry Andric           Check(S, MCDisassembler::SoftFail);
17770b57cec5SDimitry Andric       }
17780b57cec5SDimitry Andric     }
17790b57cec5SDimitry Andric   }
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric   return S;
17820b57cec5SDimitry Andric }
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
178581ad6265SDimitry Andric                                             uint64_t Address,
178681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
17870b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
17900b57cec5SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 0, 8);
17910b57cec5SDimitry Andric 
17920b57cec5SDimitry Andric   // In case of unpredictable encoding, tweak the operands.
17930b57cec5SDimitry Andric   if (regs == 0 || (Vd + regs) > 32) {
17940b57cec5SDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
17950b57cec5SDimitry Andric     regs = std::max( 1u, regs);
17960b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
17970b57cec5SDimitry Andric   }
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
18000b57cec5SDimitry Andric     return MCDisassembler::Fail;
18010b57cec5SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
18020b57cec5SDimitry Andric     if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
18030b57cec5SDimitry Andric       return MCDisassembler::Fail;
18040b57cec5SDimitry Andric   }
18050b57cec5SDimitry Andric 
18060b57cec5SDimitry Andric   return S;
18070b57cec5SDimitry Andric }
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
181081ad6265SDimitry Andric                                             uint64_t Address,
181181ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
18120b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
18150b57cec5SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 1, 7);
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric   // In case of unpredictable encoding, tweak the operands.
18180b57cec5SDimitry Andric   if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
18190b57cec5SDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
18200b57cec5SDimitry Andric     regs = std::max( 1u, regs);
18210b57cec5SDimitry Andric     regs = std::min(16u, regs);
18220b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
18230b57cec5SDimitry Andric   }
18240b57cec5SDimitry Andric 
18250b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
18260b57cec5SDimitry Andric       return MCDisassembler::Fail;
18270b57cec5SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
18280b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
18290b57cec5SDimitry Andric       return MCDisassembler::Fail;
18300b57cec5SDimitry Andric   }
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric   return S;
18330b57cec5SDimitry Andric }
18340b57cec5SDimitry Andric 
18350b57cec5SDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
183681ad6265SDimitry Andric                                               uint64_t Address,
183781ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
18380b57cec5SDimitry Andric   // This operand encodes a mask of contiguous zeros between a specified MSB
18390b57cec5SDimitry Andric   // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
18400b57cec5SDimitry Andric   // the mask of all bits LSB-and-lower, and then xor them to create
18410b57cec5SDimitry Andric   // the mask of that's all ones on [msb, lsb].  Finally we not it to
18420b57cec5SDimitry Andric   // create the final mask.
18430b57cec5SDimitry Andric   unsigned msb = fieldFromInstruction(Val, 5, 5);
18440b57cec5SDimitry Andric   unsigned lsb = fieldFromInstruction(Val, 0, 5);
18450b57cec5SDimitry Andric 
18460b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18470b57cec5SDimitry Andric   if (lsb > msb) {
18480b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
18490b57cec5SDimitry Andric     // The check above will cause the warning for the "potentially undefined
18500b57cec5SDimitry Andric     // instruction encoding" but we can't build a bad MCOperand value here
18510b57cec5SDimitry Andric     // with a lsb > msb or else printing the MCInst will cause a crash.
18520b57cec5SDimitry Andric     lsb = msb;
18530b57cec5SDimitry Andric   }
18540b57cec5SDimitry Andric 
18550b57cec5SDimitry Andric   uint32_t msb_mask = 0xFFFFFFFF;
18560b57cec5SDimitry Andric   if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
18570b57cec5SDimitry Andric   uint32_t lsb_mask = (1U << lsb) - 1;
18580b57cec5SDimitry Andric 
18590b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask)));
18600b57cec5SDimitry Andric   return S;
18610b57cec5SDimitry Andric }
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
186481ad6265SDimitry Andric                                             uint64_t Address,
186581ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
18660b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
18690b57cec5SDimitry Andric   unsigned CRd = fieldFromInstruction(Insn, 12, 4);
18700b57cec5SDimitry Andric   unsigned coproc = fieldFromInstruction(Insn, 8, 4);
18710b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
18720b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
18730b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
18740b57cec5SDimitry Andric   const FeatureBitset &featureBits =
18750b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
18760b57cec5SDimitry Andric 
18770b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
18780b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
18790b57cec5SDimitry Andric     case ARM::LDC_PRE:
18800b57cec5SDimitry Andric     case ARM::LDC_POST:
18810b57cec5SDimitry Andric     case ARM::LDC_OPTION:
18820b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
18830b57cec5SDimitry Andric     case ARM::LDCL_PRE:
18840b57cec5SDimitry Andric     case ARM::LDCL_POST:
18850b57cec5SDimitry Andric     case ARM::LDCL_OPTION:
18860b57cec5SDimitry Andric     case ARM::STC_OFFSET:
18870b57cec5SDimitry Andric     case ARM::STC_PRE:
18880b57cec5SDimitry Andric     case ARM::STC_POST:
18890b57cec5SDimitry Andric     case ARM::STC_OPTION:
18900b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
18910b57cec5SDimitry Andric     case ARM::STCL_PRE:
18920b57cec5SDimitry Andric     case ARM::STCL_POST:
18930b57cec5SDimitry Andric     case ARM::STCL_OPTION:
18940b57cec5SDimitry Andric     case ARM::t2LDC_OFFSET:
18950b57cec5SDimitry Andric     case ARM::t2LDC_PRE:
18960b57cec5SDimitry Andric     case ARM::t2LDC_POST:
18970b57cec5SDimitry Andric     case ARM::t2LDC_OPTION:
18980b57cec5SDimitry Andric     case ARM::t2LDCL_OFFSET:
18990b57cec5SDimitry Andric     case ARM::t2LDCL_PRE:
19000b57cec5SDimitry Andric     case ARM::t2LDCL_POST:
19010b57cec5SDimitry Andric     case ARM::t2LDCL_OPTION:
19020b57cec5SDimitry Andric     case ARM::t2STC_OFFSET:
19030b57cec5SDimitry Andric     case ARM::t2STC_PRE:
19040b57cec5SDimitry Andric     case ARM::t2STC_POST:
19050b57cec5SDimitry Andric     case ARM::t2STC_OPTION:
19060b57cec5SDimitry Andric     case ARM::t2STCL_OFFSET:
19070b57cec5SDimitry Andric     case ARM::t2STCL_PRE:
19080b57cec5SDimitry Andric     case ARM::t2STCL_POST:
19090b57cec5SDimitry Andric     case ARM::t2STCL_OPTION:
19100b57cec5SDimitry Andric     case ARM::t2LDC2_OFFSET:
19110b57cec5SDimitry Andric     case ARM::t2LDC2L_OFFSET:
19120b57cec5SDimitry Andric     case ARM::t2LDC2_PRE:
19130b57cec5SDimitry Andric     case ARM::t2LDC2L_PRE:
19140b57cec5SDimitry Andric     case ARM::t2STC2_OFFSET:
19150b57cec5SDimitry Andric     case ARM::t2STC2L_OFFSET:
19160b57cec5SDimitry Andric     case ARM::t2STC2_PRE:
19170b57cec5SDimitry Andric     case ARM::t2STC2L_PRE:
19180b57cec5SDimitry Andric     case ARM::LDC2_OFFSET:
19190b57cec5SDimitry Andric     case ARM::LDC2L_OFFSET:
19200b57cec5SDimitry Andric     case ARM::LDC2_PRE:
19210b57cec5SDimitry Andric     case ARM::LDC2L_PRE:
19220b57cec5SDimitry Andric     case ARM::STC2_OFFSET:
19230b57cec5SDimitry Andric     case ARM::STC2L_OFFSET:
19240b57cec5SDimitry Andric     case ARM::STC2_PRE:
19250b57cec5SDimitry Andric     case ARM::STC2L_PRE:
19260b57cec5SDimitry Andric     case ARM::t2LDC2_OPTION:
19270b57cec5SDimitry Andric     case ARM::t2STC2_OPTION:
19280b57cec5SDimitry Andric     case ARM::t2LDC2_POST:
19290b57cec5SDimitry Andric     case ARM::t2LDC2L_POST:
19300b57cec5SDimitry Andric     case ARM::t2STC2_POST:
19310b57cec5SDimitry Andric     case ARM::t2STC2L_POST:
19320b57cec5SDimitry Andric     case ARM::LDC2_POST:
19330b57cec5SDimitry Andric     case ARM::LDC2L_POST:
19340b57cec5SDimitry Andric     case ARM::STC2_POST:
19350b57cec5SDimitry Andric     case ARM::STC2L_POST:
19360b57cec5SDimitry Andric       if (coproc == 0xA || coproc == 0xB ||
19370b57cec5SDimitry Andric           (featureBits[ARM::HasV8_1MMainlineOps] &&
19380b57cec5SDimitry Andric            (coproc == 0x8 || coproc == 0x9 || coproc == 0xA || coproc == 0xB ||
19390b57cec5SDimitry Andric             coproc == 0xE || coproc == 0xF)))
19400b57cec5SDimitry Andric         return MCDisassembler::Fail;
19410b57cec5SDimitry Andric       break;
19420b57cec5SDimitry Andric     default:
19430b57cec5SDimitry Andric       break;
19440b57cec5SDimitry Andric   }
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   if (featureBits[ARM::HasV8Ops] && (coproc != 14))
19470b57cec5SDimitry Andric     return MCDisassembler::Fail;
19480b57cec5SDimitry Andric 
19490b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(coproc));
19500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRd));
19510b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
19520b57cec5SDimitry Andric     return MCDisassembler::Fail;
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
19550b57cec5SDimitry Andric     case ARM::t2LDC2_OFFSET:
19560b57cec5SDimitry Andric     case ARM::t2LDC2L_OFFSET:
19570b57cec5SDimitry Andric     case ARM::t2LDC2_PRE:
19580b57cec5SDimitry Andric     case ARM::t2LDC2L_PRE:
19590b57cec5SDimitry Andric     case ARM::t2STC2_OFFSET:
19600b57cec5SDimitry Andric     case ARM::t2STC2L_OFFSET:
19610b57cec5SDimitry Andric     case ARM::t2STC2_PRE:
19620b57cec5SDimitry Andric     case ARM::t2STC2L_PRE:
19630b57cec5SDimitry Andric     case ARM::LDC2_OFFSET:
19640b57cec5SDimitry Andric     case ARM::LDC2L_OFFSET:
19650b57cec5SDimitry Andric     case ARM::LDC2_PRE:
19660b57cec5SDimitry Andric     case ARM::LDC2L_PRE:
19670b57cec5SDimitry Andric     case ARM::STC2_OFFSET:
19680b57cec5SDimitry Andric     case ARM::STC2L_OFFSET:
19690b57cec5SDimitry Andric     case ARM::STC2_PRE:
19700b57cec5SDimitry Andric     case ARM::STC2L_PRE:
19710b57cec5SDimitry Andric     case ARM::t2LDC_OFFSET:
19720b57cec5SDimitry Andric     case ARM::t2LDCL_OFFSET:
19730b57cec5SDimitry Andric     case ARM::t2LDC_PRE:
19740b57cec5SDimitry Andric     case ARM::t2LDCL_PRE:
19750b57cec5SDimitry Andric     case ARM::t2STC_OFFSET:
19760b57cec5SDimitry Andric     case ARM::t2STCL_OFFSET:
19770b57cec5SDimitry Andric     case ARM::t2STC_PRE:
19780b57cec5SDimitry Andric     case ARM::t2STCL_PRE:
19790b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
19800b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
19810b57cec5SDimitry Andric     case ARM::LDC_PRE:
19820b57cec5SDimitry Andric     case ARM::LDCL_PRE:
19830b57cec5SDimitry Andric     case ARM::STC_OFFSET:
19840b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
19850b57cec5SDimitry Andric     case ARM::STC_PRE:
19860b57cec5SDimitry Andric     case ARM::STCL_PRE:
19870b57cec5SDimitry Andric       imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
19880b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
19890b57cec5SDimitry Andric       break;
19900b57cec5SDimitry Andric     case ARM::t2LDC2_POST:
19910b57cec5SDimitry Andric     case ARM::t2LDC2L_POST:
19920b57cec5SDimitry Andric     case ARM::t2STC2_POST:
19930b57cec5SDimitry Andric     case ARM::t2STC2L_POST:
19940b57cec5SDimitry Andric     case ARM::LDC2_POST:
19950b57cec5SDimitry Andric     case ARM::LDC2L_POST:
19960b57cec5SDimitry Andric     case ARM::STC2_POST:
19970b57cec5SDimitry Andric     case ARM::STC2L_POST:
19980b57cec5SDimitry Andric     case ARM::t2LDC_POST:
19990b57cec5SDimitry Andric     case ARM::t2LDCL_POST:
20000b57cec5SDimitry Andric     case ARM::t2STC_POST:
20010b57cec5SDimitry Andric     case ARM::t2STCL_POST:
20020b57cec5SDimitry Andric     case ARM::LDC_POST:
20030b57cec5SDimitry Andric     case ARM::LDCL_POST:
20040b57cec5SDimitry Andric     case ARM::STC_POST:
20050b57cec5SDimitry Andric     case ARM::STCL_POST:
20060b57cec5SDimitry Andric       imm |= U << 8;
2007bdd1243dSDimitry Andric       [[fallthrough]];
20080b57cec5SDimitry Andric     default:
20090b57cec5SDimitry Andric       // The 'option' variant doesn't encode 'U' in the immediate since
20100b57cec5SDimitry Andric       // the immediate is unsigned [0,255].
20110b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
20120b57cec5SDimitry Andric       break;
20130b57cec5SDimitry Andric   }
20140b57cec5SDimitry Andric 
20150b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20160b57cec5SDimitry Andric     case ARM::LDC_OFFSET:
20170b57cec5SDimitry Andric     case ARM::LDC_PRE:
20180b57cec5SDimitry Andric     case ARM::LDC_POST:
20190b57cec5SDimitry Andric     case ARM::LDC_OPTION:
20200b57cec5SDimitry Andric     case ARM::LDCL_OFFSET:
20210b57cec5SDimitry Andric     case ARM::LDCL_PRE:
20220b57cec5SDimitry Andric     case ARM::LDCL_POST:
20230b57cec5SDimitry Andric     case ARM::LDCL_OPTION:
20240b57cec5SDimitry Andric     case ARM::STC_OFFSET:
20250b57cec5SDimitry Andric     case ARM::STC_PRE:
20260b57cec5SDimitry Andric     case ARM::STC_POST:
20270b57cec5SDimitry Andric     case ARM::STC_OPTION:
20280b57cec5SDimitry Andric     case ARM::STCL_OFFSET:
20290b57cec5SDimitry Andric     case ARM::STCL_PRE:
20300b57cec5SDimitry Andric     case ARM::STCL_POST:
20310b57cec5SDimitry Andric     case ARM::STCL_OPTION:
20320b57cec5SDimitry Andric       if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
20330b57cec5SDimitry Andric         return MCDisassembler::Fail;
20340b57cec5SDimitry Andric       break;
20350b57cec5SDimitry Andric     default:
20360b57cec5SDimitry Andric       break;
20370b57cec5SDimitry Andric   }
20380b57cec5SDimitry Andric 
20390b57cec5SDimitry Andric   return S;
20400b57cec5SDimitry Andric }
20410b57cec5SDimitry Andric 
20420b57cec5SDimitry Andric static DecodeStatus
204381ad6265SDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
204481ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
20450b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
20460b57cec5SDimitry Andric 
20470b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
20480b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
20490b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
20500b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
20510b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
20520b57cec5SDimitry Andric   unsigned reg = fieldFromInstruction(Insn, 25, 1);
20530b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
20540b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
20550b57cec5SDimitry Andric 
20560b57cec5SDimitry Andric   // On stores, the writeback operand precedes Rt.
20570b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20580b57cec5SDimitry Andric     case ARM::STR_POST_IMM:
20590b57cec5SDimitry Andric     case ARM::STR_POST_REG:
20600b57cec5SDimitry Andric     case ARM::STRB_POST_IMM:
20610b57cec5SDimitry Andric     case ARM::STRB_POST_REG:
20620b57cec5SDimitry Andric     case ARM::STRT_POST_REG:
20630b57cec5SDimitry Andric     case ARM::STRT_POST_IMM:
20640b57cec5SDimitry Andric     case ARM::STRBT_POST_REG:
20650b57cec5SDimitry Andric     case ARM::STRBT_POST_IMM:
20660b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
20670b57cec5SDimitry Andric         return MCDisassembler::Fail;
20680b57cec5SDimitry Andric       break;
20690b57cec5SDimitry Andric     default:
20700b57cec5SDimitry Andric       break;
20710b57cec5SDimitry Andric   }
20720b57cec5SDimitry Andric 
20730b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
20740b57cec5SDimitry Andric     return MCDisassembler::Fail;
20750b57cec5SDimitry Andric 
20760b57cec5SDimitry Andric   // On loads, the writeback operand comes after Rt.
20770b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
20780b57cec5SDimitry Andric     case ARM::LDR_POST_IMM:
20790b57cec5SDimitry Andric     case ARM::LDR_POST_REG:
20800b57cec5SDimitry Andric     case ARM::LDRB_POST_IMM:
20810b57cec5SDimitry Andric     case ARM::LDRB_POST_REG:
20820b57cec5SDimitry Andric     case ARM::LDRBT_POST_REG:
20830b57cec5SDimitry Andric     case ARM::LDRBT_POST_IMM:
20840b57cec5SDimitry Andric     case ARM::LDRT_POST_REG:
20850b57cec5SDimitry Andric     case ARM::LDRT_POST_IMM:
20860b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
20870b57cec5SDimitry Andric         return MCDisassembler::Fail;
20880b57cec5SDimitry Andric       break;
20890b57cec5SDimitry Andric     default:
20900b57cec5SDimitry Andric       break;
20910b57cec5SDimitry Andric   }
20920b57cec5SDimitry Andric 
20930b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
20940b57cec5SDimitry Andric     return MCDisassembler::Fail;
20950b57cec5SDimitry Andric 
20960b57cec5SDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::add;
20970b57cec5SDimitry Andric   if (!fieldFromInstruction(Insn, 23, 1))
20980b57cec5SDimitry Andric     Op = ARM_AM::sub;
20990b57cec5SDimitry Andric 
21000b57cec5SDimitry Andric   bool writeback = (P == 0) || (W == 1);
21010b57cec5SDimitry Andric   unsigned idx_mode = 0;
21020b57cec5SDimitry Andric   if (P && writeback)
21030b57cec5SDimitry Andric     idx_mode = ARMII::IndexModePre;
21040b57cec5SDimitry Andric   else if (!P && writeback)
21050b57cec5SDimitry Andric     idx_mode = ARMII::IndexModePost;
21060b57cec5SDimitry Andric 
21070b57cec5SDimitry Andric   if (writeback && (Rn == 15 || Rn == Rt))
21080b57cec5SDimitry Andric     S = MCDisassembler::SoftFail; // UNPREDICTABLE
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric   if (reg) {
21110b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
21120b57cec5SDimitry Andric       return MCDisassembler::Fail;
21130b57cec5SDimitry Andric     ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
21140b57cec5SDimitry Andric     switch( fieldFromInstruction(Insn, 5, 2)) {
21150b57cec5SDimitry Andric       case 0:
21160b57cec5SDimitry Andric         Opc = ARM_AM::lsl;
21170b57cec5SDimitry Andric         break;
21180b57cec5SDimitry Andric       case 1:
21190b57cec5SDimitry Andric         Opc = ARM_AM::lsr;
21200b57cec5SDimitry Andric         break;
21210b57cec5SDimitry Andric       case 2:
21220b57cec5SDimitry Andric         Opc = ARM_AM::asr;
21230b57cec5SDimitry Andric         break;
21240b57cec5SDimitry Andric       case 3:
21250b57cec5SDimitry Andric         Opc = ARM_AM::ror;
21260b57cec5SDimitry Andric         break;
21270b57cec5SDimitry Andric       default:
21280b57cec5SDimitry Andric         return MCDisassembler::Fail;
21290b57cec5SDimitry Andric     }
21300b57cec5SDimitry Andric     unsigned amt = fieldFromInstruction(Insn, 7, 5);
21310b57cec5SDimitry Andric     if (Opc == ARM_AM::ror && amt == 0)
21320b57cec5SDimitry Andric       Opc = ARM_AM::rrx;
21330b57cec5SDimitry Andric     unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
21340b57cec5SDimitry Andric 
21350b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
21360b57cec5SDimitry Andric   } else {
21370b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
21380b57cec5SDimitry Andric     unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
21390b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(tmp));
21400b57cec5SDimitry Andric   }
21410b57cec5SDimitry Andric 
21420b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
21430b57cec5SDimitry Andric     return MCDisassembler::Fail;
21440b57cec5SDimitry Andric 
21450b57cec5SDimitry Andric   return S;
21460b57cec5SDimitry Andric }
21470b57cec5SDimitry Andric 
21480b57cec5SDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
214981ad6265SDimitry Andric                                           uint64_t Address,
215081ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
21510b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
21520b57cec5SDimitry Andric 
21530b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
21540b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val,  0, 4);
21550b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
21560b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
21570b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 12, 1);
21580b57cec5SDimitry Andric 
21590b57cec5SDimitry Andric   ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
21600b57cec5SDimitry Andric   switch (type) {
21610b57cec5SDimitry Andric     case 0:
21620b57cec5SDimitry Andric       ShOp = ARM_AM::lsl;
21630b57cec5SDimitry Andric       break;
21640b57cec5SDimitry Andric     case 1:
21650b57cec5SDimitry Andric       ShOp = ARM_AM::lsr;
21660b57cec5SDimitry Andric       break;
21670b57cec5SDimitry Andric     case 2:
21680b57cec5SDimitry Andric       ShOp = ARM_AM::asr;
21690b57cec5SDimitry Andric       break;
21700b57cec5SDimitry Andric     case 3:
21710b57cec5SDimitry Andric       ShOp = ARM_AM::ror;
21720b57cec5SDimitry Andric       break;
21730b57cec5SDimitry Andric   }
21740b57cec5SDimitry Andric 
21750b57cec5SDimitry Andric   if (ShOp == ARM_AM::ror && imm == 0)
21760b57cec5SDimitry Andric     ShOp = ARM_AM::rrx;
21770b57cec5SDimitry Andric 
21780b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
21790b57cec5SDimitry Andric     return MCDisassembler::Fail;
21800b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
21810b57cec5SDimitry Andric     return MCDisassembler::Fail;
21820b57cec5SDimitry Andric   unsigned shift;
21830b57cec5SDimitry Andric   if (U)
21840b57cec5SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
21850b57cec5SDimitry Andric   else
21860b57cec5SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
21870b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
21880b57cec5SDimitry Andric 
21890b57cec5SDimitry Andric   return S;
21900b57cec5SDimitry Andric }
21910b57cec5SDimitry Andric 
219281ad6265SDimitry Andric static DecodeStatus DecodeTSBInstruction(MCInst &Inst, unsigned Insn,
219381ad6265SDimitry Andric                                          uint64_t Address,
219481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
219581ad6265SDimitry Andric   if (Inst.getOpcode() != ARM::TSB && Inst.getOpcode() != ARM::t2TSB)
219681ad6265SDimitry Andric     return MCDisassembler::Fail;
219781ad6265SDimitry Andric 
219881ad6265SDimitry Andric   // The "csync" operand is not encoded into the "tsb" instruction (as this is
219981ad6265SDimitry Andric   // the only available operand), but LLVM expects the instruction to have one
220081ad6265SDimitry Andric   // operand, so we need to add the csync when decoding.
220181ad6265SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARM_TSB::CSYNC));
220281ad6265SDimitry Andric   return MCDisassembler::Success;
220381ad6265SDimitry Andric }
220481ad6265SDimitry Andric 
220581ad6265SDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
220681ad6265SDimitry Andric                                                uint64_t Address,
220781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
22080b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
22110b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
22120b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
22130b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 22, 1);
22140b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 8, 4);
22150b57cec5SDimitry Andric   unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
22160b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
22170b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
22180b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
22190b57cec5SDimitry Andric   unsigned Rt2 = Rt + 1;
22200b57cec5SDimitry Andric 
22210b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
22220b57cec5SDimitry Andric 
22230b57cec5SDimitry Andric   // For {LD,ST}RD, Rt must be even, else undefined.
22240b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
22250b57cec5SDimitry Andric     case ARM::STRD:
22260b57cec5SDimitry Andric     case ARM::STRD_PRE:
22270b57cec5SDimitry Andric     case ARM::STRD_POST:
22280b57cec5SDimitry Andric     case ARM::LDRD:
22290b57cec5SDimitry Andric     case ARM::LDRD_PRE:
22300b57cec5SDimitry Andric     case ARM::LDRD_POST:
22310b57cec5SDimitry Andric       if (Rt & 0x1) S = MCDisassembler::SoftFail;
22320b57cec5SDimitry Andric       break;
22330b57cec5SDimitry Andric     default:
22340b57cec5SDimitry Andric       break;
22350b57cec5SDimitry Andric   }
22360b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
22370b57cec5SDimitry Andric     case ARM::STRD:
22380b57cec5SDimitry Andric     case ARM::STRD_PRE:
22390b57cec5SDimitry Andric     case ARM::STRD_POST:
22400b57cec5SDimitry Andric       if (P == 0 && W == 1)
22410b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22420b57cec5SDimitry Andric 
22430b57cec5SDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
22440b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22450b57cec5SDimitry Andric       if (type && Rm == 15)
22460b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22470b57cec5SDimitry Andric       if (Rt2 == 15)
22480b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22490b57cec5SDimitry Andric       if (!type && fieldFromInstruction(Insn, 8, 4))
22500b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22510b57cec5SDimitry Andric       break;
22520b57cec5SDimitry Andric     case ARM::STRH:
22530b57cec5SDimitry Andric     case ARM::STRH_PRE:
22540b57cec5SDimitry Andric     case ARM::STRH_POST:
22550b57cec5SDimitry Andric       if (Rt == 15)
22560b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22570b57cec5SDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt))
22580b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22590b57cec5SDimitry Andric       if (!type && Rm == 15)
22600b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22610b57cec5SDimitry Andric       break;
22620b57cec5SDimitry Andric     case ARM::LDRD:
22630b57cec5SDimitry Andric     case ARM::LDRD_PRE:
22640b57cec5SDimitry Andric     case ARM::LDRD_POST:
22650b57cec5SDimitry Andric       if (type && Rn == 15) {
22660b57cec5SDimitry Andric         if (Rt2 == 15)
22670b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
22680b57cec5SDimitry Andric         break;
22690b57cec5SDimitry Andric       }
22700b57cec5SDimitry Andric       if (P == 0 && W == 1)
22710b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22720b57cec5SDimitry Andric       if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
22730b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22740b57cec5SDimitry Andric       if (!type && writeback && Rn == 15)
22750b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22760b57cec5SDimitry Andric       if (writeback && (Rn == Rt || Rn == Rt2))
22770b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22780b57cec5SDimitry Andric       break;
22790b57cec5SDimitry Andric     case ARM::LDRH:
22800b57cec5SDimitry Andric     case ARM::LDRH_PRE:
22810b57cec5SDimitry Andric     case ARM::LDRH_POST:
22820b57cec5SDimitry Andric       if (type && Rn == 15) {
22830b57cec5SDimitry Andric         if (Rt == 15)
22840b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
22850b57cec5SDimitry Andric         break;
22860b57cec5SDimitry Andric       }
22870b57cec5SDimitry Andric       if (Rt == 15)
22880b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22890b57cec5SDimitry Andric       if (!type && Rm == 15)
22900b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22910b57cec5SDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
22920b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
22930b57cec5SDimitry Andric       break;
22940b57cec5SDimitry Andric     case ARM::LDRSH:
22950b57cec5SDimitry Andric     case ARM::LDRSH_PRE:
22960b57cec5SDimitry Andric     case ARM::LDRSH_POST:
22970b57cec5SDimitry Andric     case ARM::LDRSB:
22980b57cec5SDimitry Andric     case ARM::LDRSB_PRE:
22990b57cec5SDimitry Andric     case ARM::LDRSB_POST:
23000b57cec5SDimitry Andric       if (type && Rn == 15) {
23010b57cec5SDimitry Andric         if (Rt == 15)
23020b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
23030b57cec5SDimitry Andric         break;
23040b57cec5SDimitry Andric       }
23050b57cec5SDimitry Andric       if (type && (Rt == 15 || (writeback && Rn == Rt)))
23060b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
23070b57cec5SDimitry Andric       if (!type && (Rt == 15 || Rm == 15))
23080b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
23090b57cec5SDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
23100b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
23110b57cec5SDimitry Andric       break;
23120b57cec5SDimitry Andric     default:
23130b57cec5SDimitry Andric       break;
23140b57cec5SDimitry Andric   }
23150b57cec5SDimitry Andric 
23160b57cec5SDimitry Andric   if (writeback) { // Writeback
23170b57cec5SDimitry Andric     if (P)
23180b57cec5SDimitry Andric       U |= ARMII::IndexModePre << 9;
23190b57cec5SDimitry Andric     else
23200b57cec5SDimitry Andric       U |= ARMII::IndexModePost << 9;
23210b57cec5SDimitry Andric 
23220b57cec5SDimitry Andric     // On stores, the writeback operand precedes Rt.
23230b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
23240b57cec5SDimitry Andric     case ARM::STRD:
23250b57cec5SDimitry Andric     case ARM::STRD_PRE:
23260b57cec5SDimitry Andric     case ARM::STRD_POST:
23270b57cec5SDimitry Andric     case ARM::STRH:
23280b57cec5SDimitry Andric     case ARM::STRH_PRE:
23290b57cec5SDimitry Andric     case ARM::STRH_POST:
23300b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23310b57cec5SDimitry Andric         return MCDisassembler::Fail;
23320b57cec5SDimitry Andric       break;
23330b57cec5SDimitry Andric     default:
23340b57cec5SDimitry Andric       break;
23350b57cec5SDimitry Andric     }
23360b57cec5SDimitry Andric   }
23370b57cec5SDimitry Andric 
23380b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
23390b57cec5SDimitry Andric     return MCDisassembler::Fail;
23400b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
23410b57cec5SDimitry Andric     case ARM::STRD:
23420b57cec5SDimitry Andric     case ARM::STRD_PRE:
23430b57cec5SDimitry Andric     case ARM::STRD_POST:
23440b57cec5SDimitry Andric     case ARM::LDRD:
23450b57cec5SDimitry Andric     case ARM::LDRD_PRE:
23460b57cec5SDimitry Andric     case ARM::LDRD_POST:
23470b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
23480b57cec5SDimitry Andric         return MCDisassembler::Fail;
23490b57cec5SDimitry Andric       break;
23500b57cec5SDimitry Andric     default:
23510b57cec5SDimitry Andric       break;
23520b57cec5SDimitry Andric   }
23530b57cec5SDimitry Andric 
23540b57cec5SDimitry Andric   if (writeback) {
23550b57cec5SDimitry Andric     // On loads, the writeback operand comes after Rt.
23560b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
23570b57cec5SDimitry Andric     case ARM::LDRD:
23580b57cec5SDimitry Andric     case ARM::LDRD_PRE:
23590b57cec5SDimitry Andric     case ARM::LDRD_POST:
23600b57cec5SDimitry Andric     case ARM::LDRH:
23610b57cec5SDimitry Andric     case ARM::LDRH_PRE:
23620b57cec5SDimitry Andric     case ARM::LDRH_POST:
23630b57cec5SDimitry Andric     case ARM::LDRSH:
23640b57cec5SDimitry Andric     case ARM::LDRSH_PRE:
23650b57cec5SDimitry Andric     case ARM::LDRSH_POST:
23660b57cec5SDimitry Andric     case ARM::LDRSB:
23670b57cec5SDimitry Andric     case ARM::LDRSB_PRE:
23680b57cec5SDimitry Andric     case ARM::LDRSB_POST:
23690b57cec5SDimitry Andric     case ARM::LDRHTr:
23700b57cec5SDimitry Andric     case ARM::LDRSBTr:
23710b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23720b57cec5SDimitry Andric         return MCDisassembler::Fail;
23730b57cec5SDimitry Andric       break;
23740b57cec5SDimitry Andric     default:
23750b57cec5SDimitry Andric       break;
23760b57cec5SDimitry Andric     }
23770b57cec5SDimitry Andric   }
23780b57cec5SDimitry Andric 
23790b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
23800b57cec5SDimitry Andric     return MCDisassembler::Fail;
23810b57cec5SDimitry Andric 
23820b57cec5SDimitry Andric   if (type) {
23830b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
23840b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm));
23850b57cec5SDimitry Andric   } else {
23860b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
23870b57cec5SDimitry Andric     return MCDisassembler::Fail;
23880b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(U));
23890b57cec5SDimitry Andric   }
23900b57cec5SDimitry Andric 
23910b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
23920b57cec5SDimitry Andric     return MCDisassembler::Fail;
23930b57cec5SDimitry Andric 
23940b57cec5SDimitry Andric   return S;
23950b57cec5SDimitry Andric }
23960b57cec5SDimitry Andric 
23970b57cec5SDimitry Andric static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
239881ad6265SDimitry Andric                                          uint64_t Address,
239981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
24000b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24010b57cec5SDimitry Andric 
24020b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
24030b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 23, 2);
24040b57cec5SDimitry Andric 
24050b57cec5SDimitry Andric   switch (mode) {
24060b57cec5SDimitry Andric     case 0:
24070b57cec5SDimitry Andric       mode = ARM_AM::da;
24080b57cec5SDimitry Andric       break;
24090b57cec5SDimitry Andric     case 1:
24100b57cec5SDimitry Andric       mode = ARM_AM::ia;
24110b57cec5SDimitry Andric       break;
24120b57cec5SDimitry Andric     case 2:
24130b57cec5SDimitry Andric       mode = ARM_AM::db;
24140b57cec5SDimitry Andric       break;
24150b57cec5SDimitry Andric     case 3:
24160b57cec5SDimitry Andric       mode = ARM_AM::ib;
24170b57cec5SDimitry Andric       break;
24180b57cec5SDimitry Andric   }
24190b57cec5SDimitry Andric 
24200b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(mode));
24210b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
24220b57cec5SDimitry Andric     return MCDisassembler::Fail;
24230b57cec5SDimitry Andric 
24240b57cec5SDimitry Andric   return S;
24250b57cec5SDimitry Andric }
24260b57cec5SDimitry Andric 
24270b57cec5SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
242881ad6265SDimitry Andric                                           uint64_t Address,
242981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
24300b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
24330b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
24340b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
24350b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
24360b57cec5SDimitry Andric 
24370b57cec5SDimitry Andric   if (pred == 0xF)
24380b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
24410b57cec5SDimitry Andric     return MCDisassembler::Fail;
24420b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
24430b57cec5SDimitry Andric     return MCDisassembler::Fail;
24440b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
24450b57cec5SDimitry Andric     return MCDisassembler::Fail;
24460b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
24470b57cec5SDimitry Andric     return MCDisassembler::Fail;
24480b57cec5SDimitry Andric   return S;
24490b57cec5SDimitry Andric }
24500b57cec5SDimitry Andric 
245181ad6265SDimitry Andric static DecodeStatus
245281ad6265SDimitry Andric DecodeMemMultipleWritebackInstruction(MCInst &Inst, unsigned Insn,
245381ad6265SDimitry Andric                                       uint64_t Address,
245481ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
24550b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
24560b57cec5SDimitry Andric 
24570b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
24580b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
24590b57cec5SDimitry Andric   unsigned reglist = fieldFromInstruction(Insn, 0, 16);
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric   if (pred == 0xF) {
24620b57cec5SDimitry Andric     // Ambiguous with RFE and SRS
24630b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
24640b57cec5SDimitry Andric       case ARM::LDMDA:
24650b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDA);
24660b57cec5SDimitry Andric         break;
24670b57cec5SDimitry Andric       case ARM::LDMDA_UPD:
24680b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDA_UPD);
24690b57cec5SDimitry Andric         break;
24700b57cec5SDimitry Andric       case ARM::LDMDB:
24710b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDB);
24720b57cec5SDimitry Andric         break;
24730b57cec5SDimitry Andric       case ARM::LDMDB_UPD:
24740b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEDB_UPD);
24750b57cec5SDimitry Andric         break;
24760b57cec5SDimitry Andric       case ARM::LDMIA:
24770b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIA);
24780b57cec5SDimitry Andric         break;
24790b57cec5SDimitry Andric       case ARM::LDMIA_UPD:
24800b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIA_UPD);
24810b57cec5SDimitry Andric         break;
24820b57cec5SDimitry Andric       case ARM::LDMIB:
24830b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIB);
24840b57cec5SDimitry Andric         break;
24850b57cec5SDimitry Andric       case ARM::LDMIB_UPD:
24860b57cec5SDimitry Andric         Inst.setOpcode(ARM::RFEIB_UPD);
24870b57cec5SDimitry Andric         break;
24880b57cec5SDimitry Andric       case ARM::STMDA:
24890b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDA);
24900b57cec5SDimitry Andric         break;
24910b57cec5SDimitry Andric       case ARM::STMDA_UPD:
24920b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDA_UPD);
24930b57cec5SDimitry Andric         break;
24940b57cec5SDimitry Andric       case ARM::STMDB:
24950b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDB);
24960b57cec5SDimitry Andric         break;
24970b57cec5SDimitry Andric       case ARM::STMDB_UPD:
24980b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSDB_UPD);
24990b57cec5SDimitry Andric         break;
25000b57cec5SDimitry Andric       case ARM::STMIA:
25010b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIA);
25020b57cec5SDimitry Andric         break;
25030b57cec5SDimitry Andric       case ARM::STMIA_UPD:
25040b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIA_UPD);
25050b57cec5SDimitry Andric         break;
25060b57cec5SDimitry Andric       case ARM::STMIB:
25070b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIB);
25080b57cec5SDimitry Andric         break;
25090b57cec5SDimitry Andric       case ARM::STMIB_UPD:
25100b57cec5SDimitry Andric         Inst.setOpcode(ARM::SRSIB_UPD);
25110b57cec5SDimitry Andric         break;
25120b57cec5SDimitry Andric       default:
25130b57cec5SDimitry Andric         return MCDisassembler::Fail;
25140b57cec5SDimitry Andric     }
25150b57cec5SDimitry Andric 
25160b57cec5SDimitry Andric     // For stores (which become SRS's, the only operand is the mode.
25170b57cec5SDimitry Andric     if (fieldFromInstruction(Insn, 20, 1) == 0) {
25180b57cec5SDimitry Andric       // Check SRS encoding constraints
25190b57cec5SDimitry Andric       if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
25200b57cec5SDimitry Andric             fieldFromInstruction(Insn, 20, 1) == 0))
25210b57cec5SDimitry Andric         return MCDisassembler::Fail;
25220b57cec5SDimitry Andric 
25230b57cec5SDimitry Andric       Inst.addOperand(
25240b57cec5SDimitry Andric           MCOperand::createImm(fieldFromInstruction(Insn, 0, 4)));
25250b57cec5SDimitry Andric       return S;
25260b57cec5SDimitry Andric     }
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric     return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
25290b57cec5SDimitry Andric   }
25300b57cec5SDimitry Andric 
25310b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25320b57cec5SDimitry Andric     return MCDisassembler::Fail;
25330b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
25340b57cec5SDimitry Andric     return MCDisassembler::Fail; // Tied
25350b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
25360b57cec5SDimitry Andric     return MCDisassembler::Fail;
25370b57cec5SDimitry Andric   if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
25380b57cec5SDimitry Andric     return MCDisassembler::Fail;
25390b57cec5SDimitry Andric 
25400b57cec5SDimitry Andric   return S;
25410b57cec5SDimitry Andric }
25420b57cec5SDimitry Andric 
25430b57cec5SDimitry Andric // Check for UNPREDICTABLE predicated ESB instruction
25440b57cec5SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
254581ad6265SDimitry Andric                                           uint64_t Address,
254681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
25470b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
25480b57cec5SDimitry Andric   unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
25490b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
25500b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
25510b57cec5SDimitry Andric 
25520b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25530b57cec5SDimitry Andric 
25540b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm8));
25550b57cec5SDimitry Andric 
25560b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
25570b57cec5SDimitry Andric     return MCDisassembler::Fail;
25580b57cec5SDimitry Andric 
25590b57cec5SDimitry Andric   // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
25600b57cec5SDimitry Andric   // so all predicates should be allowed.
25610b57cec5SDimitry Andric   if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
25620b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
25630b57cec5SDimitry Andric 
25640b57cec5SDimitry Andric   return S;
25650b57cec5SDimitry Andric }
25660b57cec5SDimitry Andric 
25670b57cec5SDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
256881ad6265SDimitry Andric                                          uint64_t Address,
256981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
25700b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 18, 2);
25710b57cec5SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 17, 1);
25720b57cec5SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 6, 3);
25730b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
25740b57cec5SDimitry Andric 
25750b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
25760b57cec5SDimitry Andric 
25770b57cec5SDimitry Andric   // This decoder is called from multiple location that do not check
25780b57cec5SDimitry Andric   // the full encoding is valid before they do.
25790b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 5, 1) != 0 ||
25800b57cec5SDimitry Andric       fieldFromInstruction(Insn, 16, 1) != 0 ||
25810b57cec5SDimitry Andric       fieldFromInstruction(Insn, 20, 8) != 0x10)
25820b57cec5SDimitry Andric     return MCDisassembler::Fail;
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   // imod == '01' --> UNPREDICTABLE
25850b57cec5SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
25860b57cec5SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
25870b57cec5SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
25880b57cec5SDimitry Andric 
25890b57cec5SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
25900b57cec5SDimitry Andric 
25910b57cec5SDimitry Andric   if (imod && M) {
25920b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS3p);
25930b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
25940b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
25950b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
25960b57cec5SDimitry Andric   } else if (imod && !M) {
25970b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS2p);
25980b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
25990b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
26000b57cec5SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
26010b57cec5SDimitry Andric   } else if (!imod && M) {
26020b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
26030b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26040b57cec5SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
26050b57cec5SDimitry Andric   } else {
26060b57cec5SDimitry Andric     // imod == '00' && M == '0' --> UNPREDICTABLE
26070b57cec5SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
26080b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26090b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
26100b57cec5SDimitry Andric   }
26110b57cec5SDimitry Andric 
26120b57cec5SDimitry Andric   return S;
26130b57cec5SDimitry Andric }
26140b57cec5SDimitry Andric 
26150b57cec5SDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
261681ad6265SDimitry Andric                                            uint64_t Address,
261781ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
26180b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 9, 2);
26190b57cec5SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 8, 1);
26200b57cec5SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 5, 3);
26210b57cec5SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
26220b57cec5SDimitry Andric 
26230b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26240b57cec5SDimitry Andric 
26250b57cec5SDimitry Andric   // imod == '01' --> UNPREDICTABLE
26260b57cec5SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
26270b57cec5SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
26280b57cec5SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
26290b57cec5SDimitry Andric 
26300b57cec5SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
26310b57cec5SDimitry Andric 
26320b57cec5SDimitry Andric   if (imod && M) {
26330b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS3p);
26340b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
26350b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
26360b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26370b57cec5SDimitry Andric   } else if (imod && !M) {
26380b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS2p);
26390b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
26400b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
26410b57cec5SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
26420b57cec5SDimitry Andric   } else if (!imod && M) {
26430b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2CPS1p);
26440b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
26450b57cec5SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
26460b57cec5SDimitry Andric   } else {
26470b57cec5SDimitry Andric     // imod == '00' && M == '0' --> this is a HINT instruction
26480b57cec5SDimitry Andric     int imm = fieldFromInstruction(Insn, 0, 8);
26490b57cec5SDimitry Andric     // HINT are defined only for immediate in [0..4]
26500b57cec5SDimitry Andric     if(imm > 4) return MCDisassembler::Fail;
26510b57cec5SDimitry Andric     Inst.setOpcode(ARM::t2HINT);
26520b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
26530b57cec5SDimitry Andric   }
26540b57cec5SDimitry Andric 
26550b57cec5SDimitry Andric   return S;
26560b57cec5SDimitry Andric }
26570b57cec5SDimitry Andric 
265881ad6265SDimitry Andric static DecodeStatus
265981ad6265SDimitry Andric DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
266081ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
26614824e7fdSDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
26624824e7fdSDimitry Andric 
26634824e7fdSDimitry Andric   unsigned Opcode = ARM::t2HINT;
26644824e7fdSDimitry Andric 
26654824e7fdSDimitry Andric   if (imm == 0x0D) {
26664824e7fdSDimitry Andric     Opcode = ARM::t2PACBTI;
26674824e7fdSDimitry Andric   } else if (imm == 0x1D) {
26684824e7fdSDimitry Andric     Opcode = ARM::t2PAC;
26694824e7fdSDimitry Andric   } else if (imm == 0x2D) {
26704824e7fdSDimitry Andric     Opcode = ARM::t2AUT;
26714824e7fdSDimitry Andric   } else if (imm == 0x0F) {
26724824e7fdSDimitry Andric     Opcode = ARM::t2BTI;
26734824e7fdSDimitry Andric   }
26744824e7fdSDimitry Andric 
26754824e7fdSDimitry Andric   Inst.setOpcode(Opcode);
26764824e7fdSDimitry Andric   if (Opcode == ARM::t2HINT) {
26774824e7fdSDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
26784824e7fdSDimitry Andric   }
26794824e7fdSDimitry Andric 
26804824e7fdSDimitry Andric   return MCDisassembler::Success;
26814824e7fdSDimitry Andric }
26824824e7fdSDimitry Andric 
26830b57cec5SDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
268481ad6265SDimitry Andric                                              uint64_t Address,
268581ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
26860b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26870b57cec5SDimitry Andric 
26880b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 8, 4);
26890b57cec5SDimitry Andric   unsigned imm = 0;
26900b57cec5SDimitry Andric 
26910b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
26920b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
26930b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
26940b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
26950b57cec5SDimitry Andric 
26960b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::t2MOVTi16)
26970b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
26980b57cec5SDimitry Andric       return MCDisassembler::Fail;
26990b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
27000b57cec5SDimitry Andric     return MCDisassembler::Fail;
27010b57cec5SDimitry Andric 
27020b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
27030b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
27040b57cec5SDimitry Andric 
27050b57cec5SDimitry Andric   return S;
27060b57cec5SDimitry Andric }
27070b57cec5SDimitry Andric 
27080b57cec5SDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
270981ad6265SDimitry Andric                                               uint64_t Address,
271081ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
27110b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27120b57cec5SDimitry Andric 
27130b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
27140b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
27150b57cec5SDimitry Andric   unsigned imm = 0;
27160b57cec5SDimitry Andric 
27170b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
27180b57cec5SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
27190b57cec5SDimitry Andric 
27200b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MOVTi16)
27210b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
27220b57cec5SDimitry Andric       return MCDisassembler::Fail;
27230b57cec5SDimitry Andric 
27240b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
27250b57cec5SDimitry Andric     return MCDisassembler::Fail;
27260b57cec5SDimitry Andric 
27270b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
27280b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
27290b57cec5SDimitry Andric 
27300b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
27310b57cec5SDimitry Andric     return MCDisassembler::Fail;
27320b57cec5SDimitry Andric 
27330b57cec5SDimitry Andric   return S;
27340b57cec5SDimitry Andric }
27350b57cec5SDimitry Andric 
27360b57cec5SDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
273781ad6265SDimitry Andric                                           uint64_t Address,
273881ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
27390b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27400b57cec5SDimitry Andric 
27410b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 16, 4);
27420b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 0, 4);
27430b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 8, 4);
27440b57cec5SDimitry Andric   unsigned Ra = fieldFromInstruction(Insn, 12, 4);
27450b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
27460b57cec5SDimitry Andric 
27470b57cec5SDimitry Andric   if (pred == 0xF)
27480b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
27490b57cec5SDimitry Andric 
27500b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
27510b57cec5SDimitry Andric     return MCDisassembler::Fail;
27520b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
27530b57cec5SDimitry Andric     return MCDisassembler::Fail;
27540b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
27550b57cec5SDimitry Andric     return MCDisassembler::Fail;
27560b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
27570b57cec5SDimitry Andric     return MCDisassembler::Fail;
27580b57cec5SDimitry Andric 
27590b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
27600b57cec5SDimitry Andric     return MCDisassembler::Fail;
27610b57cec5SDimitry Andric 
27620b57cec5SDimitry Andric   return S;
27630b57cec5SDimitry Andric }
27640b57cec5SDimitry Andric 
27650b57cec5SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
276681ad6265SDimitry Andric                                          uint64_t Address,
276781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
27680b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27690b57cec5SDimitry Andric 
27700b57cec5SDimitry Andric   unsigned Pred = fieldFromInstruction(Insn, 28, 4);
27710b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
27720b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
27730b57cec5SDimitry Andric 
27740b57cec5SDimitry Andric   if (Pred == 0xF)
27750b57cec5SDimitry Andric     return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
27760b57cec5SDimitry Andric 
27770b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
27780b57cec5SDimitry Andric     return MCDisassembler::Fail;
27790b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
27800b57cec5SDimitry Andric     return MCDisassembler::Fail;
27810b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
27820b57cec5SDimitry Andric     return MCDisassembler::Fail;
27830b57cec5SDimitry Andric 
27840b57cec5SDimitry Andric   return S;
27850b57cec5SDimitry Andric }
27860b57cec5SDimitry Andric 
27870b57cec5SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
278881ad6265SDimitry Andric                                             uint64_t Address,
278981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
27900b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
27910b57cec5SDimitry Andric 
27920b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 9, 1);
27930b57cec5SDimitry Andric 
27940b57cec5SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
27950b57cec5SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
27960b57cec5SDimitry Andric 
27970b57cec5SDimitry Andric   if (!FeatureBits[ARM::HasV8_1aOps] ||
27980b57cec5SDimitry Andric       !FeatureBits[ARM::HasV8Ops])
27990b57cec5SDimitry Andric     return MCDisassembler::Fail;
28000b57cec5SDimitry Andric 
28010b57cec5SDimitry Andric   // Decoder can be called from DecodeTST, which does not check the full
28020b57cec5SDimitry Andric   // encoding is valid.
28030b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
28040b57cec5SDimitry Andric       fieldFromInstruction(Insn, 4,4) != 0)
28050b57cec5SDimitry Andric     return MCDisassembler::Fail;
28060b57cec5SDimitry Andric   if (fieldFromInstruction(Insn, 10,10) != 0 ||
28070b57cec5SDimitry Andric       fieldFromInstruction(Insn, 0,4) != 0)
28080b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
28090b57cec5SDimitry Andric 
28100b57cec5SDimitry Andric   Inst.setOpcode(ARM::SETPAN);
28110b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
28120b57cec5SDimitry Andric 
28130b57cec5SDimitry Andric   return S;
28140b57cec5SDimitry Andric }
28150b57cec5SDimitry Andric 
28160b57cec5SDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
281781ad6265SDimitry Andric                                                uint64_t Address,
281881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
28190b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
28200b57cec5SDimitry Andric 
28210b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Val, 12, 1);
28220b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
28230b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
28240b57cec5SDimitry Andric 
28250b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
28260b57cec5SDimitry Andric     return MCDisassembler::Fail;
28270b57cec5SDimitry Andric 
28280b57cec5SDimitry Andric   if (!add) imm *= -1;
28290b57cec5SDimitry Andric   if (imm == 0 && !add) imm = INT32_MIN;
28300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
28310b57cec5SDimitry Andric   if (Rn == 15)
28320b57cec5SDimitry Andric     tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
28330b57cec5SDimitry Andric 
28340b57cec5SDimitry Andric   return S;
28350b57cec5SDimitry Andric }
28360b57cec5SDimitry Andric 
28370b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
283881ad6265SDimitry Andric                                            uint64_t Address,
283981ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
28400b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
28410b57cec5SDimitry Andric 
28420b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
28430b57cec5SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
28440b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
28450b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
28460b57cec5SDimitry Andric 
28470b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
28480b57cec5SDimitry Andric     return MCDisassembler::Fail;
28490b57cec5SDimitry Andric 
28500b57cec5SDimitry Andric   if (U)
28510b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
28520b57cec5SDimitry Andric   else
28530b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric   return S;
28560b57cec5SDimitry Andric }
28570b57cec5SDimitry Andric 
28580b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
285981ad6265SDimitry Andric                                                uint64_t Address,
286081ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
28610b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
28620b57cec5SDimitry Andric 
28630b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
28640b57cec5SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
28650b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
28660b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
28690b57cec5SDimitry Andric     return MCDisassembler::Fail;
28700b57cec5SDimitry Andric 
28710b57cec5SDimitry Andric   if (U)
28720b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm)));
28730b57cec5SDimitry Andric   else
28740b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm)));
28750b57cec5SDimitry Andric 
28760b57cec5SDimitry Andric   return S;
28770b57cec5SDimitry Andric }
28780b57cec5SDimitry Andric 
28790b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
288081ad6265SDimitry Andric                                            uint64_t Address,
288181ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
28820b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
28830b57cec5SDimitry Andric }
28840b57cec5SDimitry Andric 
288581ad6265SDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
288681ad6265SDimitry Andric                                          uint64_t Address,
288781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
28880b57cec5SDimitry Andric   DecodeStatus Status = MCDisassembler::Success;
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric   // Note the J1 and J2 values are from the encoded instruction.  So here
28910b57cec5SDimitry Andric   // change them to I1 and I2 values via as documented:
28920b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
28930b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
28940b57cec5SDimitry Andric   // and build the imm32 with one trailing zero as documented:
28950b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
28960b57cec5SDimitry Andric   unsigned S = fieldFromInstruction(Insn, 26, 1);
28970b57cec5SDimitry Andric   unsigned J1 = fieldFromInstruction(Insn, 13, 1);
28980b57cec5SDimitry Andric   unsigned J2 = fieldFromInstruction(Insn, 11, 1);
28990b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
29000b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
29010b57cec5SDimitry Andric   unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
29020b57cec5SDimitry Andric   unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
29030b57cec5SDimitry Andric   unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
29040b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
29050b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
29060b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
29070b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
29080b57cec5SDimitry Andric 
29090b57cec5SDimitry Andric   return Status;
29100b57cec5SDimitry Andric }
29110b57cec5SDimitry Andric 
291281ad6265SDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
291381ad6265SDimitry Andric                                                uint64_t Address,
291481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
29150b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29160b57cec5SDimitry Andric 
29170b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
29180b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
29190b57cec5SDimitry Andric 
29200b57cec5SDimitry Andric   if (pred == 0xF) {
29210b57cec5SDimitry Andric     Inst.setOpcode(ARM::BLXi);
29220b57cec5SDimitry Andric     imm |= fieldFromInstruction(Insn, 24, 1) << 1;
29230b57cec5SDimitry Andric     if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
29240b57cec5SDimitry Andric                                   true, 4, Inst, Decoder))
29250b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
29260b57cec5SDimitry Andric     return S;
29270b57cec5SDimitry Andric   }
29280b57cec5SDimitry Andric 
29290b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
29300b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
29310b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
2932fe6060f1SDimitry Andric 
2933fe6060f1SDimitry Andric   // We already have BL_pred for BL w/ predicate, no need to add addition
2934fe6060f1SDimitry Andric   // predicate opreands for BL
2935fe6060f1SDimitry Andric   if (Inst.getOpcode() != ARM::BL)
29360b57cec5SDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
29370b57cec5SDimitry Andric       return MCDisassembler::Fail;
29380b57cec5SDimitry Andric 
29390b57cec5SDimitry Andric   return S;
29400b57cec5SDimitry Andric }
29410b57cec5SDimitry Andric 
29420b57cec5SDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
294381ad6265SDimitry Andric                                            uint64_t Address,
294481ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
29450b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29460b57cec5SDimitry Andric 
29470b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
29480b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Val, 4, 2);
29490b57cec5SDimitry Andric 
29500b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
29510b57cec5SDimitry Andric     return MCDisassembler::Fail;
29520b57cec5SDimitry Andric   if (!align)
29530b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
29540b57cec5SDimitry Andric   else
29550b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(4 << align));
29560b57cec5SDimitry Andric 
29570b57cec5SDimitry Andric   return S;
29580b57cec5SDimitry Andric }
29590b57cec5SDimitry Andric 
29600b57cec5SDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
296181ad6265SDimitry Andric                                          uint64_t Address,
296281ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
29630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29640b57cec5SDimitry Andric 
29650b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
29660b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
29670b57cec5SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
29680b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
29690b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
29700b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
29710b57cec5SDimitry Andric 
29720b57cec5SDimitry Andric   // First output register
29730b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
29740b57cec5SDimitry Andric   case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
29750b57cec5SDimitry Andric   case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
29760b57cec5SDimitry Andric   case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
29770b57cec5SDimitry Andric   case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
29780b57cec5SDimitry Andric   case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
29790b57cec5SDimitry Andric   case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
29800b57cec5SDimitry Andric   case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
29810b57cec5SDimitry Andric   case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
29820b57cec5SDimitry Andric   case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
29830b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
29840b57cec5SDimitry Andric       return MCDisassembler::Fail;
29850b57cec5SDimitry Andric     break;
29860b57cec5SDimitry Andric   case ARM::VLD2b16:
29870b57cec5SDimitry Andric   case ARM::VLD2b32:
29880b57cec5SDimitry Andric   case ARM::VLD2b8:
29890b57cec5SDimitry Andric   case ARM::VLD2b16wb_fixed:
29900b57cec5SDimitry Andric   case ARM::VLD2b16wb_register:
29910b57cec5SDimitry Andric   case ARM::VLD2b32wb_fixed:
29920b57cec5SDimitry Andric   case ARM::VLD2b32wb_register:
29930b57cec5SDimitry Andric   case ARM::VLD2b8wb_fixed:
29940b57cec5SDimitry Andric   case ARM::VLD2b8wb_register:
29950b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
29960b57cec5SDimitry Andric       return MCDisassembler::Fail;
29970b57cec5SDimitry Andric     break;
29980b57cec5SDimitry Andric   default:
29990b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
30000b57cec5SDimitry Andric       return MCDisassembler::Fail;
30010b57cec5SDimitry Andric   }
30020b57cec5SDimitry Andric 
30030b57cec5SDimitry Andric   // Second output register
30040b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
30050b57cec5SDimitry Andric     case ARM::VLD3d8:
30060b57cec5SDimitry Andric     case ARM::VLD3d16:
30070b57cec5SDimitry Andric     case ARM::VLD3d32:
30080b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
30090b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
30100b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
30110b57cec5SDimitry Andric     case ARM::VLD4d8:
30120b57cec5SDimitry Andric     case ARM::VLD4d16:
30130b57cec5SDimitry Andric     case ARM::VLD4d32:
30140b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
30150b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
30160b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
30170b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
30180b57cec5SDimitry Andric         return MCDisassembler::Fail;
30190b57cec5SDimitry Andric       break;
30200b57cec5SDimitry Andric     case ARM::VLD3q8:
30210b57cec5SDimitry Andric     case ARM::VLD3q16:
30220b57cec5SDimitry Andric     case ARM::VLD3q32:
30230b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
30240b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
30250b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
30260b57cec5SDimitry Andric     case ARM::VLD4q8:
30270b57cec5SDimitry Andric     case ARM::VLD4q16:
30280b57cec5SDimitry Andric     case ARM::VLD4q32:
30290b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
30300b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
30310b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
30320b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
30330b57cec5SDimitry Andric         return MCDisassembler::Fail;
30340b57cec5SDimitry Andric       break;
30350b57cec5SDimitry Andric     default:
30360b57cec5SDimitry Andric       break;
30370b57cec5SDimitry Andric   }
30380b57cec5SDimitry Andric 
30390b57cec5SDimitry Andric   // Third output register
30400b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
30410b57cec5SDimitry Andric     case ARM::VLD3d8:
30420b57cec5SDimitry Andric     case ARM::VLD3d16:
30430b57cec5SDimitry Andric     case ARM::VLD3d32:
30440b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
30450b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
30460b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
30470b57cec5SDimitry Andric     case ARM::VLD4d8:
30480b57cec5SDimitry Andric     case ARM::VLD4d16:
30490b57cec5SDimitry Andric     case ARM::VLD4d32:
30500b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
30510b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
30520b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
30530b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
30540b57cec5SDimitry Andric         return MCDisassembler::Fail;
30550b57cec5SDimitry Andric       break;
30560b57cec5SDimitry Andric     case ARM::VLD3q8:
30570b57cec5SDimitry Andric     case ARM::VLD3q16:
30580b57cec5SDimitry Andric     case ARM::VLD3q32:
30590b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
30600b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
30610b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
30620b57cec5SDimitry Andric     case ARM::VLD4q8:
30630b57cec5SDimitry Andric     case ARM::VLD4q16:
30640b57cec5SDimitry Andric     case ARM::VLD4q32:
30650b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
30660b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
30670b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
30680b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
30690b57cec5SDimitry Andric         return MCDisassembler::Fail;
30700b57cec5SDimitry Andric       break;
30710b57cec5SDimitry Andric     default:
30720b57cec5SDimitry Andric       break;
30730b57cec5SDimitry Andric   }
30740b57cec5SDimitry Andric 
30750b57cec5SDimitry Andric   // Fourth output register
30760b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
30770b57cec5SDimitry Andric     case ARM::VLD4d8:
30780b57cec5SDimitry Andric     case ARM::VLD4d16:
30790b57cec5SDimitry Andric     case ARM::VLD4d32:
30800b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
30810b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
30820b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
30830b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
30840b57cec5SDimitry Andric         return MCDisassembler::Fail;
30850b57cec5SDimitry Andric       break;
30860b57cec5SDimitry Andric     case ARM::VLD4q8:
30870b57cec5SDimitry Andric     case ARM::VLD4q16:
30880b57cec5SDimitry Andric     case ARM::VLD4q32:
30890b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
30900b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
30910b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
30920b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
30930b57cec5SDimitry Andric         return MCDisassembler::Fail;
30940b57cec5SDimitry Andric       break;
30950b57cec5SDimitry Andric     default:
30960b57cec5SDimitry Andric       break;
30970b57cec5SDimitry Andric   }
30980b57cec5SDimitry Andric 
30990b57cec5SDimitry Andric   // Writeback operand
31000b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
31010b57cec5SDimitry Andric     case ARM::VLD1d8wb_fixed:
31020b57cec5SDimitry Andric     case ARM::VLD1d16wb_fixed:
31030b57cec5SDimitry Andric     case ARM::VLD1d32wb_fixed:
31040b57cec5SDimitry Andric     case ARM::VLD1d64wb_fixed:
31050b57cec5SDimitry Andric     case ARM::VLD1d8wb_register:
31060b57cec5SDimitry Andric     case ARM::VLD1d16wb_register:
31070b57cec5SDimitry Andric     case ARM::VLD1d32wb_register:
31080b57cec5SDimitry Andric     case ARM::VLD1d64wb_register:
31090b57cec5SDimitry Andric     case ARM::VLD1q8wb_fixed:
31100b57cec5SDimitry Andric     case ARM::VLD1q16wb_fixed:
31110b57cec5SDimitry Andric     case ARM::VLD1q32wb_fixed:
31120b57cec5SDimitry Andric     case ARM::VLD1q64wb_fixed:
31130b57cec5SDimitry Andric     case ARM::VLD1q8wb_register:
31140b57cec5SDimitry Andric     case ARM::VLD1q16wb_register:
31150b57cec5SDimitry Andric     case ARM::VLD1q32wb_register:
31160b57cec5SDimitry Andric     case ARM::VLD1q64wb_register:
31170b57cec5SDimitry Andric     case ARM::VLD1d8Twb_fixed:
31180b57cec5SDimitry Andric     case ARM::VLD1d8Twb_register:
31190b57cec5SDimitry Andric     case ARM::VLD1d16Twb_fixed:
31200b57cec5SDimitry Andric     case ARM::VLD1d16Twb_register:
31210b57cec5SDimitry Andric     case ARM::VLD1d32Twb_fixed:
31220b57cec5SDimitry Andric     case ARM::VLD1d32Twb_register:
31230b57cec5SDimitry Andric     case ARM::VLD1d64Twb_fixed:
31240b57cec5SDimitry Andric     case ARM::VLD1d64Twb_register:
31250b57cec5SDimitry Andric     case ARM::VLD1d8Qwb_fixed:
31260b57cec5SDimitry Andric     case ARM::VLD1d8Qwb_register:
31270b57cec5SDimitry Andric     case ARM::VLD1d16Qwb_fixed:
31280b57cec5SDimitry Andric     case ARM::VLD1d16Qwb_register:
31290b57cec5SDimitry Andric     case ARM::VLD1d32Qwb_fixed:
31300b57cec5SDimitry Andric     case ARM::VLD1d32Qwb_register:
31310b57cec5SDimitry Andric     case ARM::VLD1d64Qwb_fixed:
31320b57cec5SDimitry Andric     case ARM::VLD1d64Qwb_register:
31330b57cec5SDimitry Andric     case ARM::VLD2d8wb_fixed:
31340b57cec5SDimitry Andric     case ARM::VLD2d16wb_fixed:
31350b57cec5SDimitry Andric     case ARM::VLD2d32wb_fixed:
31360b57cec5SDimitry Andric     case ARM::VLD2q8wb_fixed:
31370b57cec5SDimitry Andric     case ARM::VLD2q16wb_fixed:
31380b57cec5SDimitry Andric     case ARM::VLD2q32wb_fixed:
31390b57cec5SDimitry Andric     case ARM::VLD2d8wb_register:
31400b57cec5SDimitry Andric     case ARM::VLD2d16wb_register:
31410b57cec5SDimitry Andric     case ARM::VLD2d32wb_register:
31420b57cec5SDimitry Andric     case ARM::VLD2q8wb_register:
31430b57cec5SDimitry Andric     case ARM::VLD2q16wb_register:
31440b57cec5SDimitry Andric     case ARM::VLD2q32wb_register:
31450b57cec5SDimitry Andric     case ARM::VLD2b8wb_fixed:
31460b57cec5SDimitry Andric     case ARM::VLD2b16wb_fixed:
31470b57cec5SDimitry Andric     case ARM::VLD2b32wb_fixed:
31480b57cec5SDimitry Andric     case ARM::VLD2b8wb_register:
31490b57cec5SDimitry Andric     case ARM::VLD2b16wb_register:
31500b57cec5SDimitry Andric     case ARM::VLD2b32wb_register:
31510b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
31520b57cec5SDimitry Andric       break;
31530b57cec5SDimitry Andric     case ARM::VLD3d8_UPD:
31540b57cec5SDimitry Andric     case ARM::VLD3d16_UPD:
31550b57cec5SDimitry Andric     case ARM::VLD3d32_UPD:
31560b57cec5SDimitry Andric     case ARM::VLD3q8_UPD:
31570b57cec5SDimitry Andric     case ARM::VLD3q16_UPD:
31580b57cec5SDimitry Andric     case ARM::VLD3q32_UPD:
31590b57cec5SDimitry Andric     case ARM::VLD4d8_UPD:
31600b57cec5SDimitry Andric     case ARM::VLD4d16_UPD:
31610b57cec5SDimitry Andric     case ARM::VLD4d32_UPD:
31620b57cec5SDimitry Andric     case ARM::VLD4q8_UPD:
31630b57cec5SDimitry Andric     case ARM::VLD4q16_UPD:
31640b57cec5SDimitry Andric     case ARM::VLD4q32_UPD:
31650b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
31660b57cec5SDimitry Andric         return MCDisassembler::Fail;
31670b57cec5SDimitry Andric       break;
31680b57cec5SDimitry Andric     default:
31690b57cec5SDimitry Andric       break;
31700b57cec5SDimitry Andric   }
31710b57cec5SDimitry Andric 
31720b57cec5SDimitry Andric   // AddrMode6 Base (register+alignment)
31730b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
31740b57cec5SDimitry Andric     return MCDisassembler::Fail;
31750b57cec5SDimitry Andric 
31760b57cec5SDimitry Andric   // AddrMode6 Offset (register)
31770b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
31780b57cec5SDimitry Andric   default:
31790b57cec5SDimitry Andric     // The below have been updated to have explicit am6offset split
31800b57cec5SDimitry Andric     // between fixed and register offset. For those instructions not
31810b57cec5SDimitry Andric     // yet updated, we need to add an additional reg0 operand for the
31820b57cec5SDimitry Andric     // fixed variant.
31830b57cec5SDimitry Andric     //
31840b57cec5SDimitry Andric     // The fixed offset encodes as Rm == 0xd, so we check for that.
31850b57cec5SDimitry Andric     if (Rm == 0xd) {
31860b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
31870b57cec5SDimitry Andric       break;
31880b57cec5SDimitry Andric     }
31890b57cec5SDimitry Andric     // Fall through to handle the register offset variant.
3190bdd1243dSDimitry Andric     [[fallthrough]];
31910b57cec5SDimitry Andric   case ARM::VLD1d8wb_fixed:
31920b57cec5SDimitry Andric   case ARM::VLD1d16wb_fixed:
31930b57cec5SDimitry Andric   case ARM::VLD1d32wb_fixed:
31940b57cec5SDimitry Andric   case ARM::VLD1d64wb_fixed:
31950b57cec5SDimitry Andric   case ARM::VLD1d8Twb_fixed:
31960b57cec5SDimitry Andric   case ARM::VLD1d16Twb_fixed:
31970b57cec5SDimitry Andric   case ARM::VLD1d32Twb_fixed:
31980b57cec5SDimitry Andric   case ARM::VLD1d64Twb_fixed:
31990b57cec5SDimitry Andric   case ARM::VLD1d8Qwb_fixed:
32000b57cec5SDimitry Andric   case ARM::VLD1d16Qwb_fixed:
32010b57cec5SDimitry Andric   case ARM::VLD1d32Qwb_fixed:
32020b57cec5SDimitry Andric   case ARM::VLD1d64Qwb_fixed:
32030b57cec5SDimitry Andric   case ARM::VLD1d8wb_register:
32040b57cec5SDimitry Andric   case ARM::VLD1d16wb_register:
32050b57cec5SDimitry Andric   case ARM::VLD1d32wb_register:
32060b57cec5SDimitry Andric   case ARM::VLD1d64wb_register:
32070b57cec5SDimitry Andric   case ARM::VLD1q8wb_fixed:
32080b57cec5SDimitry Andric   case ARM::VLD1q16wb_fixed:
32090b57cec5SDimitry Andric   case ARM::VLD1q32wb_fixed:
32100b57cec5SDimitry Andric   case ARM::VLD1q64wb_fixed:
32110b57cec5SDimitry Andric   case ARM::VLD1q8wb_register:
32120b57cec5SDimitry Andric   case ARM::VLD1q16wb_register:
32130b57cec5SDimitry Andric   case ARM::VLD1q32wb_register:
32140b57cec5SDimitry Andric   case ARM::VLD1q64wb_register:
32150b57cec5SDimitry Andric     // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
32160b57cec5SDimitry Andric     // variant encodes Rm == 0xf. Anything else is a register offset post-
32170b57cec5SDimitry Andric     // increment and we need to add the register operand to the instruction.
32180b57cec5SDimitry Andric     if (Rm != 0xD && Rm != 0xF &&
32190b57cec5SDimitry Andric         !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
32200b57cec5SDimitry Andric       return MCDisassembler::Fail;
32210b57cec5SDimitry Andric     break;
32220b57cec5SDimitry Andric   case ARM::VLD2d8wb_fixed:
32230b57cec5SDimitry Andric   case ARM::VLD2d16wb_fixed:
32240b57cec5SDimitry Andric   case ARM::VLD2d32wb_fixed:
32250b57cec5SDimitry Andric   case ARM::VLD2b8wb_fixed:
32260b57cec5SDimitry Andric   case ARM::VLD2b16wb_fixed:
32270b57cec5SDimitry Andric   case ARM::VLD2b32wb_fixed:
32280b57cec5SDimitry Andric   case ARM::VLD2q8wb_fixed:
32290b57cec5SDimitry Andric   case ARM::VLD2q16wb_fixed:
32300b57cec5SDimitry Andric   case ARM::VLD2q32wb_fixed:
32310b57cec5SDimitry Andric     break;
32320b57cec5SDimitry Andric   }
32330b57cec5SDimitry Andric 
32340b57cec5SDimitry Andric   return S;
32350b57cec5SDimitry Andric }
32360b57cec5SDimitry Andric 
32370b57cec5SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
323881ad6265SDimitry Andric                                             uint64_t Address,
323981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32400b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
32410b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
32420b57cec5SDimitry Andric   if (type == 6 && (align & 2)) return MCDisassembler::Fail;
32430b57cec5SDimitry Andric   if (type == 7 && (align & 2)) return MCDisassembler::Fail;
32440b57cec5SDimitry Andric   if (type == 10 && align == 3) return MCDisassembler::Fail;
32450b57cec5SDimitry Andric 
32460b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32470b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32480b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32490b57cec5SDimitry Andric }
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
325281ad6265SDimitry Andric                                             uint64_t Address,
325381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32540b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
32550b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
32560b57cec5SDimitry Andric 
32570b57cec5SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
32580b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
32590b57cec5SDimitry Andric   if (type == 8 && align == 3) return MCDisassembler::Fail;
32600b57cec5SDimitry Andric   if (type == 9 && align == 3) return MCDisassembler::Fail;
32610b57cec5SDimitry Andric 
32620b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32630b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32640b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32650b57cec5SDimitry Andric }
32660b57cec5SDimitry Andric 
32670b57cec5SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
326881ad6265SDimitry Andric                                             uint64_t Address,
326981ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32700b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
32710b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
32720b57cec5SDimitry Andric 
32730b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
32740b57cec5SDimitry Andric   if (align & 2) return MCDisassembler::Fail;
32750b57cec5SDimitry Andric 
32760b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32770b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32780b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32790b57cec5SDimitry Andric }
32800b57cec5SDimitry Andric 
32810b57cec5SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
328281ad6265SDimitry Andric                                             uint64_t Address,
328381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
32840b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
32850b57cec5SDimitry Andric   if (size == 3) return MCDisassembler::Fail;
32860b57cec5SDimitry Andric 
32870b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
32880b57cec5SDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
32890b57cec5SDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
32900b57cec5SDimitry Andric }
32910b57cec5SDimitry Andric 
32920b57cec5SDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
329381ad6265SDimitry Andric                                          uint64_t Address,
329481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
32950b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
32960b57cec5SDimitry Andric 
32970b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
32980b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
32990b57cec5SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
33000b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
33010b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
33020b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric   // Writeback Operand
33050b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
33060b57cec5SDimitry Andric     case ARM::VST1d8wb_fixed:
33070b57cec5SDimitry Andric     case ARM::VST1d16wb_fixed:
33080b57cec5SDimitry Andric     case ARM::VST1d32wb_fixed:
33090b57cec5SDimitry Andric     case ARM::VST1d64wb_fixed:
33100b57cec5SDimitry Andric     case ARM::VST1d8wb_register:
33110b57cec5SDimitry Andric     case ARM::VST1d16wb_register:
33120b57cec5SDimitry Andric     case ARM::VST1d32wb_register:
33130b57cec5SDimitry Andric     case ARM::VST1d64wb_register:
33140b57cec5SDimitry Andric     case ARM::VST1q8wb_fixed:
33150b57cec5SDimitry Andric     case ARM::VST1q16wb_fixed:
33160b57cec5SDimitry Andric     case ARM::VST1q32wb_fixed:
33170b57cec5SDimitry Andric     case ARM::VST1q64wb_fixed:
33180b57cec5SDimitry Andric     case ARM::VST1q8wb_register:
33190b57cec5SDimitry Andric     case ARM::VST1q16wb_register:
33200b57cec5SDimitry Andric     case ARM::VST1q32wb_register:
33210b57cec5SDimitry Andric     case ARM::VST1q64wb_register:
33220b57cec5SDimitry Andric     case ARM::VST1d8Twb_fixed:
33230b57cec5SDimitry Andric     case ARM::VST1d16Twb_fixed:
33240b57cec5SDimitry Andric     case ARM::VST1d32Twb_fixed:
33250b57cec5SDimitry Andric     case ARM::VST1d64Twb_fixed:
33260b57cec5SDimitry Andric     case ARM::VST1d8Twb_register:
33270b57cec5SDimitry Andric     case ARM::VST1d16Twb_register:
33280b57cec5SDimitry Andric     case ARM::VST1d32Twb_register:
33290b57cec5SDimitry Andric     case ARM::VST1d64Twb_register:
33300b57cec5SDimitry Andric     case ARM::VST1d8Qwb_fixed:
33310b57cec5SDimitry Andric     case ARM::VST1d16Qwb_fixed:
33320b57cec5SDimitry Andric     case ARM::VST1d32Qwb_fixed:
33330b57cec5SDimitry Andric     case ARM::VST1d64Qwb_fixed:
33340b57cec5SDimitry Andric     case ARM::VST1d8Qwb_register:
33350b57cec5SDimitry Andric     case ARM::VST1d16Qwb_register:
33360b57cec5SDimitry Andric     case ARM::VST1d32Qwb_register:
33370b57cec5SDimitry Andric     case ARM::VST1d64Qwb_register:
33380b57cec5SDimitry Andric     case ARM::VST2d8wb_fixed:
33390b57cec5SDimitry Andric     case ARM::VST2d16wb_fixed:
33400b57cec5SDimitry Andric     case ARM::VST2d32wb_fixed:
33410b57cec5SDimitry Andric     case ARM::VST2d8wb_register:
33420b57cec5SDimitry Andric     case ARM::VST2d16wb_register:
33430b57cec5SDimitry Andric     case ARM::VST2d32wb_register:
33440b57cec5SDimitry Andric     case ARM::VST2q8wb_fixed:
33450b57cec5SDimitry Andric     case ARM::VST2q16wb_fixed:
33460b57cec5SDimitry Andric     case ARM::VST2q32wb_fixed:
33470b57cec5SDimitry Andric     case ARM::VST2q8wb_register:
33480b57cec5SDimitry Andric     case ARM::VST2q16wb_register:
33490b57cec5SDimitry Andric     case ARM::VST2q32wb_register:
33500b57cec5SDimitry Andric     case ARM::VST2b8wb_fixed:
33510b57cec5SDimitry Andric     case ARM::VST2b16wb_fixed:
33520b57cec5SDimitry Andric     case ARM::VST2b32wb_fixed:
33530b57cec5SDimitry Andric     case ARM::VST2b8wb_register:
33540b57cec5SDimitry Andric     case ARM::VST2b16wb_register:
33550b57cec5SDimitry Andric     case ARM::VST2b32wb_register:
33560b57cec5SDimitry Andric       if (Rm == 0xF)
33570b57cec5SDimitry Andric         return MCDisassembler::Fail;
33580b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
33590b57cec5SDimitry Andric       break;
33600b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
33610b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
33620b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
33630b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
33640b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
33650b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
33660b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
33670b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
33680b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
33690b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
33700b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
33710b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
33720b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
33730b57cec5SDimitry Andric         return MCDisassembler::Fail;
33740b57cec5SDimitry Andric       break;
33750b57cec5SDimitry Andric     default:
33760b57cec5SDimitry Andric       break;
33770b57cec5SDimitry Andric   }
33780b57cec5SDimitry Andric 
33790b57cec5SDimitry Andric   // AddrMode6 Base (register+alignment)
33800b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
33810b57cec5SDimitry Andric     return MCDisassembler::Fail;
33820b57cec5SDimitry Andric 
33830b57cec5SDimitry Andric   // AddrMode6 Offset (register)
33840b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
33850b57cec5SDimitry Andric     default:
33860b57cec5SDimitry Andric       if (Rm == 0xD)
33870b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createReg(0));
33880b57cec5SDimitry Andric       else if (Rm != 0xF) {
33890b57cec5SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
33900b57cec5SDimitry Andric           return MCDisassembler::Fail;
33910b57cec5SDimitry Andric       }
33920b57cec5SDimitry Andric       break;
33930b57cec5SDimitry Andric     case ARM::VST1d8wb_fixed:
33940b57cec5SDimitry Andric     case ARM::VST1d16wb_fixed:
33950b57cec5SDimitry Andric     case ARM::VST1d32wb_fixed:
33960b57cec5SDimitry Andric     case ARM::VST1d64wb_fixed:
33970b57cec5SDimitry Andric     case ARM::VST1q8wb_fixed:
33980b57cec5SDimitry Andric     case ARM::VST1q16wb_fixed:
33990b57cec5SDimitry Andric     case ARM::VST1q32wb_fixed:
34000b57cec5SDimitry Andric     case ARM::VST1q64wb_fixed:
34010b57cec5SDimitry Andric     case ARM::VST1d8Twb_fixed:
34020b57cec5SDimitry Andric     case ARM::VST1d16Twb_fixed:
34030b57cec5SDimitry Andric     case ARM::VST1d32Twb_fixed:
34040b57cec5SDimitry Andric     case ARM::VST1d64Twb_fixed:
34050b57cec5SDimitry Andric     case ARM::VST1d8Qwb_fixed:
34060b57cec5SDimitry Andric     case ARM::VST1d16Qwb_fixed:
34070b57cec5SDimitry Andric     case ARM::VST1d32Qwb_fixed:
34080b57cec5SDimitry Andric     case ARM::VST1d64Qwb_fixed:
34090b57cec5SDimitry Andric     case ARM::VST2d8wb_fixed:
34100b57cec5SDimitry Andric     case ARM::VST2d16wb_fixed:
34110b57cec5SDimitry Andric     case ARM::VST2d32wb_fixed:
34120b57cec5SDimitry Andric     case ARM::VST2q8wb_fixed:
34130b57cec5SDimitry Andric     case ARM::VST2q16wb_fixed:
34140b57cec5SDimitry Andric     case ARM::VST2q32wb_fixed:
34150b57cec5SDimitry Andric     case ARM::VST2b8wb_fixed:
34160b57cec5SDimitry Andric     case ARM::VST2b16wb_fixed:
34170b57cec5SDimitry Andric     case ARM::VST2b32wb_fixed:
34180b57cec5SDimitry Andric       break;
34190b57cec5SDimitry Andric   }
34200b57cec5SDimitry Andric 
34210b57cec5SDimitry Andric   // First input register
34220b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
34230b57cec5SDimitry Andric   case ARM::VST1q16:
34240b57cec5SDimitry Andric   case ARM::VST1q32:
34250b57cec5SDimitry Andric   case ARM::VST1q64:
34260b57cec5SDimitry Andric   case ARM::VST1q8:
34270b57cec5SDimitry Andric   case ARM::VST1q16wb_fixed:
34280b57cec5SDimitry Andric   case ARM::VST1q16wb_register:
34290b57cec5SDimitry Andric   case ARM::VST1q32wb_fixed:
34300b57cec5SDimitry Andric   case ARM::VST1q32wb_register:
34310b57cec5SDimitry Andric   case ARM::VST1q64wb_fixed:
34320b57cec5SDimitry Andric   case ARM::VST1q64wb_register:
34330b57cec5SDimitry Andric   case ARM::VST1q8wb_fixed:
34340b57cec5SDimitry Andric   case ARM::VST1q8wb_register:
34350b57cec5SDimitry Andric   case ARM::VST2d16:
34360b57cec5SDimitry Andric   case ARM::VST2d32:
34370b57cec5SDimitry Andric   case ARM::VST2d8:
34380b57cec5SDimitry Andric   case ARM::VST2d16wb_fixed:
34390b57cec5SDimitry Andric   case ARM::VST2d16wb_register:
34400b57cec5SDimitry Andric   case ARM::VST2d32wb_fixed:
34410b57cec5SDimitry Andric   case ARM::VST2d32wb_register:
34420b57cec5SDimitry Andric   case ARM::VST2d8wb_fixed:
34430b57cec5SDimitry Andric   case ARM::VST2d8wb_register:
34440b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
34450b57cec5SDimitry Andric       return MCDisassembler::Fail;
34460b57cec5SDimitry Andric     break;
34470b57cec5SDimitry Andric   case ARM::VST2b16:
34480b57cec5SDimitry Andric   case ARM::VST2b32:
34490b57cec5SDimitry Andric   case ARM::VST2b8:
34500b57cec5SDimitry Andric   case ARM::VST2b16wb_fixed:
34510b57cec5SDimitry Andric   case ARM::VST2b16wb_register:
34520b57cec5SDimitry Andric   case ARM::VST2b32wb_fixed:
34530b57cec5SDimitry Andric   case ARM::VST2b32wb_register:
34540b57cec5SDimitry Andric   case ARM::VST2b8wb_fixed:
34550b57cec5SDimitry Andric   case ARM::VST2b8wb_register:
34560b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
34570b57cec5SDimitry Andric       return MCDisassembler::Fail;
34580b57cec5SDimitry Andric     break;
34590b57cec5SDimitry Andric   default:
34600b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
34610b57cec5SDimitry Andric       return MCDisassembler::Fail;
34620b57cec5SDimitry Andric   }
34630b57cec5SDimitry Andric 
34640b57cec5SDimitry Andric   // Second input register
34650b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
34660b57cec5SDimitry Andric     case ARM::VST3d8:
34670b57cec5SDimitry Andric     case ARM::VST3d16:
34680b57cec5SDimitry Andric     case ARM::VST3d32:
34690b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
34700b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
34710b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
34720b57cec5SDimitry Andric     case ARM::VST4d8:
34730b57cec5SDimitry Andric     case ARM::VST4d16:
34740b57cec5SDimitry Andric     case ARM::VST4d32:
34750b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
34760b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
34770b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
34780b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
34790b57cec5SDimitry Andric         return MCDisassembler::Fail;
34800b57cec5SDimitry Andric       break;
34810b57cec5SDimitry Andric     case ARM::VST3q8:
34820b57cec5SDimitry Andric     case ARM::VST3q16:
34830b57cec5SDimitry Andric     case ARM::VST3q32:
34840b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
34850b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
34860b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
34870b57cec5SDimitry Andric     case ARM::VST4q8:
34880b57cec5SDimitry Andric     case ARM::VST4q16:
34890b57cec5SDimitry Andric     case ARM::VST4q32:
34900b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
34910b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
34920b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
34930b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
34940b57cec5SDimitry Andric         return MCDisassembler::Fail;
34950b57cec5SDimitry Andric       break;
34960b57cec5SDimitry Andric     default:
34970b57cec5SDimitry Andric       break;
34980b57cec5SDimitry Andric   }
34990b57cec5SDimitry Andric 
35000b57cec5SDimitry Andric   // Third input register
35010b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
35020b57cec5SDimitry Andric     case ARM::VST3d8:
35030b57cec5SDimitry Andric     case ARM::VST3d16:
35040b57cec5SDimitry Andric     case ARM::VST3d32:
35050b57cec5SDimitry Andric     case ARM::VST3d8_UPD:
35060b57cec5SDimitry Andric     case ARM::VST3d16_UPD:
35070b57cec5SDimitry Andric     case ARM::VST3d32_UPD:
35080b57cec5SDimitry Andric     case ARM::VST4d8:
35090b57cec5SDimitry Andric     case ARM::VST4d16:
35100b57cec5SDimitry Andric     case ARM::VST4d32:
35110b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
35120b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
35130b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
35140b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
35150b57cec5SDimitry Andric         return MCDisassembler::Fail;
35160b57cec5SDimitry Andric       break;
35170b57cec5SDimitry Andric     case ARM::VST3q8:
35180b57cec5SDimitry Andric     case ARM::VST3q16:
35190b57cec5SDimitry Andric     case ARM::VST3q32:
35200b57cec5SDimitry Andric     case ARM::VST3q8_UPD:
35210b57cec5SDimitry Andric     case ARM::VST3q16_UPD:
35220b57cec5SDimitry Andric     case ARM::VST3q32_UPD:
35230b57cec5SDimitry Andric     case ARM::VST4q8:
35240b57cec5SDimitry Andric     case ARM::VST4q16:
35250b57cec5SDimitry Andric     case ARM::VST4q32:
35260b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
35270b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
35280b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
35290b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
35300b57cec5SDimitry Andric         return MCDisassembler::Fail;
35310b57cec5SDimitry Andric       break;
35320b57cec5SDimitry Andric     default:
35330b57cec5SDimitry Andric       break;
35340b57cec5SDimitry Andric   }
35350b57cec5SDimitry Andric 
35360b57cec5SDimitry Andric   // Fourth input register
35370b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
35380b57cec5SDimitry Andric     case ARM::VST4d8:
35390b57cec5SDimitry Andric     case ARM::VST4d16:
35400b57cec5SDimitry Andric     case ARM::VST4d32:
35410b57cec5SDimitry Andric     case ARM::VST4d8_UPD:
35420b57cec5SDimitry Andric     case ARM::VST4d16_UPD:
35430b57cec5SDimitry Andric     case ARM::VST4d32_UPD:
35440b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
35450b57cec5SDimitry Andric         return MCDisassembler::Fail;
35460b57cec5SDimitry Andric       break;
35470b57cec5SDimitry Andric     case ARM::VST4q8:
35480b57cec5SDimitry Andric     case ARM::VST4q16:
35490b57cec5SDimitry Andric     case ARM::VST4q32:
35500b57cec5SDimitry Andric     case ARM::VST4q8_UPD:
35510b57cec5SDimitry Andric     case ARM::VST4q16_UPD:
35520b57cec5SDimitry Andric     case ARM::VST4q32_UPD:
35530b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
35540b57cec5SDimitry Andric         return MCDisassembler::Fail;
35550b57cec5SDimitry Andric       break;
35560b57cec5SDimitry Andric     default:
35570b57cec5SDimitry Andric       break;
35580b57cec5SDimitry Andric   }
35590b57cec5SDimitry Andric 
35600b57cec5SDimitry Andric   return S;
35610b57cec5SDimitry Andric }
35620b57cec5SDimitry Andric 
35630b57cec5SDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
356481ad6265SDimitry Andric                                              uint64_t Address,
356581ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
35660b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
35670b57cec5SDimitry Andric 
35680b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
35690b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
35700b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
35710b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
35720b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
35730b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
35740b57cec5SDimitry Andric 
35750b57cec5SDimitry Andric   if (size == 0 && align == 1)
35760b57cec5SDimitry Andric     return MCDisassembler::Fail;
35770b57cec5SDimitry Andric   align *= (1 << size);
35780b57cec5SDimitry Andric 
35790b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
35800b57cec5SDimitry Andric   case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
35810b57cec5SDimitry Andric   case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
35820b57cec5SDimitry Andric   case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
35830b57cec5SDimitry Andric   case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
35840b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
35850b57cec5SDimitry Andric       return MCDisassembler::Fail;
35860b57cec5SDimitry Andric     break;
35870b57cec5SDimitry Andric   default:
35880b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
35890b57cec5SDimitry Andric       return MCDisassembler::Fail;
35900b57cec5SDimitry Andric     break;
35910b57cec5SDimitry Andric   }
35920b57cec5SDimitry Andric   if (Rm != 0xF) {
35930b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
35940b57cec5SDimitry Andric       return MCDisassembler::Fail;
35950b57cec5SDimitry Andric   }
35960b57cec5SDimitry Andric 
35970b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
35980b57cec5SDimitry Andric     return MCDisassembler::Fail;
35990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
36000b57cec5SDimitry Andric 
36010b57cec5SDimitry Andric   // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
36020b57cec5SDimitry Andric   // variant encodes Rm == 0xf. Anything else is a register offset post-
36030b57cec5SDimitry Andric   // increment and we need to add the register operand to the instruction.
36040b57cec5SDimitry Andric   if (Rm != 0xD && Rm != 0xF &&
36050b57cec5SDimitry Andric       !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
36060b57cec5SDimitry Andric     return MCDisassembler::Fail;
36070b57cec5SDimitry Andric 
36080b57cec5SDimitry Andric   return S;
36090b57cec5SDimitry Andric }
36100b57cec5SDimitry Andric 
36110b57cec5SDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
361281ad6265SDimitry Andric                                              uint64_t Address,
361381ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
36140b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36150b57cec5SDimitry Andric 
36160b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
36170b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
36180b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
36190b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
36200b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
36210b57cec5SDimitry Andric   unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
36220b57cec5SDimitry Andric   align *= 2*size;
36230b57cec5SDimitry Andric 
36240b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
36250b57cec5SDimitry Andric   case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
36260b57cec5SDimitry Andric   case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
36270b57cec5SDimitry Andric   case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
36280b57cec5SDimitry Andric   case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
36290b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
36300b57cec5SDimitry Andric       return MCDisassembler::Fail;
36310b57cec5SDimitry Andric     break;
36320b57cec5SDimitry Andric   case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
36330b57cec5SDimitry Andric   case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
36340b57cec5SDimitry Andric   case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
36350b57cec5SDimitry Andric   case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
36360b57cec5SDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
36370b57cec5SDimitry Andric       return MCDisassembler::Fail;
36380b57cec5SDimitry Andric     break;
36390b57cec5SDimitry Andric   default:
36400b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
36410b57cec5SDimitry Andric       return MCDisassembler::Fail;
36420b57cec5SDimitry Andric     break;
36430b57cec5SDimitry Andric   }
36440b57cec5SDimitry Andric 
36450b57cec5SDimitry Andric   if (Rm != 0xF)
36460b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
36470b57cec5SDimitry Andric 
36480b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
36490b57cec5SDimitry Andric     return MCDisassembler::Fail;
36500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
36510b57cec5SDimitry Andric 
36520b57cec5SDimitry Andric   if (Rm != 0xD && Rm != 0xF) {
36530b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
36540b57cec5SDimitry Andric       return MCDisassembler::Fail;
36550b57cec5SDimitry Andric   }
36560b57cec5SDimitry Andric 
36570b57cec5SDimitry Andric   return S;
36580b57cec5SDimitry Andric }
36590b57cec5SDimitry Andric 
36600b57cec5SDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
366181ad6265SDimitry Andric                                              uint64_t Address,
366281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
36630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
36640b57cec5SDimitry Andric 
36650b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
36660b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
36670b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
36680b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
36690b57cec5SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
36700b57cec5SDimitry Andric 
36710b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
36720b57cec5SDimitry Andric     return MCDisassembler::Fail;
36730b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
36740b57cec5SDimitry Andric     return MCDisassembler::Fail;
36750b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
36760b57cec5SDimitry Andric     return MCDisassembler::Fail;
36770b57cec5SDimitry Andric   if (Rm != 0xF) {
36780b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
36790b57cec5SDimitry Andric       return MCDisassembler::Fail;
36800b57cec5SDimitry Andric   }
36810b57cec5SDimitry Andric 
36820b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
36830b57cec5SDimitry Andric     return MCDisassembler::Fail;
36840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
36850b57cec5SDimitry Andric 
36860b57cec5SDimitry Andric   if (Rm == 0xD)
36870b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
36880b57cec5SDimitry Andric   else if (Rm != 0xF) {
36890b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
36900b57cec5SDimitry Andric       return MCDisassembler::Fail;
36910b57cec5SDimitry Andric   }
36920b57cec5SDimitry Andric 
36930b57cec5SDimitry Andric   return S;
36940b57cec5SDimitry Andric }
36950b57cec5SDimitry Andric 
36960b57cec5SDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
369781ad6265SDimitry Andric                                              uint64_t Address,
369881ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
36990b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37000b57cec5SDimitry Andric 
37010b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
37020b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
37030b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
37040b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
37050b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
37060b57cec5SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
37070b57cec5SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
37080b57cec5SDimitry Andric 
37090b57cec5SDimitry Andric   if (size == 0x3) {
37100b57cec5SDimitry Andric     if (align == 0)
37110b57cec5SDimitry Andric       return MCDisassembler::Fail;
37120b57cec5SDimitry Andric     align = 16;
37130b57cec5SDimitry Andric   } else {
37140b57cec5SDimitry Andric     if (size == 2) {
37150b57cec5SDimitry Andric       align *= 8;
37160b57cec5SDimitry Andric     } else {
37170b57cec5SDimitry Andric       size = 1 << size;
37180b57cec5SDimitry Andric       align *= 4*size;
37190b57cec5SDimitry Andric     }
37200b57cec5SDimitry Andric   }
37210b57cec5SDimitry Andric 
37220b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
37230b57cec5SDimitry Andric     return MCDisassembler::Fail;
37240b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
37250b57cec5SDimitry Andric     return MCDisassembler::Fail;
37260b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
37270b57cec5SDimitry Andric     return MCDisassembler::Fail;
37280b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
37290b57cec5SDimitry Andric     return MCDisassembler::Fail;
37300b57cec5SDimitry Andric   if (Rm != 0xF) {
37310b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37320b57cec5SDimitry Andric       return MCDisassembler::Fail;
37330b57cec5SDimitry Andric   }
37340b57cec5SDimitry Andric 
37350b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37360b57cec5SDimitry Andric     return MCDisassembler::Fail;
37370b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
37380b57cec5SDimitry Andric 
37390b57cec5SDimitry Andric   if (Rm == 0xD)
37400b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
37410b57cec5SDimitry Andric   else if (Rm != 0xF) {
37420b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
37430b57cec5SDimitry Andric       return MCDisassembler::Fail;
37440b57cec5SDimitry Andric   }
37450b57cec5SDimitry Andric 
37460b57cec5SDimitry Andric   return S;
37470b57cec5SDimitry Andric }
37480b57cec5SDimitry Andric 
374981ad6265SDimitry Andric static DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst, unsigned Insn,
375081ad6265SDimitry Andric                                                 uint64_t Address,
375181ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
37520b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37530b57cec5SDimitry Andric 
37540b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
37550b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
37560b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
37570b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
37580b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 24, 1) << 7;
37590b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 8, 4) << 8;
37600b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1) << 12;
37610b57cec5SDimitry Andric   unsigned Q = fieldFromInstruction(Insn, 6, 1);
37620b57cec5SDimitry Andric 
37630b57cec5SDimitry Andric   if (Q) {
37640b57cec5SDimitry Andric     if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
37650b57cec5SDimitry Andric     return MCDisassembler::Fail;
37660b57cec5SDimitry Andric   } else {
37670b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
37680b57cec5SDimitry Andric     return MCDisassembler::Fail;
37690b57cec5SDimitry Andric   }
37700b57cec5SDimitry Andric 
37710b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37720b57cec5SDimitry Andric 
37730b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
37740b57cec5SDimitry Andric     case ARM::VORRiv4i16:
37750b57cec5SDimitry Andric     case ARM::VORRiv2i32:
37760b57cec5SDimitry Andric     case ARM::VBICiv4i16:
37770b57cec5SDimitry Andric     case ARM::VBICiv2i32:
37780b57cec5SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
37790b57cec5SDimitry Andric         return MCDisassembler::Fail;
37800b57cec5SDimitry Andric       break;
37810b57cec5SDimitry Andric     case ARM::VORRiv8i16:
37820b57cec5SDimitry Andric     case ARM::VORRiv4i32:
37830b57cec5SDimitry Andric     case ARM::VBICiv8i16:
37840b57cec5SDimitry Andric     case ARM::VBICiv4i32:
37850b57cec5SDimitry Andric       if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
37860b57cec5SDimitry Andric         return MCDisassembler::Fail;
37870b57cec5SDimitry Andric       break;
37880b57cec5SDimitry Andric     default:
37890b57cec5SDimitry Andric       break;
37900b57cec5SDimitry Andric   }
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric   return S;
37930b57cec5SDimitry Andric }
37940b57cec5SDimitry Andric 
379581ad6265SDimitry Andric static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
379681ad6265SDimitry Andric                                                uint64_t Address,
379781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
37980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37990b57cec5SDimitry Andric 
38000b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
38010b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
38020b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
38030b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
38040b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
38050b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 28, 1) << 7;
38060b57cec5SDimitry Andric   imm |= cmode                             << 8;
38070b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1)  << 12;
38080b57cec5SDimitry Andric 
38090b57cec5SDimitry Andric   if (cmode == 0xF && Inst.getOpcode() == ARM::MVE_VMVNimmi32)
38100b57cec5SDimitry Andric     return MCDisassembler::Fail;
38110b57cec5SDimitry Andric 
38120b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
38130b57cec5SDimitry Andric     return MCDisassembler::Fail;
38140b57cec5SDimitry Andric 
38150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
38160b57cec5SDimitry Andric 
38170b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
38180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
38190b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
38200b57cec5SDimitry Andric 
38210b57cec5SDimitry Andric   return S;
38220b57cec5SDimitry Andric }
38230b57cec5SDimitry Andric 
38240b57cec5SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
382581ad6265SDimitry Andric                                              uint64_t Address,
382681ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
38270b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38280b57cec5SDimitry Andric 
38290b57cec5SDimitry Andric   unsigned Qd = fieldFromInstruction(Insn, 13, 3);
38300b57cec5SDimitry Andric   Qd |= fieldFromInstruction(Insn, 22, 1) << 3;
38310b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
38320b57cec5SDimitry Andric     return MCDisassembler::Fail;
38330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
38340b57cec5SDimitry Andric 
38350b57cec5SDimitry Andric   unsigned Qn = fieldFromInstruction(Insn, 17, 3);
38360b57cec5SDimitry Andric   Qn |= fieldFromInstruction(Insn, 7, 1) << 3;
38370b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
38380b57cec5SDimitry Andric     return MCDisassembler::Fail;
38390b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 1, 3);
38400b57cec5SDimitry Andric   Qm |= fieldFromInstruction(Insn, 5, 1) << 3;
38410b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
38420b57cec5SDimitry Andric     return MCDisassembler::Fail;
38430b57cec5SDimitry Andric   if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
38440b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
38450b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Qd));
38460b57cec5SDimitry Andric 
38470b57cec5SDimitry Andric   return S;
38480b57cec5SDimitry Andric }
38490b57cec5SDimitry Andric 
38500b57cec5SDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
385181ad6265SDimitry Andric                                              uint64_t Address,
385281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
38530b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38540b57cec5SDimitry Andric 
38550b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
38560b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
38570b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
38580b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
38590b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 18, 2);
38600b57cec5SDimitry Andric 
38610b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
38620b57cec5SDimitry Andric     return MCDisassembler::Fail;
38630b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
38640b57cec5SDimitry Andric     return MCDisassembler::Fail;
38650b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 << size));
38660b57cec5SDimitry Andric 
38670b57cec5SDimitry Andric   return S;
38680b57cec5SDimitry Andric }
38690b57cec5SDimitry Andric 
38700b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
387181ad6265SDimitry Andric                                          uint64_t Address,
387281ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
38730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 - Val));
38740b57cec5SDimitry Andric   return MCDisassembler::Success;
38750b57cec5SDimitry Andric }
38760b57cec5SDimitry Andric 
38770b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
387881ad6265SDimitry Andric                                           uint64_t Address,
387981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
38800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(16 - Val));
38810b57cec5SDimitry Andric   return MCDisassembler::Success;
38820b57cec5SDimitry Andric }
38830b57cec5SDimitry Andric 
38840b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
388581ad6265SDimitry Andric                                           uint64_t Address,
388681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
38870b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(32 - Val));
38880b57cec5SDimitry Andric   return MCDisassembler::Success;
38890b57cec5SDimitry Andric }
38900b57cec5SDimitry Andric 
38910b57cec5SDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
389281ad6265SDimitry Andric                                           uint64_t Address,
389381ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
38940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
38950b57cec5SDimitry Andric   return MCDisassembler::Success;
38960b57cec5SDimitry Andric }
38970b57cec5SDimitry Andric 
38980b57cec5SDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
389981ad6265SDimitry Andric                                          uint64_t Address,
390081ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
39010b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39020b57cec5SDimitry Andric 
39030b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
39040b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
39050b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
39060b57cec5SDimitry Andric   Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
39070b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
39080b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
39090b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 6, 1);
39100b57cec5SDimitry Andric 
39110b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
39120b57cec5SDimitry Andric     return MCDisassembler::Fail;
39130b57cec5SDimitry Andric   if (op) {
39140b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
39150b57cec5SDimitry Andric     return MCDisassembler::Fail; // Writeback
39160b57cec5SDimitry Andric   }
39170b57cec5SDimitry Andric 
39180b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
39190b57cec5SDimitry Andric   case ARM::VTBL2:
39200b57cec5SDimitry Andric   case ARM::VTBX2:
39210b57cec5SDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
39220b57cec5SDimitry Andric       return MCDisassembler::Fail;
39230b57cec5SDimitry Andric     break;
39240b57cec5SDimitry Andric   default:
39250b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
39260b57cec5SDimitry Andric       return MCDisassembler::Fail;
39270b57cec5SDimitry Andric   }
39280b57cec5SDimitry Andric 
39290b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
39300b57cec5SDimitry Andric     return MCDisassembler::Fail;
39310b57cec5SDimitry Andric 
39320b57cec5SDimitry Andric   return S;
39330b57cec5SDimitry Andric }
39340b57cec5SDimitry Andric 
39350b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
393681ad6265SDimitry Andric                                              uint64_t Address,
393781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
39380b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39390b57cec5SDimitry Andric 
39400b57cec5SDimitry Andric   unsigned dst = fieldFromInstruction(Insn, 8, 3);
39410b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
39420b57cec5SDimitry Andric 
39430b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
39440b57cec5SDimitry Andric     return MCDisassembler::Fail;
39450b57cec5SDimitry Andric 
39460b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
39470b57cec5SDimitry Andric     default:
39480b57cec5SDimitry Andric       return MCDisassembler::Fail;
39490b57cec5SDimitry Andric     case ARM::tADR:
39500b57cec5SDimitry Andric       break; // tADR does not explicitly represent the PC as an operand.
39510b57cec5SDimitry Andric     case ARM::tADDrSPi:
39520b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::SP));
39530b57cec5SDimitry Andric       break;
39540b57cec5SDimitry Andric   }
39550b57cec5SDimitry Andric 
39560b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
39570b57cec5SDimitry Andric   return S;
39580b57cec5SDimitry Andric }
39590b57cec5SDimitry Andric 
39600b57cec5SDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
396181ad6265SDimitry Andric                                          uint64_t Address,
396281ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
39630b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
39640b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
39650b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1)));
39660b57cec5SDimitry Andric   return MCDisassembler::Success;
39670b57cec5SDimitry Andric }
39680b57cec5SDimitry Andric 
39690b57cec5SDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
397081ad6265SDimitry Andric                                       uint64_t Address,
397181ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
39720b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
39730b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
39740b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val)));
39750b57cec5SDimitry Andric   return MCDisassembler::Success;
39760b57cec5SDimitry Andric }
39770b57cec5SDimitry Andric 
39780b57cec5SDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
397981ad6265SDimitry Andric                                             uint64_t Address,
398081ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
39810b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
39820b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
39830b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val << 1));
39840b57cec5SDimitry Andric   return MCDisassembler::Success;
39850b57cec5SDimitry Andric }
39860b57cec5SDimitry Andric 
39870b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
398881ad6265SDimitry Andric                                           uint64_t Address,
398981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
39900b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39910b57cec5SDimitry Andric 
39920b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
39930b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 3, 3);
39940b57cec5SDimitry Andric 
39950b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
39960b57cec5SDimitry Andric     return MCDisassembler::Fail;
39970b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
39980b57cec5SDimitry Andric     return MCDisassembler::Fail;
39990b57cec5SDimitry Andric 
40000b57cec5SDimitry Andric   return S;
40010b57cec5SDimitry Andric }
40020b57cec5SDimitry Andric 
40030b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
400481ad6265SDimitry Andric                                           uint64_t Address,
400581ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40060b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40070b57cec5SDimitry Andric 
40080b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
40090b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 3, 5);
40100b57cec5SDimitry Andric 
40110b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
40120b57cec5SDimitry Andric     return MCDisassembler::Fail;
40130b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
40140b57cec5SDimitry Andric 
40150b57cec5SDimitry Andric   return S;
40160b57cec5SDimitry Andric }
40170b57cec5SDimitry Andric 
40180b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
401981ad6265SDimitry Andric                                           uint64_t Address,
402081ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40210b57cec5SDimitry Andric   unsigned imm = Val << 2;
40220b57cec5SDimitry Andric 
40230b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
40240b57cec5SDimitry Andric   tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
40250b57cec5SDimitry Andric 
40260b57cec5SDimitry Andric   return MCDisassembler::Success;
40270b57cec5SDimitry Andric }
40280b57cec5SDimitry Andric 
40290b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
403081ad6265SDimitry Andric                                           uint64_t Address,
403181ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40320b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
40330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
40340b57cec5SDimitry Andric 
40350b57cec5SDimitry Andric   return MCDisassembler::Success;
40360b57cec5SDimitry Andric }
40370b57cec5SDimitry Andric 
40380b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
403981ad6265SDimitry Andric                                           uint64_t Address,
404081ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
40410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40420b57cec5SDimitry Andric 
40430b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 6, 4);
40440b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 2, 4);
40450b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 2);
40460b57cec5SDimitry Andric 
40470b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
40480b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
40490b57cec5SDimitry Andric   case ARM::t2STRHs:
40500b57cec5SDimitry Andric   case ARM::t2STRBs:
40510b57cec5SDimitry Andric   case ARM::t2STRs:
40520b57cec5SDimitry Andric     if (Rn == 15)
40530b57cec5SDimitry Andric       return MCDisassembler::Fail;
40540b57cec5SDimitry Andric     break;
40550b57cec5SDimitry Andric   default:
40560b57cec5SDimitry Andric     break;
40570b57cec5SDimitry Andric   }
40580b57cec5SDimitry Andric 
40590b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
40600b57cec5SDimitry Andric     return MCDisassembler::Fail;
40610b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
40620b57cec5SDimitry Andric     return MCDisassembler::Fail;
40630b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
40640b57cec5SDimitry Andric 
40650b57cec5SDimitry Andric   return S;
40660b57cec5SDimitry Andric }
40670b57cec5SDimitry Andric 
40680b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
406981ad6265SDimitry Andric                                       uint64_t Address,
407081ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
40710b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40720b57cec5SDimitry Andric 
40730b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
40740b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
40750b57cec5SDimitry Andric 
40760b57cec5SDimitry Andric   const FeatureBitset &featureBits =
40770b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
40780b57cec5SDimitry Andric 
40790b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
40800b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
40810b57cec5SDimitry Andric 
40820b57cec5SDimitry Andric   if (Rn == 15) {
40830b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
40840b57cec5SDimitry Andric     case ARM::t2LDRBs:
40850b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
40860b57cec5SDimitry Andric       break;
40870b57cec5SDimitry Andric     case ARM::t2LDRHs:
40880b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
40890b57cec5SDimitry Andric       break;
40900b57cec5SDimitry Andric     case ARM::t2LDRSHs:
40910b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
40920b57cec5SDimitry Andric       break;
40930b57cec5SDimitry Andric     case ARM::t2LDRSBs:
40940b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
40950b57cec5SDimitry Andric       break;
40960b57cec5SDimitry Andric     case ARM::t2LDRs:
40970b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
40980b57cec5SDimitry Andric       break;
40990b57cec5SDimitry Andric     case ARM::t2PLDs:
41000b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
41010b57cec5SDimitry Andric       break;
41020b57cec5SDimitry Andric     case ARM::t2PLIs:
41030b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
41040b57cec5SDimitry Andric       break;
41050b57cec5SDimitry Andric     default:
41060b57cec5SDimitry Andric       return MCDisassembler::Fail;
41070b57cec5SDimitry Andric     }
41080b57cec5SDimitry Andric 
41090b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
41100b57cec5SDimitry Andric   }
41110b57cec5SDimitry Andric 
41120b57cec5SDimitry Andric   if (Rt == 15) {
41130b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
41140b57cec5SDimitry Andric     case ARM::t2LDRSHs:
41150b57cec5SDimitry Andric       return MCDisassembler::Fail;
41160b57cec5SDimitry Andric     case ARM::t2LDRHs:
41170b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDWs);
41180b57cec5SDimitry Andric       break;
41190b57cec5SDimitry Andric     case ARM::t2LDRSBs:
41200b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIs);
41210b57cec5SDimitry Andric       break;
41220b57cec5SDimitry Andric     default:
41230b57cec5SDimitry Andric       break;
41240b57cec5SDimitry Andric     }
41250b57cec5SDimitry Andric   }
41260b57cec5SDimitry Andric 
41270b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
41280b57cec5SDimitry Andric     case ARM::t2PLDs:
41290b57cec5SDimitry Andric       break;
41300b57cec5SDimitry Andric     case ARM::t2PLIs:
41310b57cec5SDimitry Andric       if (!hasV7Ops)
41320b57cec5SDimitry Andric         return MCDisassembler::Fail;
41330b57cec5SDimitry Andric       break;
41340b57cec5SDimitry Andric     case ARM::t2PLDWs:
41350b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
41360b57cec5SDimitry Andric         return MCDisassembler::Fail;
41370b57cec5SDimitry Andric       break;
41380b57cec5SDimitry Andric     default:
41390b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
41400b57cec5SDimitry Andric         return MCDisassembler::Fail;
41410b57cec5SDimitry Andric   }
41420b57cec5SDimitry Andric 
41430b57cec5SDimitry Andric   unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
41440b57cec5SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
41450b57cec5SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
41460b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
41470b57cec5SDimitry Andric     return MCDisassembler::Fail;
41480b57cec5SDimitry Andric 
41490b57cec5SDimitry Andric   return S;
41500b57cec5SDimitry Andric }
41510b57cec5SDimitry Andric 
41520b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
415381ad6265SDimitry Andric                                      uint64_t Address,
415481ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
41550b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
41560b57cec5SDimitry Andric 
41570b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
41580b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
41590b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 9, 1);
41600b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
41610b57cec5SDimitry Andric   imm |= (U << 8);
41620b57cec5SDimitry Andric   imm |= (Rn << 9);
41630b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 9, 1);
41640b57cec5SDimitry Andric 
41650b57cec5SDimitry Andric   const FeatureBitset &featureBits =
41660b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
41670b57cec5SDimitry Andric 
41680b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
41690b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
41700b57cec5SDimitry Andric 
41710b57cec5SDimitry Andric   if (Rn == 15) {
41720b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
41730b57cec5SDimitry Andric     case ARM::t2LDRi8:
41740b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
41750b57cec5SDimitry Andric       break;
41760b57cec5SDimitry Andric     case ARM::t2LDRBi8:
41770b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
41780b57cec5SDimitry Andric       break;
41790b57cec5SDimitry Andric     case ARM::t2LDRSBi8:
41800b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
41810b57cec5SDimitry Andric       break;
41820b57cec5SDimitry Andric     case ARM::t2LDRHi8:
41830b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
41840b57cec5SDimitry Andric       break;
41850b57cec5SDimitry Andric     case ARM::t2LDRSHi8:
41860b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
41870b57cec5SDimitry Andric       break;
41880b57cec5SDimitry Andric     case ARM::t2PLDi8:
41890b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
41900b57cec5SDimitry Andric       break;
41910b57cec5SDimitry Andric     case ARM::t2PLIi8:
41920b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
41930b57cec5SDimitry Andric       break;
41940b57cec5SDimitry Andric     default:
41950b57cec5SDimitry Andric       return MCDisassembler::Fail;
41960b57cec5SDimitry Andric     }
41970b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
41980b57cec5SDimitry Andric   }
41990b57cec5SDimitry Andric 
42000b57cec5SDimitry Andric   if (Rt == 15) {
42010b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
42020b57cec5SDimitry Andric     case ARM::t2LDRSHi8:
42030b57cec5SDimitry Andric       return MCDisassembler::Fail;
42040b57cec5SDimitry Andric     case ARM::t2LDRHi8:
42050b57cec5SDimitry Andric       if (!add)
42060b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLDWi8);
42070b57cec5SDimitry Andric       break;
42080b57cec5SDimitry Andric     case ARM::t2LDRSBi8:
42090b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIi8);
42100b57cec5SDimitry Andric       break;
42110b57cec5SDimitry Andric     default:
42120b57cec5SDimitry Andric       break;
42130b57cec5SDimitry Andric     }
42140b57cec5SDimitry Andric   }
42150b57cec5SDimitry Andric 
42160b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
42170b57cec5SDimitry Andric   case ARM::t2PLDi8:
42180b57cec5SDimitry Andric     break;
42190b57cec5SDimitry Andric   case ARM::t2PLIi8:
42200b57cec5SDimitry Andric     if (!hasV7Ops)
42210b57cec5SDimitry Andric       return MCDisassembler::Fail;
42220b57cec5SDimitry Andric     break;
42230b57cec5SDimitry Andric   case ARM::t2PLDWi8:
42240b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
42250b57cec5SDimitry Andric         return MCDisassembler::Fail;
42260b57cec5SDimitry Andric       break;
42270b57cec5SDimitry Andric   default:
42280b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
42290b57cec5SDimitry Andric       return MCDisassembler::Fail;
42300b57cec5SDimitry Andric   }
42310b57cec5SDimitry Andric 
42320b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
42330b57cec5SDimitry Andric     return MCDisassembler::Fail;
42340b57cec5SDimitry Andric   return S;
42350b57cec5SDimitry Andric }
42360b57cec5SDimitry Andric 
42370b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
423881ad6265SDimitry Andric                                       uint64_t Address,
423981ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
42400b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42410b57cec5SDimitry Andric 
42420b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
42430b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
42440b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
42450b57cec5SDimitry Andric   imm |= (Rn << 13);
42460b57cec5SDimitry Andric 
42470b57cec5SDimitry Andric   const FeatureBitset &featureBits =
42480b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
42490b57cec5SDimitry Andric 
42500b57cec5SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
42510b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
42520b57cec5SDimitry Andric 
42530b57cec5SDimitry Andric   if (Rn == 15) {
42540b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
42550b57cec5SDimitry Andric     case ARM::t2LDRi12:
42560b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
42570b57cec5SDimitry Andric       break;
42580b57cec5SDimitry Andric     case ARM::t2LDRHi12:
42590b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
42600b57cec5SDimitry Andric       break;
42610b57cec5SDimitry Andric     case ARM::t2LDRSHi12:
42620b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
42630b57cec5SDimitry Andric       break;
42640b57cec5SDimitry Andric     case ARM::t2LDRBi12:
42650b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
42660b57cec5SDimitry Andric       break;
42670b57cec5SDimitry Andric     case ARM::t2LDRSBi12:
42680b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
42690b57cec5SDimitry Andric       break;
42700b57cec5SDimitry Andric     case ARM::t2PLDi12:
42710b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
42720b57cec5SDimitry Andric       break;
42730b57cec5SDimitry Andric     case ARM::t2PLIi12:
42740b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
42750b57cec5SDimitry Andric       break;
42760b57cec5SDimitry Andric     default:
42770b57cec5SDimitry Andric       return MCDisassembler::Fail;
42780b57cec5SDimitry Andric     }
42790b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
42800b57cec5SDimitry Andric   }
42810b57cec5SDimitry Andric 
42820b57cec5SDimitry Andric   if (Rt == 15) {
42830b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
42840b57cec5SDimitry Andric     case ARM::t2LDRSHi12:
42850b57cec5SDimitry Andric       return MCDisassembler::Fail;
42860b57cec5SDimitry Andric     case ARM::t2LDRHi12:
42870b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLDWi12);
42880b57cec5SDimitry Andric       break;
42890b57cec5SDimitry Andric     case ARM::t2LDRSBi12:
42900b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2PLIi12);
42910b57cec5SDimitry Andric       break;
42920b57cec5SDimitry Andric     default:
42930b57cec5SDimitry Andric       break;
42940b57cec5SDimitry Andric     }
42950b57cec5SDimitry Andric   }
42960b57cec5SDimitry Andric 
42970b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
42980b57cec5SDimitry Andric   case ARM::t2PLDi12:
42990b57cec5SDimitry Andric     break;
43000b57cec5SDimitry Andric   case ARM::t2PLIi12:
43010b57cec5SDimitry Andric     if (!hasV7Ops)
43020b57cec5SDimitry Andric       return MCDisassembler::Fail;
43030b57cec5SDimitry Andric     break;
43040b57cec5SDimitry Andric   case ARM::t2PLDWi12:
43050b57cec5SDimitry Andric       if (!hasV7Ops || !hasMP)
43060b57cec5SDimitry Andric         return MCDisassembler::Fail;
43070b57cec5SDimitry Andric       break;
43080b57cec5SDimitry Andric   default:
43090b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43100b57cec5SDimitry Andric       return MCDisassembler::Fail;
43110b57cec5SDimitry Andric   }
43120b57cec5SDimitry Andric 
43130b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
43140b57cec5SDimitry Andric     return MCDisassembler::Fail;
43150b57cec5SDimitry Andric   return S;
43160b57cec5SDimitry Andric }
43170b57cec5SDimitry Andric 
431881ad6265SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, uint64_t Address,
431981ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
43200b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43210b57cec5SDimitry Andric 
43220b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
43230b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43240b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
43250b57cec5SDimitry Andric   imm |= (Rn << 9);
43260b57cec5SDimitry Andric 
43270b57cec5SDimitry Andric   if (Rn == 15) {
43280b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
43290b57cec5SDimitry Andric     case ARM::t2LDRT:
43300b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
43310b57cec5SDimitry Andric       break;
43320b57cec5SDimitry Andric     case ARM::t2LDRBT:
43330b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
43340b57cec5SDimitry Andric       break;
43350b57cec5SDimitry Andric     case ARM::t2LDRHT:
43360b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
43370b57cec5SDimitry Andric       break;
43380b57cec5SDimitry Andric     case ARM::t2LDRSBT:
43390b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
43400b57cec5SDimitry Andric       break;
43410b57cec5SDimitry Andric     case ARM::t2LDRSHT:
43420b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
43430b57cec5SDimitry Andric       break;
43440b57cec5SDimitry Andric     default:
43450b57cec5SDimitry Andric       return MCDisassembler::Fail;
43460b57cec5SDimitry Andric     }
43470b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
43480b57cec5SDimitry Andric   }
43490b57cec5SDimitry Andric 
43500b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
43510b57cec5SDimitry Andric     return MCDisassembler::Fail;
43520b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
43530b57cec5SDimitry Andric     return MCDisassembler::Fail;
43540b57cec5SDimitry Andric   return S;
43550b57cec5SDimitry Andric }
43560b57cec5SDimitry Andric 
43570b57cec5SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
435881ad6265SDimitry Andric                                       uint64_t Address,
435981ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
43600b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43610b57cec5SDimitry Andric 
43620b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43630b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
43640b57cec5SDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 12);
43650b57cec5SDimitry Andric 
43660b57cec5SDimitry Andric   const FeatureBitset &featureBits =
43670b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
43680b57cec5SDimitry Andric 
43690b57cec5SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
43700b57cec5SDimitry Andric 
43710b57cec5SDimitry Andric   if (Rt == 15) {
43720b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
43730b57cec5SDimitry Andric       case ARM::t2LDRBpci:
43740b57cec5SDimitry Andric       case ARM::t2LDRHpci:
43750b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLDpci);
43760b57cec5SDimitry Andric         break;
43770b57cec5SDimitry Andric       case ARM::t2LDRSBpci:
43780b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
43790b57cec5SDimitry Andric         break;
43800b57cec5SDimitry Andric       case ARM::t2LDRSHpci:
43810b57cec5SDimitry Andric         return MCDisassembler::Fail;
43820b57cec5SDimitry Andric       default:
43830b57cec5SDimitry Andric         break;
43840b57cec5SDimitry Andric     }
43850b57cec5SDimitry Andric   }
43860b57cec5SDimitry Andric 
43870b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
43880b57cec5SDimitry Andric   case ARM::t2PLDpci:
43890b57cec5SDimitry Andric     break;
43900b57cec5SDimitry Andric   case ARM::t2PLIpci:
43910b57cec5SDimitry Andric     if (!hasV7Ops)
43920b57cec5SDimitry Andric       return MCDisassembler::Fail;
43930b57cec5SDimitry Andric     break;
43940b57cec5SDimitry Andric   default:
43950b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43960b57cec5SDimitry Andric       return MCDisassembler::Fail;
43970b57cec5SDimitry Andric   }
43980b57cec5SDimitry Andric 
43990b57cec5SDimitry Andric   if (!U) {
44000b57cec5SDimitry Andric     // Special case for #-0.
44010b57cec5SDimitry Andric     if (imm == 0)
44020b57cec5SDimitry Andric       imm = INT32_MIN;
44030b57cec5SDimitry Andric     else
44040b57cec5SDimitry Andric       imm = -imm;
44050b57cec5SDimitry Andric   }
44060b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44070b57cec5SDimitry Andric 
44080b57cec5SDimitry Andric   return S;
44090b57cec5SDimitry Andric }
44100b57cec5SDimitry Andric 
441181ad6265SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, uint64_t Address,
441281ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
44130b57cec5SDimitry Andric   if (Val == 0)
44140b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
44150b57cec5SDimitry Andric   else {
44160b57cec5SDimitry Andric     int imm = Val & 0xFF;
44170b57cec5SDimitry Andric 
44180b57cec5SDimitry Andric     if (!(Val & 0x100)) imm *= -1;
44190b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
44200b57cec5SDimitry Andric   }
44210b57cec5SDimitry Andric 
44220b57cec5SDimitry Andric   return MCDisassembler::Success;
44230b57cec5SDimitry Andric }
44240b57cec5SDimitry Andric 
44250b57cec5SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
442681ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
44270b57cec5SDimitry Andric   if (Val == 0)
44280b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
44290b57cec5SDimitry Andric   else {
44300b57cec5SDimitry Andric     int imm = Val & 0x7F;
44310b57cec5SDimitry Andric 
44320b57cec5SDimitry Andric     if (!(Val & 0x80))
44330b57cec5SDimitry Andric       imm *= -1;
44340b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
44350b57cec5SDimitry Andric   }
44360b57cec5SDimitry Andric 
44370b57cec5SDimitry Andric   return MCDisassembler::Success;
44380b57cec5SDimitry Andric }
44390b57cec5SDimitry Andric 
44400b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
444181ad6265SDimitry Andric                                            uint64_t Address,
444281ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
44430b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44440b57cec5SDimitry Andric 
44450b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
44460b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
44470b57cec5SDimitry Andric 
44480b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
44490b57cec5SDimitry Andric     return MCDisassembler::Fail;
44500b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
44510b57cec5SDimitry Andric     return MCDisassembler::Fail;
44520b57cec5SDimitry Andric 
44530b57cec5SDimitry Andric   return S;
44540b57cec5SDimitry Andric }
44550b57cec5SDimitry Andric 
44560b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
44570b57cec5SDimitry Andric                                            uint64_t Address,
445881ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
44590b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44600b57cec5SDimitry Andric 
44610b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
44620b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
44630b57cec5SDimitry Andric 
44640b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
44650b57cec5SDimitry Andric     return MCDisassembler::Fail;
44660b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7S4(Inst, imm, Address, Decoder)))
44670b57cec5SDimitry Andric     return MCDisassembler::Fail;
44680b57cec5SDimitry Andric 
44690b57cec5SDimitry Andric   return S;
44700b57cec5SDimitry Andric }
44710b57cec5SDimitry Andric 
44720b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst, unsigned Val,
447381ad6265SDimitry Andric                                                 uint64_t Address,
447481ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
44750b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44760b57cec5SDimitry Andric 
44770b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
44780b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
44790b57cec5SDimitry Andric 
44800b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
44810b57cec5SDimitry Andric     return MCDisassembler::Fail;
44820b57cec5SDimitry Andric 
44830b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44840b57cec5SDimitry Andric 
44850b57cec5SDimitry Andric   return S;
44860b57cec5SDimitry Andric }
44870b57cec5SDimitry Andric 
448881ad6265SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
448981ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
44900b57cec5SDimitry Andric   int imm = Val & 0xFF;
44910b57cec5SDimitry Andric   if (Val == 0)
44920b57cec5SDimitry Andric     imm = INT32_MIN;
44930b57cec5SDimitry Andric   else if (!(Val & 0x100))
44940b57cec5SDimitry Andric     imm *= -1;
44950b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
44960b57cec5SDimitry Andric 
44970b57cec5SDimitry Andric   return MCDisassembler::Success;
44980b57cec5SDimitry Andric }
44990b57cec5SDimitry Andric 
45000b57cec5SDimitry Andric template <int shift>
450181ad6265SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, uint64_t Address,
450281ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
45030b57cec5SDimitry Andric   int imm = Val & 0x7F;
45040b57cec5SDimitry Andric   if (Val == 0)
45050b57cec5SDimitry Andric     imm = INT32_MIN;
45060b57cec5SDimitry Andric   else if (!(Val & 0x80))
45070b57cec5SDimitry Andric     imm *= -1;
45080b57cec5SDimitry Andric   if (imm != INT32_MIN)
45090b57cec5SDimitry Andric     imm *= (1U << shift);
45100b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
45110b57cec5SDimitry Andric 
45120b57cec5SDimitry Andric   return MCDisassembler::Success;
45130b57cec5SDimitry Andric }
45140b57cec5SDimitry Andric 
45150b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
451681ad6265SDimitry Andric                                          uint64_t Address,
451781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
45180b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45190b57cec5SDimitry Andric 
45200b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
45210b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
45220b57cec5SDimitry Andric 
45230b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
45240b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
45250b57cec5SDimitry Andric   case ARM::t2STRT:
45260b57cec5SDimitry Andric   case ARM::t2STRBT:
45270b57cec5SDimitry Andric   case ARM::t2STRHT:
45280b57cec5SDimitry Andric   case ARM::t2STRi8:
45290b57cec5SDimitry Andric   case ARM::t2STRHi8:
45300b57cec5SDimitry Andric   case ARM::t2STRBi8:
45310b57cec5SDimitry Andric     if (Rn == 15)
45320b57cec5SDimitry Andric       return MCDisassembler::Fail;
45330b57cec5SDimitry Andric     break;
45340b57cec5SDimitry Andric   default:
45350b57cec5SDimitry Andric     break;
45360b57cec5SDimitry Andric   }
45370b57cec5SDimitry Andric 
45380b57cec5SDimitry Andric   // Some instructions always use an additive offset.
45390b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
45400b57cec5SDimitry Andric     case ARM::t2LDRT:
45410b57cec5SDimitry Andric     case ARM::t2LDRBT:
45420b57cec5SDimitry Andric     case ARM::t2LDRHT:
45430b57cec5SDimitry Andric     case ARM::t2LDRSBT:
45440b57cec5SDimitry Andric     case ARM::t2LDRSHT:
45450b57cec5SDimitry Andric     case ARM::t2STRT:
45460b57cec5SDimitry Andric     case ARM::t2STRBT:
45470b57cec5SDimitry Andric     case ARM::t2STRHT:
45480b57cec5SDimitry Andric       imm |= 0x100;
45490b57cec5SDimitry Andric       break;
45500b57cec5SDimitry Andric     default:
45510b57cec5SDimitry Andric       break;
45520b57cec5SDimitry Andric   }
45530b57cec5SDimitry Andric 
45540b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
45550b57cec5SDimitry Andric     return MCDisassembler::Fail;
45560b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
45570b57cec5SDimitry Andric     return MCDisassembler::Fail;
45580b57cec5SDimitry Andric 
45590b57cec5SDimitry Andric   return S;
45600b57cec5SDimitry Andric }
45610b57cec5SDimitry Andric 
45620b57cec5SDimitry Andric template <int shift>
45630b57cec5SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
45640b57cec5SDimitry Andric                                         uint64_t Address,
456581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
45660b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45670b57cec5SDimitry Andric 
45680b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 3);
45690b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
45700b57cec5SDimitry Andric 
45710b57cec5SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
45720b57cec5SDimitry Andric     return MCDisassembler::Fail;
45730b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
45740b57cec5SDimitry Andric     return MCDisassembler::Fail;
45750b57cec5SDimitry Andric 
45760b57cec5SDimitry Andric   return S;
45770b57cec5SDimitry Andric }
45780b57cec5SDimitry Andric 
45790b57cec5SDimitry Andric template <int shift, int WriteBack>
45800b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
45810b57cec5SDimitry Andric                                          uint64_t Address,
458281ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
45830b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45840b57cec5SDimitry Andric 
45850b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
45860b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
45870b57cec5SDimitry Andric   if (WriteBack) {
45880b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
45890b57cec5SDimitry Andric       return MCDisassembler::Fail;
45900b57cec5SDimitry Andric   } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
45910b57cec5SDimitry Andric     return MCDisassembler::Fail;
45920b57cec5SDimitry Andric   if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
45930b57cec5SDimitry Andric     return MCDisassembler::Fail;
45940b57cec5SDimitry Andric 
45950b57cec5SDimitry Andric   return S;
45960b57cec5SDimitry Andric }
45970b57cec5SDimitry Andric 
45980b57cec5SDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
459981ad6265SDimitry Andric                                     uint64_t Address,
460081ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
46010b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
46020b57cec5SDimitry Andric 
46030b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
46040b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
46050b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
46060b57cec5SDimitry Andric   addr |= fieldFromInstruction(Insn, 9, 1) << 8;
46070b57cec5SDimitry Andric   addr |= Rn << 9;
46080b57cec5SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 20, 1);
46090b57cec5SDimitry Andric 
46100b57cec5SDimitry Andric   if (Rn == 15) {
46110b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
46120b57cec5SDimitry Andric     case ARM::t2LDR_PRE:
46130b57cec5SDimitry Andric     case ARM::t2LDR_POST:
46140b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
46150b57cec5SDimitry Andric       break;
46160b57cec5SDimitry Andric     case ARM::t2LDRB_PRE:
46170b57cec5SDimitry Andric     case ARM::t2LDRB_POST:
46180b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
46190b57cec5SDimitry Andric       break;
46200b57cec5SDimitry Andric     case ARM::t2LDRH_PRE:
46210b57cec5SDimitry Andric     case ARM::t2LDRH_POST:
46220b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
46230b57cec5SDimitry Andric       break;
46240b57cec5SDimitry Andric     case ARM::t2LDRSB_PRE:
46250b57cec5SDimitry Andric     case ARM::t2LDRSB_POST:
46260b57cec5SDimitry Andric       if (Rt == 15)
46270b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
46280b57cec5SDimitry Andric       else
46290b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2LDRSBpci);
46300b57cec5SDimitry Andric       break;
46310b57cec5SDimitry Andric     case ARM::t2LDRSH_PRE:
46320b57cec5SDimitry Andric     case ARM::t2LDRSH_POST:
46330b57cec5SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
46340b57cec5SDimitry Andric       break;
46350b57cec5SDimitry Andric     default:
46360b57cec5SDimitry Andric       return MCDisassembler::Fail;
46370b57cec5SDimitry Andric     }
46380b57cec5SDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
46390b57cec5SDimitry Andric   }
46400b57cec5SDimitry Andric 
46410b57cec5SDimitry Andric   if (!load) {
46420b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46430b57cec5SDimitry Andric       return MCDisassembler::Fail;
46440b57cec5SDimitry Andric   }
46450b57cec5SDimitry Andric 
46460b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
46470b57cec5SDimitry Andric     return MCDisassembler::Fail;
46480b57cec5SDimitry Andric 
46490b57cec5SDimitry Andric   if (load) {
46500b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46510b57cec5SDimitry Andric       return MCDisassembler::Fail;
46520b57cec5SDimitry Andric   }
46530b57cec5SDimitry Andric 
46540b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
46550b57cec5SDimitry Andric     return MCDisassembler::Fail;
46560b57cec5SDimitry Andric 
46570b57cec5SDimitry Andric   return S;
46580b57cec5SDimitry Andric }
46590b57cec5SDimitry Andric 
46600b57cec5SDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
466181ad6265SDimitry Andric                                           uint64_t Address,
466281ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
46630b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
46640b57cec5SDimitry Andric 
46650b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
46660b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
46670b57cec5SDimitry Andric 
46680b57cec5SDimitry Andric   // Thumb stores cannot use PC as dest register.
46690b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
46700b57cec5SDimitry Andric   case ARM::t2STRi12:
46710b57cec5SDimitry Andric   case ARM::t2STRBi12:
46720b57cec5SDimitry Andric   case ARM::t2STRHi12:
46730b57cec5SDimitry Andric     if (Rn == 15)
46740b57cec5SDimitry Andric       return MCDisassembler::Fail;
46750b57cec5SDimitry Andric     break;
46760b57cec5SDimitry Andric   default:
46770b57cec5SDimitry Andric     break;
46780b57cec5SDimitry Andric   }
46790b57cec5SDimitry Andric 
46800b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46810b57cec5SDimitry Andric     return MCDisassembler::Fail;
46820b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
46830b57cec5SDimitry Andric 
46840b57cec5SDimitry Andric   return S;
46850b57cec5SDimitry Andric }
46860b57cec5SDimitry Andric 
46870b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
468881ad6265SDimitry Andric                                         uint64_t Address,
468981ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
46900b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 7);
46910b57cec5SDimitry Andric 
46920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
46930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
46940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
46950b57cec5SDimitry Andric 
46960b57cec5SDimitry Andric   return MCDisassembler::Success;
46970b57cec5SDimitry Andric }
46980b57cec5SDimitry Andric 
46990b57cec5SDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
470081ad6265SDimitry Andric                                         uint64_t Address,
470181ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
47020b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47030b57cec5SDimitry Andric 
47040b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::tADDrSP) {
47050b57cec5SDimitry Andric     unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
47060b57cec5SDimitry Andric     Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
47070b57cec5SDimitry Andric 
47080b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
47090b57cec5SDimitry Andric     return MCDisassembler::Fail;
47100b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
47110b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
47120b57cec5SDimitry Andric     return MCDisassembler::Fail;
47130b57cec5SDimitry Andric   } else if (Inst.getOpcode() == ARM::tADDspr) {
47140b57cec5SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 3, 4);
47150b57cec5SDimitry Andric 
47160b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
47170b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
47180b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
47190b57cec5SDimitry Andric     return MCDisassembler::Fail;
47200b57cec5SDimitry Andric   }
47210b57cec5SDimitry Andric 
47220b57cec5SDimitry Andric   return S;
47230b57cec5SDimitry Andric }
47240b57cec5SDimitry Andric 
47250b57cec5SDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
472681ad6265SDimitry Andric                                    uint64_t Address,
472781ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
47280b57cec5SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
47290b57cec5SDimitry Andric   unsigned flags = fieldFromInstruction(Insn, 0, 3);
47300b57cec5SDimitry Andric 
47310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imod));
47320b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(flags));
47330b57cec5SDimitry Andric 
47340b57cec5SDimitry Andric   return MCDisassembler::Success;
47350b57cec5SDimitry Andric }
47360b57cec5SDimitry Andric 
47370b57cec5SDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
473881ad6265SDimitry Andric                                      uint64_t Address,
473981ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
47400b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47410b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
47420b57cec5SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 4, 1);
47430b57cec5SDimitry Andric 
47440b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
47450b57cec5SDimitry Andric     return MCDisassembler::Fail;
47460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(add));
47470b57cec5SDimitry Andric 
47480b57cec5SDimitry Andric   return S;
47490b57cec5SDimitry Andric }
47500b57cec5SDimitry Andric 
47510b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
475281ad6265SDimitry Andric                                         uint64_t Address,
475381ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
47540b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47550b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 3, 4);
47560b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 0, 3);
47570b57cec5SDimitry Andric 
47580b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
47590b57cec5SDimitry Andric     return MCDisassembler::Fail;
47600b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
47610b57cec5SDimitry Andric     return MCDisassembler::Fail;
47620b57cec5SDimitry Andric 
47630b57cec5SDimitry Andric   return S;
47640b57cec5SDimitry Andric }
47650b57cec5SDimitry Andric 
47660b57cec5SDimitry Andric template <int shift>
47670b57cec5SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
476881ad6265SDimitry Andric                                        uint64_t Address,
476981ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
47700b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47710b57cec5SDimitry Andric   unsigned Qm = fieldFromInstruction(Insn, 8, 3);
47720b57cec5SDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 7);
47730b57cec5SDimitry Andric 
47740b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
47750b57cec5SDimitry Andric     return MCDisassembler::Fail;
47760b57cec5SDimitry Andric 
47770b57cec5SDimitry Andric   if(!fieldFromInstruction(Insn, 7, 1)) {
47780b57cec5SDimitry Andric     if (imm == 0)
47790b57cec5SDimitry Andric       imm = INT32_MIN;                 // indicate -0
47800b57cec5SDimitry Andric     else
47810b57cec5SDimitry Andric       imm *= -1;
47820b57cec5SDimitry Andric   }
47830b57cec5SDimitry Andric   if (imm != INT32_MIN)
47840b57cec5SDimitry Andric     imm *= (1U << shift);
47850b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
47860b57cec5SDimitry Andric 
47870b57cec5SDimitry Andric   return S;
47880b57cec5SDimitry Andric }
47890b57cec5SDimitry Andric 
47900b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
479181ad6265SDimitry Andric                                          uint64_t Address,
479281ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
47930b57cec5SDimitry Andric   // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
47940b57cec5SDimitry Andric   // Note only one trailing zero not two.  Also the J1 and J2 values are from
47950b57cec5SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
47960b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
47970b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
47980b57cec5SDimitry Andric   // and build the imm32 with two trailing zeros as documented:
47990b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
48000b57cec5SDimitry Andric   unsigned S = (Val >> 23) & 1;
48010b57cec5SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
48020b57cec5SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
48030b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
48040b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
48050b57cec5SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
48060b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
48070b57cec5SDimitry Andric 
48080b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address,
48090b57cec5SDimitry Andric                                 (Address & ~2u) + imm32 + 4,
48100b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
48110b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
48120b57cec5SDimitry Andric   return MCDisassembler::Success;
48130b57cec5SDimitry Andric }
48140b57cec5SDimitry Andric 
48150b57cec5SDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
481681ad6265SDimitry Andric                                       uint64_t Address,
481781ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
48180b57cec5SDimitry Andric   if (Val == 0xA || Val == 0xB)
48190b57cec5SDimitry Andric     return MCDisassembler::Fail;
48200b57cec5SDimitry Andric 
48210b57cec5SDimitry Andric   const FeatureBitset &featureBits =
48220b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
48230b57cec5SDimitry Andric 
48240b57cec5SDimitry Andric   if (!isValidCoprocessorNumber(Val, featureBits))
48250b57cec5SDimitry Andric     return MCDisassembler::Fail;
48260b57cec5SDimitry Andric 
48270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
48280b57cec5SDimitry Andric   return MCDisassembler::Success;
48290b57cec5SDimitry Andric }
48300b57cec5SDimitry Andric 
483181ad6265SDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
483281ad6265SDimitry Andric                                            uint64_t Address,
483381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
4834e8d8bef9SDimitry Andric   const FeatureBitset &FeatureBits =
4835e8d8bef9SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
48360b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48370b57cec5SDimitry Andric 
48380b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48390b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
48400b57cec5SDimitry Andric 
4841e8d8bef9SDimitry Andric   if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
48420b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48430b57cec5SDimitry Andric     return MCDisassembler::Fail;
48440b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
48450b57cec5SDimitry Andric     return MCDisassembler::Fail;
48460b57cec5SDimitry Andric   return S;
48470b57cec5SDimitry Andric }
48480b57cec5SDimitry Andric 
484981ad6265SDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
485081ad6265SDimitry Andric                                                uint64_t Address,
485181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
48520b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48530b57cec5SDimitry Andric 
48540b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 22, 4);
48550b57cec5SDimitry Andric   if (pred == 0xE || pred == 0xF) {
48560b57cec5SDimitry Andric     unsigned opc = fieldFromInstruction(Insn, 4, 28);
48570b57cec5SDimitry Andric     switch (opc) {
48580b57cec5SDimitry Andric       default:
48590b57cec5SDimitry Andric         return MCDisassembler::Fail;
48600b57cec5SDimitry Andric       case 0xf3bf8f4:
48610b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2DSB);
48620b57cec5SDimitry Andric         break;
48630b57cec5SDimitry Andric       case 0xf3bf8f5:
48640b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2DMB);
48650b57cec5SDimitry Andric         break;
48660b57cec5SDimitry Andric       case 0xf3bf8f6:
48670b57cec5SDimitry Andric         Inst.setOpcode(ARM::t2ISB);
48680b57cec5SDimitry Andric         break;
48690b57cec5SDimitry Andric     }
48700b57cec5SDimitry Andric 
48710b57cec5SDimitry Andric     unsigned imm = fieldFromInstruction(Insn, 0, 4);
48720b57cec5SDimitry Andric     return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
48730b57cec5SDimitry Andric   }
48740b57cec5SDimitry Andric 
48750b57cec5SDimitry Andric   unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
48760b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
48770b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
48780b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
48790b57cec5SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
48800b57cec5SDimitry Andric 
48810b57cec5SDimitry Andric   if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
48820b57cec5SDimitry Andric     return MCDisassembler::Fail;
48830b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
48840b57cec5SDimitry Andric     return MCDisassembler::Fail;
48850b57cec5SDimitry Andric 
48860b57cec5SDimitry Andric   return S;
48870b57cec5SDimitry Andric }
48880b57cec5SDimitry Andric 
48890b57cec5SDimitry Andric // Decode a shifted immediate operand.  These basically consist
48900b57cec5SDimitry Andric // of an 8-bit value, and a 4-bit directive that specifies either
48910b57cec5SDimitry Andric // a splat operation or a rotation.
489281ad6265SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, uint64_t Address,
489381ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
48940b57cec5SDimitry Andric   unsigned ctrl = fieldFromInstruction(Val, 10, 2);
48950b57cec5SDimitry Andric   if (ctrl == 0) {
48960b57cec5SDimitry Andric     unsigned byte = fieldFromInstruction(Val, 8, 2);
48970b57cec5SDimitry Andric     unsigned imm = fieldFromInstruction(Val, 0, 8);
48980b57cec5SDimitry Andric     switch (byte) {
48990b57cec5SDimitry Andric       case 0:
49000b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(imm));
49010b57cec5SDimitry Andric         break;
49020b57cec5SDimitry Andric       case 1:
49030b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 16) | imm));
49040b57cec5SDimitry Andric         break;
49050b57cec5SDimitry Andric       case 2:
49060b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8)));
49070b57cec5SDimitry Andric         break;
49080b57cec5SDimitry Andric       case 3:
49090b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) |
49100b57cec5SDimitry Andric                                              (imm << 8)  |  imm));
49110b57cec5SDimitry Andric         break;
49120b57cec5SDimitry Andric     }
49130b57cec5SDimitry Andric   } else {
49140b57cec5SDimitry Andric     unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
49150b57cec5SDimitry Andric     unsigned rot = fieldFromInstruction(Val, 7, 5);
491606c3fb27SDimitry Andric     unsigned imm = llvm::rotr<uint32_t>(unrot, rot);
49170b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
49180b57cec5SDimitry Andric   }
49190b57cec5SDimitry Andric 
49200b57cec5SDimitry Andric   return MCDisassembler::Success;
49210b57cec5SDimitry Andric }
49220b57cec5SDimitry Andric 
492381ad6265SDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
492481ad6265SDimitry Andric                                                 uint64_t Address,
492581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
49260b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
49270b57cec5SDimitry Andric                                 true, 2, Inst, Decoder))
49280b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1)));
49290b57cec5SDimitry Andric   return MCDisassembler::Success;
49300b57cec5SDimitry Andric }
49310b57cec5SDimitry Andric 
49320b57cec5SDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
49330b57cec5SDimitry Andric                                                uint64_t Address,
493481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
49350b57cec5SDimitry Andric   // Val is passed in as S:J1:J2:imm10:imm11
49360b57cec5SDimitry Andric   // Note no trailing zero after imm11.  Also the J1 and J2 values are from
49370b57cec5SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
49380b57cec5SDimitry Andric   // I1 = NOT(J1 EOR S);
49390b57cec5SDimitry Andric   // I2 = NOT(J2 EOR S);
49400b57cec5SDimitry Andric   // and build the imm32 with one trailing zero as documented:
49410b57cec5SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
49420b57cec5SDimitry Andric   unsigned S = (Val >> 23) & 1;
49430b57cec5SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
49440b57cec5SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
49450b57cec5SDimitry Andric   unsigned I1 = !(J1 ^ S);
49460b57cec5SDimitry Andric   unsigned I2 = !(J2 ^ S);
49470b57cec5SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
49480b57cec5SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
49490b57cec5SDimitry Andric 
49500b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
49510b57cec5SDimitry Andric                                 true, 4, Inst, Decoder))
49520b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
49530b57cec5SDimitry Andric   return MCDisassembler::Success;
49540b57cec5SDimitry Andric }
49550b57cec5SDimitry Andric 
49560b57cec5SDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
495781ad6265SDimitry Andric                                            uint64_t Address,
495881ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
49590b57cec5SDimitry Andric   if (Val & ~0xf)
49600b57cec5SDimitry Andric     return MCDisassembler::Fail;
49610b57cec5SDimitry Andric 
49620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
49630b57cec5SDimitry Andric   return MCDisassembler::Success;
49640b57cec5SDimitry Andric }
49650b57cec5SDimitry Andric 
49660b57cec5SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
496781ad6265SDimitry Andric                                                 uint64_t Address,
496881ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
49690b57cec5SDimitry Andric   if (Val & ~0xf)
49700b57cec5SDimitry Andric     return MCDisassembler::Fail;
49710b57cec5SDimitry Andric 
49720b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
49730b57cec5SDimitry Andric   return MCDisassembler::Success;
49740b57cec5SDimitry Andric }
49750b57cec5SDimitry Andric 
497681ad6265SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, uint64_t Address,
497781ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
49780b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49790b57cec5SDimitry Andric   const FeatureBitset &FeatureBits =
49800b57cec5SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
49810b57cec5SDimitry Andric 
49820b57cec5SDimitry Andric   if (FeatureBits[ARM::FeatureMClass]) {
49830b57cec5SDimitry Andric     unsigned ValLow = Val & 0xff;
49840b57cec5SDimitry Andric 
49850b57cec5SDimitry Andric     // Validate the SYSm value first.
49860b57cec5SDimitry Andric     switch (ValLow) {
49870b57cec5SDimitry Andric     case  0: // apsr
49880b57cec5SDimitry Andric     case  1: // iapsr
49890b57cec5SDimitry Andric     case  2: // eapsr
49900b57cec5SDimitry Andric     case  3: // xpsr
49910b57cec5SDimitry Andric     case  5: // ipsr
49920b57cec5SDimitry Andric     case  6: // epsr
49930b57cec5SDimitry Andric     case  7: // iepsr
49940b57cec5SDimitry Andric     case  8: // msp
49950b57cec5SDimitry Andric     case  9: // psp
49960b57cec5SDimitry Andric     case 16: // primask
49970b57cec5SDimitry Andric     case 20: // control
49980b57cec5SDimitry Andric       break;
49990b57cec5SDimitry Andric     case 17: // basepri
50000b57cec5SDimitry Andric     case 18: // basepri_max
50010b57cec5SDimitry Andric     case 19: // faultmask
50020b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops]))
50030b57cec5SDimitry Andric         // Values basepri, basepri_max and faultmask are only valid for v7m.
50040b57cec5SDimitry Andric         return MCDisassembler::Fail;
50050b57cec5SDimitry Andric       break;
50060b57cec5SDimitry Andric     case 0x8a: // msplim_ns
50070b57cec5SDimitry Andric     case 0x8b: // psplim_ns
50080b57cec5SDimitry Andric     case 0x91: // basepri_ns
50090b57cec5SDimitry Andric     case 0x93: // faultmask_ns
50100b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV8MMainlineOps]))
50110b57cec5SDimitry Andric         return MCDisassembler::Fail;
5012bdd1243dSDimitry Andric       [[fallthrough]];
50130b57cec5SDimitry Andric     case 10:   // msplim
50140b57cec5SDimitry Andric     case 11:   // psplim
50150b57cec5SDimitry Andric     case 0x88: // msp_ns
50160b57cec5SDimitry Andric     case 0x89: // psp_ns
50170b57cec5SDimitry Andric     case 0x90: // primask_ns
50180b57cec5SDimitry Andric     case 0x94: // control_ns
50190b57cec5SDimitry Andric     case 0x98: // sp_ns
50200b57cec5SDimitry Andric       if (!(FeatureBits[ARM::Feature8MSecExt]))
50210b57cec5SDimitry Andric         return MCDisassembler::Fail;
50220b57cec5SDimitry Andric       break;
50234824e7fdSDimitry Andric     case 0x20: // pac_key_p_0
50244824e7fdSDimitry Andric     case 0x21: // pac_key_p_1
50254824e7fdSDimitry Andric     case 0x22: // pac_key_p_2
50264824e7fdSDimitry Andric     case 0x23: // pac_key_p_3
50274824e7fdSDimitry Andric     case 0x24: // pac_key_u_0
50284824e7fdSDimitry Andric     case 0x25: // pac_key_u_1
50294824e7fdSDimitry Andric     case 0x26: // pac_key_u_2
50304824e7fdSDimitry Andric     case 0x27: // pac_key_u_3
50314824e7fdSDimitry Andric     case 0xa0: // pac_key_p_0_ns
50324824e7fdSDimitry Andric     case 0xa1: // pac_key_p_1_ns
50334824e7fdSDimitry Andric     case 0xa2: // pac_key_p_2_ns
50344824e7fdSDimitry Andric     case 0xa3: // pac_key_p_3_ns
50354824e7fdSDimitry Andric     case 0xa4: // pac_key_u_0_ns
50364824e7fdSDimitry Andric     case 0xa5: // pac_key_u_1_ns
50374824e7fdSDimitry Andric     case 0xa6: // pac_key_u_2_ns
50384824e7fdSDimitry Andric     case 0xa7: // pac_key_u_3_ns
50394824e7fdSDimitry Andric       if (!(FeatureBits[ARM::FeaturePACBTI]))
50404824e7fdSDimitry Andric         return MCDisassembler::Fail;
50414824e7fdSDimitry Andric       break;
50420b57cec5SDimitry Andric     default:
50430b57cec5SDimitry Andric       // Architecturally defined as unpredictable
50440b57cec5SDimitry Andric       S = MCDisassembler::SoftFail;
50450b57cec5SDimitry Andric       break;
50460b57cec5SDimitry Andric     }
50470b57cec5SDimitry Andric 
50480b57cec5SDimitry Andric     if (Inst.getOpcode() == ARM::t2MSR_M) {
50490b57cec5SDimitry Andric       unsigned Mask = fieldFromInstruction(Val, 10, 2);
50500b57cec5SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops])) {
50510b57cec5SDimitry Andric         // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
50520b57cec5SDimitry Andric         // unpredictable.
50530b57cec5SDimitry Andric         if (Mask != 2)
50540b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
50550b57cec5SDimitry Andric       }
50560b57cec5SDimitry Andric       else {
50570b57cec5SDimitry Andric         // The ARMv7-M architecture stores an additional 2-bit mask value in
50580b57cec5SDimitry Andric         // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
50590b57cec5SDimitry Andric         // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
50600b57cec5SDimitry Andric         // the NZCVQ bits should be moved by the instruction. Bit mask{0}
50610b57cec5SDimitry Andric         // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
50620b57cec5SDimitry Andric         // only if the processor includes the DSP extension.
50630b57cec5SDimitry Andric         if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
50640b57cec5SDimitry Andric             (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1)))
50650b57cec5SDimitry Andric           S = MCDisassembler::SoftFail;
50660b57cec5SDimitry Andric       }
50670b57cec5SDimitry Andric     }
50680b57cec5SDimitry Andric   } else {
50690b57cec5SDimitry Andric     // A/R class
50700b57cec5SDimitry Andric     if (Val == 0)
50710b57cec5SDimitry Andric       return MCDisassembler::Fail;
50720b57cec5SDimitry Andric   }
50730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
50740b57cec5SDimitry Andric   return S;
50750b57cec5SDimitry Andric }
50760b57cec5SDimitry Andric 
50770b57cec5SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
507881ad6265SDimitry Andric                                     uint64_t Address,
507981ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
50800b57cec5SDimitry Andric   unsigned R = fieldFromInstruction(Val, 5, 1);
50810b57cec5SDimitry Andric   unsigned SysM = fieldFromInstruction(Val, 0, 5);
50820b57cec5SDimitry Andric 
50830b57cec5SDimitry Andric   // The table of encodings for these banked registers comes from B9.2.3 of the
50840b57cec5SDimitry Andric   // ARM ARM. There are patterns, but nothing regular enough to make this logic
50850b57cec5SDimitry Andric   // neater. So by fiat, these values are UNPREDICTABLE:
50860b57cec5SDimitry Andric   if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM))
50870b57cec5SDimitry Andric     return MCDisassembler::Fail;
50880b57cec5SDimitry Andric 
50890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
50900b57cec5SDimitry Andric   return MCDisassembler::Success;
50910b57cec5SDimitry Andric }
50920b57cec5SDimitry Andric 
50930b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
509481ad6265SDimitry Andric                                         uint64_t Address,
509581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
50960b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
50970b57cec5SDimitry Andric 
50980b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
50990b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51000b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51010b57cec5SDimitry Andric 
51020b57cec5SDimitry Andric   if (Rn == 0xF)
51030b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
51040b57cec5SDimitry Andric 
51050b57cec5SDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
51060b57cec5SDimitry Andric     return MCDisassembler::Fail;
51070b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51080b57cec5SDimitry Andric     return MCDisassembler::Fail;
51090b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51100b57cec5SDimitry Andric     return MCDisassembler::Fail;
51110b57cec5SDimitry Andric 
51120b57cec5SDimitry Andric   return S;
51130b57cec5SDimitry Andric }
51140b57cec5SDimitry Andric 
51150b57cec5SDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
51160b57cec5SDimitry Andric                                          uint64_t Address,
511781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
51180b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51190b57cec5SDimitry Andric 
51200b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
51210b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
51220b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51230b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51240b57cec5SDimitry Andric 
51250b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
51260b57cec5SDimitry Andric     return MCDisassembler::Fail;
51270b57cec5SDimitry Andric 
51280b57cec5SDimitry Andric   if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
51290b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
51300b57cec5SDimitry Andric 
51310b57cec5SDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
51320b57cec5SDimitry Andric     return MCDisassembler::Fail;
51330b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51340b57cec5SDimitry Andric     return MCDisassembler::Fail;
51350b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51360b57cec5SDimitry Andric     return MCDisassembler::Fail;
51370b57cec5SDimitry Andric 
51380b57cec5SDimitry Andric   return S;
51390b57cec5SDimitry Andric }
51400b57cec5SDimitry Andric 
51410b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
514281ad6265SDimitry Andric                                     uint64_t Address,
514381ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
51440b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51450b57cec5SDimitry Andric 
51460b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51470b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
51480b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
51490b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
51500b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
51510b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51520b57cec5SDimitry Andric 
51530b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
51540b57cec5SDimitry Andric 
51550b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
51560b57cec5SDimitry Andric     return MCDisassembler::Fail;
51570b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51580b57cec5SDimitry Andric     return MCDisassembler::Fail;
51590b57cec5SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
51600b57cec5SDimitry Andric     return MCDisassembler::Fail;
51610b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51620b57cec5SDimitry Andric     return MCDisassembler::Fail;
51630b57cec5SDimitry Andric 
51640b57cec5SDimitry Andric   return S;
51650b57cec5SDimitry Andric }
51660b57cec5SDimitry Andric 
51670b57cec5SDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
516881ad6265SDimitry Andric                                     uint64_t Address,
516981ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
51700b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51710b57cec5SDimitry Andric 
51720b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
51730b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
51740b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
51750b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
51760b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
51770b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
51780b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
51790b57cec5SDimitry Andric 
51800b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
51810b57cec5SDimitry Andric   if (Rm == 0xF) S = MCDisassembler::SoftFail;
51820b57cec5SDimitry Andric 
51830b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
51840b57cec5SDimitry Andric     return MCDisassembler::Fail;
51850b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
51860b57cec5SDimitry Andric     return MCDisassembler::Fail;
51870b57cec5SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
51880b57cec5SDimitry Andric     return MCDisassembler::Fail;
51890b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
51900b57cec5SDimitry Andric     return MCDisassembler::Fail;
51910b57cec5SDimitry Andric 
51920b57cec5SDimitry Andric   return S;
51930b57cec5SDimitry Andric }
51940b57cec5SDimitry Andric 
51950b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
519681ad6265SDimitry Andric                                     uint64_t Address,
519781ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
51980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
51990b57cec5SDimitry Andric 
52000b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
52010b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
52020b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
52030b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
52040b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
52050b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
52060b57cec5SDimitry Andric 
52070b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
52080b57cec5SDimitry Andric 
52090b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52100b57cec5SDimitry Andric     return MCDisassembler::Fail;
52110b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
52120b57cec5SDimitry Andric     return MCDisassembler::Fail;
52130b57cec5SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
52140b57cec5SDimitry Andric     return MCDisassembler::Fail;
52150b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
52160b57cec5SDimitry Andric     return MCDisassembler::Fail;
52170b57cec5SDimitry Andric 
52180b57cec5SDimitry Andric   return S;
52190b57cec5SDimitry Andric }
52200b57cec5SDimitry Andric 
52210b57cec5SDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
522281ad6265SDimitry Andric                                     uint64_t Address,
522381ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
52240b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
52250b57cec5SDimitry Andric 
52260b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
52270b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
52280b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
52290b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
52300b57cec5SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
52310b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
52320b57cec5SDimitry Andric 
52330b57cec5SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
52340b57cec5SDimitry Andric 
52350b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52360b57cec5SDimitry Andric     return MCDisassembler::Fail;
52370b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
52380b57cec5SDimitry Andric     return MCDisassembler::Fail;
52390b57cec5SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
52400b57cec5SDimitry Andric     return MCDisassembler::Fail;
52410b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
52420b57cec5SDimitry Andric     return MCDisassembler::Fail;
52430b57cec5SDimitry Andric 
52440b57cec5SDimitry Andric   return S;
52450b57cec5SDimitry Andric }
52460b57cec5SDimitry Andric 
524781ad6265SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
524881ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
52490b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
52500b57cec5SDimitry Andric 
52510b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
52520b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
52530b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
52540b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
52550b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
52560b57cec5SDimitry Andric 
52570b57cec5SDimitry Andric   unsigned align = 0;
52580b57cec5SDimitry Andric   unsigned index = 0;
52590b57cec5SDimitry Andric   switch (size) {
52600b57cec5SDimitry Andric     default:
52610b57cec5SDimitry Andric       return MCDisassembler::Fail;
52620b57cec5SDimitry Andric     case 0:
52630b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52640b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52650b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
52660b57cec5SDimitry Andric       break;
52670b57cec5SDimitry Andric     case 1:
52680b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
52690b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52700b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
52710b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
52720b57cec5SDimitry Andric         align = 2;
52730b57cec5SDimitry Andric       break;
52740b57cec5SDimitry Andric     case 2:
52750b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
52760b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
52770b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
52780b57cec5SDimitry Andric 
52790b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
52800b57cec5SDimitry Andric         case 0 :
52810b57cec5SDimitry Andric           align = 0; break;
52820b57cec5SDimitry Andric         case 3:
52830b57cec5SDimitry Andric           align = 4; break;
52840b57cec5SDimitry Andric         default:
52850b57cec5SDimitry Andric           return MCDisassembler::Fail;
52860b57cec5SDimitry Andric       }
52870b57cec5SDimitry Andric       break;
52880b57cec5SDimitry Andric   }
52890b57cec5SDimitry Andric 
52900b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
52910b57cec5SDimitry Andric     return MCDisassembler::Fail;
52920b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
52930b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52940b57cec5SDimitry Andric       return MCDisassembler::Fail;
52950b57cec5SDimitry Andric   }
52960b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
52970b57cec5SDimitry Andric     return MCDisassembler::Fail;
52980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
52990b57cec5SDimitry Andric   if (Rm != 0xF) {
53000b57cec5SDimitry Andric     if (Rm != 0xD) {
53010b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
53020b57cec5SDimitry Andric         return MCDisassembler::Fail;
53030b57cec5SDimitry Andric     } else
53040b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
53050b57cec5SDimitry Andric   }
53060b57cec5SDimitry Andric 
53070b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53080b57cec5SDimitry Andric     return MCDisassembler::Fail;
53090b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
53100b57cec5SDimitry Andric 
53110b57cec5SDimitry Andric   return S;
53120b57cec5SDimitry Andric }
53130b57cec5SDimitry Andric 
531481ad6265SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
531581ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
53160b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
53170b57cec5SDimitry Andric 
53180b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
53190b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
53200b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
53210b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
53220b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
53230b57cec5SDimitry Andric 
53240b57cec5SDimitry Andric   unsigned align = 0;
53250b57cec5SDimitry Andric   unsigned index = 0;
53260b57cec5SDimitry Andric   switch (size) {
53270b57cec5SDimitry Andric     default:
53280b57cec5SDimitry Andric       return MCDisassembler::Fail;
53290b57cec5SDimitry Andric     case 0:
53300b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53310b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
53320b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
53330b57cec5SDimitry Andric       break;
53340b57cec5SDimitry Andric     case 1:
53350b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
53360b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
53370b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
53380b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53390b57cec5SDimitry Andric         align = 2;
53400b57cec5SDimitry Andric       break;
53410b57cec5SDimitry Andric     case 2:
53420b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
53430b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
53440b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
53450b57cec5SDimitry Andric 
53460b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
53470b57cec5SDimitry Andric         case 0:
53480b57cec5SDimitry Andric           align = 0; break;
53490b57cec5SDimitry Andric         case 3:
53500b57cec5SDimitry Andric           align = 4; break;
53510b57cec5SDimitry Andric         default:
53520b57cec5SDimitry Andric           return MCDisassembler::Fail;
53530b57cec5SDimitry Andric       }
53540b57cec5SDimitry Andric       break;
53550b57cec5SDimitry Andric   }
53560b57cec5SDimitry Andric 
53570b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
53580b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
53590b57cec5SDimitry Andric     return MCDisassembler::Fail;
53600b57cec5SDimitry Andric   }
53610b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
53620b57cec5SDimitry Andric     return MCDisassembler::Fail;
53630b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
53640b57cec5SDimitry Andric   if (Rm != 0xF) {
53650b57cec5SDimitry Andric     if (Rm != 0xD) {
53660b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
53670b57cec5SDimitry Andric     return MCDisassembler::Fail;
53680b57cec5SDimitry Andric     } else
53690b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
53700b57cec5SDimitry Andric   }
53710b57cec5SDimitry Andric 
53720b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
53730b57cec5SDimitry Andric     return MCDisassembler::Fail;
53740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
53750b57cec5SDimitry Andric 
53760b57cec5SDimitry Andric   return S;
53770b57cec5SDimitry Andric }
53780b57cec5SDimitry Andric 
537981ad6265SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
538081ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
53810b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
53820b57cec5SDimitry Andric 
53830b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
53840b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
53850b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
53860b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
53870b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
53880b57cec5SDimitry Andric 
53890b57cec5SDimitry Andric   unsigned align = 0;
53900b57cec5SDimitry Andric   unsigned index = 0;
53910b57cec5SDimitry Andric   unsigned inc = 1;
53920b57cec5SDimitry Andric   switch (size) {
53930b57cec5SDimitry Andric     default:
53940b57cec5SDimitry Andric       return MCDisassembler::Fail;
53950b57cec5SDimitry Andric     case 0:
53960b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
53970b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
53980b57cec5SDimitry Andric         align = 2;
53990b57cec5SDimitry Andric       break;
54000b57cec5SDimitry Andric     case 1:
54010b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
54020b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54030b57cec5SDimitry Andric         align = 4;
54040b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54050b57cec5SDimitry Andric         inc = 2;
54060b57cec5SDimitry Andric       break;
54070b57cec5SDimitry Andric     case 2:
54080b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54090b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
54100b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
54110b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
54120b57cec5SDimitry Andric         align = 8;
54130b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
54140b57cec5SDimitry Andric         inc = 2;
54150b57cec5SDimitry Andric       break;
54160b57cec5SDimitry Andric   }
54170b57cec5SDimitry Andric 
54180b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
54190b57cec5SDimitry Andric     return MCDisassembler::Fail;
54200b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
54210b57cec5SDimitry Andric     return MCDisassembler::Fail;
54220b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
54230b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54240b57cec5SDimitry Andric       return MCDisassembler::Fail;
54250b57cec5SDimitry Andric   }
54260b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54270b57cec5SDimitry Andric     return MCDisassembler::Fail;
54280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
54290b57cec5SDimitry Andric   if (Rm != 0xF) {
54300b57cec5SDimitry Andric     if (Rm != 0xD) {
54310b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
54320b57cec5SDimitry Andric         return MCDisassembler::Fail;
54330b57cec5SDimitry Andric     } else
54340b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
54350b57cec5SDimitry Andric   }
54360b57cec5SDimitry Andric 
54370b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
54380b57cec5SDimitry Andric     return MCDisassembler::Fail;
54390b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
54400b57cec5SDimitry Andric     return MCDisassembler::Fail;
54410b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
54420b57cec5SDimitry Andric 
54430b57cec5SDimitry Andric   return S;
54440b57cec5SDimitry Andric }
54450b57cec5SDimitry Andric 
544681ad6265SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
544781ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
54480b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
54490b57cec5SDimitry Andric 
54500b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
54510b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
54520b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
54530b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
54540b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
54550b57cec5SDimitry Andric 
54560b57cec5SDimitry Andric   unsigned align = 0;
54570b57cec5SDimitry Andric   unsigned index = 0;
54580b57cec5SDimitry Andric   unsigned inc = 1;
54590b57cec5SDimitry Andric   switch (size) {
54600b57cec5SDimitry Andric     default:
54610b57cec5SDimitry Andric       return MCDisassembler::Fail;
54620b57cec5SDimitry Andric     case 0:
54630b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
54640b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54650b57cec5SDimitry Andric         align = 2;
54660b57cec5SDimitry Andric       break;
54670b57cec5SDimitry Andric     case 1:
54680b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
54690b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
54700b57cec5SDimitry Andric         align = 4;
54710b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54720b57cec5SDimitry Andric         inc = 2;
54730b57cec5SDimitry Andric       break;
54740b57cec5SDimitry Andric     case 2:
54750b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
54760b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
54770b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
54780b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
54790b57cec5SDimitry Andric         align = 8;
54800b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
54810b57cec5SDimitry Andric         inc = 2;
54820b57cec5SDimitry Andric       break;
54830b57cec5SDimitry Andric   }
54840b57cec5SDimitry Andric 
54850b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
54860b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54870b57cec5SDimitry Andric       return MCDisassembler::Fail;
54880b57cec5SDimitry Andric   }
54890b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
54900b57cec5SDimitry Andric     return MCDisassembler::Fail;
54910b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
54920b57cec5SDimitry Andric   if (Rm != 0xF) {
54930b57cec5SDimitry Andric     if (Rm != 0xD) {
54940b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
54950b57cec5SDimitry Andric         return MCDisassembler::Fail;
54960b57cec5SDimitry Andric     } else
54970b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
54980b57cec5SDimitry Andric   }
54990b57cec5SDimitry Andric 
55000b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
55010b57cec5SDimitry Andric     return MCDisassembler::Fail;
55020b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
55030b57cec5SDimitry Andric     return MCDisassembler::Fail;
55040b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
55050b57cec5SDimitry Andric 
55060b57cec5SDimitry Andric   return S;
55070b57cec5SDimitry Andric }
55080b57cec5SDimitry Andric 
550981ad6265SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
551081ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
55110b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55120b57cec5SDimitry Andric 
55130b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
55140b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
55150b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
55160b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
55170b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
55180b57cec5SDimitry Andric 
55190b57cec5SDimitry Andric   unsigned align = 0;
55200b57cec5SDimitry Andric   unsigned index = 0;
55210b57cec5SDimitry Andric   unsigned inc = 1;
55220b57cec5SDimitry Andric   switch (size) {
55230b57cec5SDimitry Andric     default:
55240b57cec5SDimitry Andric       return MCDisassembler::Fail;
55250b57cec5SDimitry Andric     case 0:
55260b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55270b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55280b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
55290b57cec5SDimitry Andric       break;
55300b57cec5SDimitry Andric     case 1:
55310b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55320b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55330b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
55340b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
55350b57cec5SDimitry Andric         inc = 2;
55360b57cec5SDimitry Andric       break;
55370b57cec5SDimitry Andric     case 2:
55380b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
55390b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55400b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
55410b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
55420b57cec5SDimitry Andric         inc = 2;
55430b57cec5SDimitry Andric       break;
55440b57cec5SDimitry Andric   }
55450b57cec5SDimitry Andric 
55460b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
55470b57cec5SDimitry Andric     return MCDisassembler::Fail;
55480b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
55490b57cec5SDimitry Andric     return MCDisassembler::Fail;
55500b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
55510b57cec5SDimitry Andric     return MCDisassembler::Fail;
55520b57cec5SDimitry Andric 
55530b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
55540b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
55550b57cec5SDimitry Andric     return MCDisassembler::Fail;
55560b57cec5SDimitry Andric   }
55570b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
55580b57cec5SDimitry Andric     return MCDisassembler::Fail;
55590b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
55600b57cec5SDimitry Andric   if (Rm != 0xF) {
55610b57cec5SDimitry Andric     if (Rm != 0xD) {
55620b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
55630b57cec5SDimitry Andric     return MCDisassembler::Fail;
55640b57cec5SDimitry Andric     } else
55650b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
55660b57cec5SDimitry Andric   }
55670b57cec5SDimitry Andric 
55680b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
55690b57cec5SDimitry Andric     return MCDisassembler::Fail;
55700b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
55710b57cec5SDimitry Andric     return MCDisassembler::Fail;
55720b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
55730b57cec5SDimitry Andric     return MCDisassembler::Fail;
55740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
55750b57cec5SDimitry Andric 
55760b57cec5SDimitry Andric   return S;
55770b57cec5SDimitry Andric }
55780b57cec5SDimitry Andric 
557981ad6265SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
558081ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
55810b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
55820b57cec5SDimitry Andric 
55830b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
55840b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
55850b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
55860b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
55870b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
55880b57cec5SDimitry Andric 
55890b57cec5SDimitry Andric   unsigned align = 0;
55900b57cec5SDimitry Andric   unsigned index = 0;
55910b57cec5SDimitry Andric   unsigned inc = 1;
55920b57cec5SDimitry Andric   switch (size) {
55930b57cec5SDimitry Andric     default:
55940b57cec5SDimitry Andric       return MCDisassembler::Fail;
55950b57cec5SDimitry Andric     case 0:
55960b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
55970b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
55980b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
55990b57cec5SDimitry Andric       break;
56000b57cec5SDimitry Andric     case 1:
56010b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
56020b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
56030b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
56040b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
56050b57cec5SDimitry Andric         inc = 2;
56060b57cec5SDimitry Andric       break;
56070b57cec5SDimitry Andric     case 2:
56080b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
56090b57cec5SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
56100b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
56110b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
56120b57cec5SDimitry Andric         inc = 2;
56130b57cec5SDimitry Andric       break;
56140b57cec5SDimitry Andric   }
56150b57cec5SDimitry Andric 
56160b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
56170b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56180b57cec5SDimitry Andric     return MCDisassembler::Fail;
56190b57cec5SDimitry Andric   }
56200b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56210b57cec5SDimitry Andric     return MCDisassembler::Fail;
56220b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
56230b57cec5SDimitry Andric   if (Rm != 0xF) {
56240b57cec5SDimitry Andric     if (Rm != 0xD) {
56250b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
56260b57cec5SDimitry Andric     return MCDisassembler::Fail;
56270b57cec5SDimitry Andric     } else
56280b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
56290b57cec5SDimitry Andric   }
56300b57cec5SDimitry Andric 
56310b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
56320b57cec5SDimitry Andric     return MCDisassembler::Fail;
56330b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
56340b57cec5SDimitry Andric     return MCDisassembler::Fail;
56350b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
56360b57cec5SDimitry Andric     return MCDisassembler::Fail;
56370b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
56380b57cec5SDimitry Andric 
56390b57cec5SDimitry Andric   return S;
56400b57cec5SDimitry Andric }
56410b57cec5SDimitry Andric 
564281ad6265SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
564381ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
56440b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
56450b57cec5SDimitry Andric 
56460b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
56470b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
56480b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
56490b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
56500b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
56510b57cec5SDimitry Andric 
56520b57cec5SDimitry Andric   unsigned align = 0;
56530b57cec5SDimitry Andric   unsigned index = 0;
56540b57cec5SDimitry Andric   unsigned inc = 1;
56550b57cec5SDimitry Andric   switch (size) {
56560b57cec5SDimitry Andric     default:
56570b57cec5SDimitry Andric       return MCDisassembler::Fail;
56580b57cec5SDimitry Andric     case 0:
56590b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
56600b57cec5SDimitry Andric         align = 4;
56610b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
56620b57cec5SDimitry Andric       break;
56630b57cec5SDimitry Andric     case 1:
56640b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
56650b57cec5SDimitry Andric         align = 8;
56660b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
56670b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
56680b57cec5SDimitry Andric         inc = 2;
56690b57cec5SDimitry Andric       break;
56700b57cec5SDimitry Andric     case 2:
56710b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
56720b57cec5SDimitry Andric         case 0:
56730b57cec5SDimitry Andric           align = 0; break;
56740b57cec5SDimitry Andric         case 3:
56750b57cec5SDimitry Andric           return MCDisassembler::Fail;
56760b57cec5SDimitry Andric         default:
56770b57cec5SDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
56780b57cec5SDimitry Andric       }
56790b57cec5SDimitry Andric 
56800b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
56810b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
56820b57cec5SDimitry Andric         inc = 2;
56830b57cec5SDimitry Andric       break;
56840b57cec5SDimitry Andric   }
56850b57cec5SDimitry Andric 
56860b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
56870b57cec5SDimitry Andric     return MCDisassembler::Fail;
56880b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
56890b57cec5SDimitry Andric     return MCDisassembler::Fail;
56900b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
56910b57cec5SDimitry Andric     return MCDisassembler::Fail;
56920b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
56930b57cec5SDimitry Andric     return MCDisassembler::Fail;
56940b57cec5SDimitry Andric 
56950b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
56960b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
56970b57cec5SDimitry Andric       return MCDisassembler::Fail;
56980b57cec5SDimitry Andric   }
56990b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
57000b57cec5SDimitry Andric     return MCDisassembler::Fail;
57010b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
57020b57cec5SDimitry Andric   if (Rm != 0xF) {
57030b57cec5SDimitry Andric     if (Rm != 0xD) {
57040b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
57050b57cec5SDimitry Andric         return MCDisassembler::Fail;
57060b57cec5SDimitry Andric     } else
57070b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
57080b57cec5SDimitry Andric   }
57090b57cec5SDimitry Andric 
57100b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
57110b57cec5SDimitry Andric     return MCDisassembler::Fail;
57120b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
57130b57cec5SDimitry Andric     return MCDisassembler::Fail;
57140b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
57150b57cec5SDimitry Andric     return MCDisassembler::Fail;
57160b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
57170b57cec5SDimitry Andric     return MCDisassembler::Fail;
57180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
57190b57cec5SDimitry Andric 
57200b57cec5SDimitry Andric   return S;
57210b57cec5SDimitry Andric }
57220b57cec5SDimitry Andric 
572381ad6265SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
572481ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
57250b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
57260b57cec5SDimitry Andric 
57270b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
57280b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
57290b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
57300b57cec5SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
57310b57cec5SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
57320b57cec5SDimitry Andric 
57330b57cec5SDimitry Andric   unsigned align = 0;
57340b57cec5SDimitry Andric   unsigned index = 0;
57350b57cec5SDimitry Andric   unsigned inc = 1;
57360b57cec5SDimitry Andric   switch (size) {
57370b57cec5SDimitry Andric     default:
57380b57cec5SDimitry Andric       return MCDisassembler::Fail;
57390b57cec5SDimitry Andric     case 0:
57400b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
57410b57cec5SDimitry Andric         align = 4;
57420b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
57430b57cec5SDimitry Andric       break;
57440b57cec5SDimitry Andric     case 1:
57450b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
57460b57cec5SDimitry Andric         align = 8;
57470b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
57480b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
57490b57cec5SDimitry Andric         inc = 2;
57500b57cec5SDimitry Andric       break;
57510b57cec5SDimitry Andric     case 2:
57520b57cec5SDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
57530b57cec5SDimitry Andric         case 0:
57540b57cec5SDimitry Andric           align = 0; break;
57550b57cec5SDimitry Andric         case 3:
57560b57cec5SDimitry Andric           return MCDisassembler::Fail;
57570b57cec5SDimitry Andric         default:
57580b57cec5SDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
57590b57cec5SDimitry Andric       }
57600b57cec5SDimitry Andric 
57610b57cec5SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
57620b57cec5SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
57630b57cec5SDimitry Andric         inc = 2;
57640b57cec5SDimitry Andric       break;
57650b57cec5SDimitry Andric   }
57660b57cec5SDimitry Andric 
57670b57cec5SDimitry Andric   if (Rm != 0xF) { // Writeback
57680b57cec5SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
57690b57cec5SDimitry Andric     return MCDisassembler::Fail;
57700b57cec5SDimitry Andric   }
57710b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
57720b57cec5SDimitry Andric     return MCDisassembler::Fail;
57730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
57740b57cec5SDimitry Andric   if (Rm != 0xF) {
57750b57cec5SDimitry Andric     if (Rm != 0xD) {
57760b57cec5SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
57770b57cec5SDimitry Andric     return MCDisassembler::Fail;
57780b57cec5SDimitry Andric     } else
57790b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
57800b57cec5SDimitry Andric   }
57810b57cec5SDimitry Andric 
57820b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
57830b57cec5SDimitry Andric     return MCDisassembler::Fail;
57840b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
57850b57cec5SDimitry Andric     return MCDisassembler::Fail;
57860b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
57870b57cec5SDimitry Andric     return MCDisassembler::Fail;
57880b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
57890b57cec5SDimitry Andric     return MCDisassembler::Fail;
57900b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
57910b57cec5SDimitry Andric 
57920b57cec5SDimitry Andric   return S;
57930b57cec5SDimitry Andric }
57940b57cec5SDimitry Andric 
579581ad6265SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, uint64_t Address,
579681ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
57970b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
57980b57cec5SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
57990b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
58000b57cec5SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
58010b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
58020b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
58030b57cec5SDimitry Andric 
58040b57cec5SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
58050b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58060b57cec5SDimitry Andric 
58070b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
58080b57cec5SDimitry Andric     return MCDisassembler::Fail;
58090b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
58100b57cec5SDimitry Andric     return MCDisassembler::Fail;
58110b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
58120b57cec5SDimitry Andric     return MCDisassembler::Fail;
58130b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
58140b57cec5SDimitry Andric     return MCDisassembler::Fail;
58150b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
58160b57cec5SDimitry Andric     return MCDisassembler::Fail;
58170b57cec5SDimitry Andric 
58180b57cec5SDimitry Andric   return S;
58190b57cec5SDimitry Andric }
58200b57cec5SDimitry Andric 
582181ad6265SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, uint64_t Address,
582281ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
58230b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58240b57cec5SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
58250b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
58260b57cec5SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
58270b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
58280b57cec5SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
58290b57cec5SDimitry Andric 
58300b57cec5SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
58310b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58320b57cec5SDimitry Andric 
58330b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
58340b57cec5SDimitry Andric     return MCDisassembler::Fail;
58350b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
58360b57cec5SDimitry Andric     return MCDisassembler::Fail;
58370b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
58380b57cec5SDimitry Andric     return MCDisassembler::Fail;
58390b57cec5SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
58400b57cec5SDimitry Andric     return MCDisassembler::Fail;
58410b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
58420b57cec5SDimitry Andric     return MCDisassembler::Fail;
58430b57cec5SDimitry Andric 
58440b57cec5SDimitry Andric   return S;
58450b57cec5SDimitry Andric }
58460b57cec5SDimitry Andric 
584781ad6265SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, uint64_t Address,
584881ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
58490b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58500b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 4, 4);
58510b57cec5SDimitry Andric   unsigned mask = fieldFromInstruction(Insn, 0, 4);
58520b57cec5SDimitry Andric 
58530b57cec5SDimitry Andric   if (pred == 0xF) {
58540b57cec5SDimitry Andric     pred = 0xE;
58550b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
58560b57cec5SDimitry Andric   }
58570b57cec5SDimitry Andric 
58580b57cec5SDimitry Andric   if (mask == 0x0)
58590b57cec5SDimitry Andric     return MCDisassembler::Fail;
58600b57cec5SDimitry Andric 
58610b57cec5SDimitry Andric   // IT masks are encoded as a sequence of replacement low-order bits
58620b57cec5SDimitry Andric   // for the condition code. So if the low bit of the starting
58630b57cec5SDimitry Andric   // condition code is 1, then we have to flip all the bits above the
58640b57cec5SDimitry Andric   // terminating bit (which is the lowest 1 bit).
58650b57cec5SDimitry Andric   if (pred & 1) {
58660b57cec5SDimitry Andric     unsigned LowBit = mask & -mask;
58670b57cec5SDimitry Andric     unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
58680b57cec5SDimitry Andric     mask ^= BitsAboveLowBit;
58690b57cec5SDimitry Andric   }
58700b57cec5SDimitry Andric 
58710b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(pred));
58720b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(mask));
58730b57cec5SDimitry Andric   return S;
58740b57cec5SDimitry Andric }
58750b57cec5SDimitry Andric 
587681ad6265SDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
587781ad6265SDimitry Andric                                                uint64_t Address,
587881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
58790b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
58800b57cec5SDimitry Andric 
58810b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
58820b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
58830b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
58840b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
58850b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
58860b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
58870b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
58880b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
58890b57cec5SDimitry Andric 
58900b57cec5SDimitry Andric   addr |= (U << 8) | (Rn << 9);
58910b57cec5SDimitry Andric 
58920b57cec5SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
58930b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
58940b57cec5SDimitry Andric   if (Rt == Rt2)
58950b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
58960b57cec5SDimitry Andric 
58970b57cec5SDimitry Andric   // Rt
58980b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
58990b57cec5SDimitry Andric     return MCDisassembler::Fail;
59000b57cec5SDimitry Andric   // Rt2
59010b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
59020b57cec5SDimitry Andric     return MCDisassembler::Fail;
59030b57cec5SDimitry Andric   // Writeback operand
59040b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
59050b57cec5SDimitry Andric     return MCDisassembler::Fail;
59060b57cec5SDimitry Andric   // addr
59070b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
59080b57cec5SDimitry Andric     return MCDisassembler::Fail;
59090b57cec5SDimitry Andric 
59100b57cec5SDimitry Andric   return S;
59110b57cec5SDimitry Andric }
59120b57cec5SDimitry Andric 
591381ad6265SDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
591481ad6265SDimitry Andric                                                uint64_t Address,
591581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
59160b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59170b57cec5SDimitry Andric 
59180b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
59190b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
59200b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
59210b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
59220b57cec5SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
59230b57cec5SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
59240b57cec5SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
59250b57cec5SDimitry Andric   bool writeback = (W == 1) | (P == 0);
59260b57cec5SDimitry Andric 
59270b57cec5SDimitry Andric   addr |= (U << 8) | (Rn << 9);
59280b57cec5SDimitry Andric 
59290b57cec5SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
59300b57cec5SDimitry Andric     Check(S, MCDisassembler::SoftFail);
59310b57cec5SDimitry Andric 
59320b57cec5SDimitry Andric   // Writeback operand
59330b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
59340b57cec5SDimitry Andric     return MCDisassembler::Fail;
59350b57cec5SDimitry Andric   // Rt
59360b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
59370b57cec5SDimitry Andric     return MCDisassembler::Fail;
59380b57cec5SDimitry Andric   // Rt2
59390b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
59400b57cec5SDimitry Andric     return MCDisassembler::Fail;
59410b57cec5SDimitry Andric   // addr
59420b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
59430b57cec5SDimitry Andric     return MCDisassembler::Fail;
59440b57cec5SDimitry Andric 
59450b57cec5SDimitry Andric   return S;
59460b57cec5SDimitry Andric }
59470b57cec5SDimitry Andric 
594881ad6265SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, uint64_t Address,
594981ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
59500b57cec5SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
59510b57cec5SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
59520b57cec5SDimitry Andric   if (sign1 != sign2) return MCDisassembler::Fail;
5953480093f4SDimitry Andric   const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
5954480093f4SDimitry Andric   assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst");
5955480093f4SDimitry Andric   DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder);
59560b57cec5SDimitry Andric 
59570b57cec5SDimitry Andric   unsigned Val = fieldFromInstruction(Insn, 0, 8);
59580b57cec5SDimitry Andric   Val |= fieldFromInstruction(Insn, 12, 3) << 8;
59590b57cec5SDimitry Andric   Val |= fieldFromInstruction(Insn, 26, 1) << 11;
5960480093f4SDimitry Andric   // If sign, then it is decreasing the address.
5961480093f4SDimitry Andric   if (sign1) {
5962480093f4SDimitry Andric     // Following ARMv7 Architecture Manual, when the offset
5963480093f4SDimitry Andric     // is zero, it is decoded as a subw, not as a adr.w
5964480093f4SDimitry Andric     if (!Val) {
5965480093f4SDimitry Andric       Inst.setOpcode(ARM::t2SUBri12);
5966480093f4SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::PC));
5967480093f4SDimitry Andric     } else
5968480093f4SDimitry Andric       Val = -Val;
5969480093f4SDimitry Andric   }
5970480093f4SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
5971480093f4SDimitry Andric   return S;
59720b57cec5SDimitry Andric }
59730b57cec5SDimitry Andric 
59740b57cec5SDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
59750b57cec5SDimitry Andric                                               uint64_t Address,
597681ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
59770b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59780b57cec5SDimitry Andric 
59790b57cec5SDimitry Andric   // Shift of "asr #32" is not allowed in Thumb2 mode.
59800b57cec5SDimitry Andric   if (Val == 0x20) S = MCDisassembler::Fail;
59810b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
59820b57cec5SDimitry Andric   return S;
59830b57cec5SDimitry Andric }
59840b57cec5SDimitry Andric 
598581ad6265SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, uint64_t Address,
598681ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
59870b57cec5SDimitry Andric   unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
59880b57cec5SDimitry Andric   unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
59890b57cec5SDimitry Andric   unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
59900b57cec5SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
59910b57cec5SDimitry Andric 
59920b57cec5SDimitry Andric   if (pred == 0xF)
59930b57cec5SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
59940b57cec5SDimitry Andric 
59950b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
59960b57cec5SDimitry Andric 
59970b57cec5SDimitry Andric   if (Rt == Rn || Rn == Rt2)
59980b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
59990b57cec5SDimitry Andric 
60000b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
60010b57cec5SDimitry Andric     return MCDisassembler::Fail;
60020b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
60030b57cec5SDimitry Andric     return MCDisassembler::Fail;
60040b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
60050b57cec5SDimitry Andric     return MCDisassembler::Fail;
60060b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
60070b57cec5SDimitry Andric     return MCDisassembler::Fail;
60080b57cec5SDimitry Andric 
60090b57cec5SDimitry Andric   return S;
60100b57cec5SDimitry Andric }
60110b57cec5SDimitry Andric 
601281ad6265SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, uint64_t Address,
601381ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
60140b57cec5SDimitry Andric   const FeatureBitset &featureBits =
60150b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
60160b57cec5SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
60170b57cec5SDimitry Andric 
60180b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
60190b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
60200b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
60210b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
60220b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
60230b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
60240b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
60250b57cec5SDimitry Andric 
60260b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
60270b57cec5SDimitry Andric 
60280b57cec5SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
60290b57cec5SDimitry Andric   if (!(imm & 0x38)) {
60300b57cec5SDimitry Andric     if (cmode == 0xF) {
60310b57cec5SDimitry Andric       if (op == 1) return MCDisassembler::Fail;
60320b57cec5SDimitry Andric       Inst.setOpcode(ARM::VMOVv2f32);
60330b57cec5SDimitry Andric     }
60340b57cec5SDimitry Andric     if (hasFullFP16) {
60350b57cec5SDimitry Andric       if (cmode == 0xE) {
60360b57cec5SDimitry Andric         if (op == 1) {
60370b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv1i64);
60380b57cec5SDimitry Andric         } else {
60390b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv8i8);
60400b57cec5SDimitry Andric         }
60410b57cec5SDimitry Andric       }
60420b57cec5SDimitry Andric       if (cmode == 0xD) {
60430b57cec5SDimitry Andric         if (op == 1) {
60440b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
60450b57cec5SDimitry Andric         } else {
60460b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
60470b57cec5SDimitry Andric         }
60480b57cec5SDimitry Andric       }
60490b57cec5SDimitry Andric       if (cmode == 0xC) {
60500b57cec5SDimitry Andric         if (op == 1) {
60510b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
60520b57cec5SDimitry Andric         } else {
60530b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
60540b57cec5SDimitry Andric         }
60550b57cec5SDimitry Andric       }
60560b57cec5SDimitry Andric     }
60578bcb0991SDimitry Andric     return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
60580b57cec5SDimitry Andric   }
60590b57cec5SDimitry Andric 
60600b57cec5SDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
60610b57cec5SDimitry Andric 
60620b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
60630b57cec5SDimitry Andric     return MCDisassembler::Fail;
60640b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
60650b57cec5SDimitry Andric     return MCDisassembler::Fail;
60660b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
60670b57cec5SDimitry Andric 
60680b57cec5SDimitry Andric   return S;
60690b57cec5SDimitry Andric }
60700b57cec5SDimitry Andric 
607181ad6265SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, uint64_t Address,
607281ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
60730b57cec5SDimitry Andric   const FeatureBitset &featureBits =
60740b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
60750b57cec5SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
60760b57cec5SDimitry Andric 
60770b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
60780b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
60790b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
60800b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
60810b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
60820b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
60830b57cec5SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
60840b57cec5SDimitry Andric 
60850b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
60860b57cec5SDimitry Andric 
60870b57cec5SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
60880b57cec5SDimitry Andric   if (!(imm & 0x38)) {
60890b57cec5SDimitry Andric     if (cmode == 0xF) {
60900b57cec5SDimitry Andric       if (op == 1) return MCDisassembler::Fail;
60910b57cec5SDimitry Andric       Inst.setOpcode(ARM::VMOVv4f32);
60920b57cec5SDimitry Andric     }
60930b57cec5SDimitry Andric     if (hasFullFP16) {
60940b57cec5SDimitry Andric       if (cmode == 0xE) {
60950b57cec5SDimitry Andric         if (op == 1) {
60960b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i64);
60970b57cec5SDimitry Andric         } else {
60980b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv16i8);
60990b57cec5SDimitry Andric         }
61000b57cec5SDimitry Andric       }
61010b57cec5SDimitry Andric       if (cmode == 0xD) {
61020b57cec5SDimitry Andric         if (op == 1) {
61030b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
61040b57cec5SDimitry Andric         } else {
61050b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
61060b57cec5SDimitry Andric         }
61070b57cec5SDimitry Andric       }
61080b57cec5SDimitry Andric       if (cmode == 0xC) {
61090b57cec5SDimitry Andric         if (op == 1) {
61100b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
61110b57cec5SDimitry Andric         } else {
61120b57cec5SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
61130b57cec5SDimitry Andric         }
61140b57cec5SDimitry Andric       }
61150b57cec5SDimitry Andric     }
61168bcb0991SDimitry Andric     return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
61170b57cec5SDimitry Andric   }
61180b57cec5SDimitry Andric 
61190b57cec5SDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
61200b57cec5SDimitry Andric 
61210b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
61220b57cec5SDimitry Andric     return MCDisassembler::Fail;
61230b57cec5SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
61240b57cec5SDimitry Andric     return MCDisassembler::Fail;
61250b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
61260b57cec5SDimitry Andric 
61270b57cec5SDimitry Andric   return S;
61280b57cec5SDimitry Andric }
61290b57cec5SDimitry Andric 
613081ad6265SDimitry Andric static DecodeStatus
613181ad6265SDimitry Andric DecodeNEONComplexLane64Instruction(MCInst &Inst, unsigned Insn,
61320b57cec5SDimitry Andric                                    uint64_t Address,
613381ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
61340b57cec5SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
61350b57cec5SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
61360b57cec5SDimitry Andric   unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
61370b57cec5SDimitry Andric   Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
61380b57cec5SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
61390b57cec5SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
61400b57cec5SDimitry Andric   unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
61410b57cec5SDimitry Andric   unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
61420b57cec5SDimitry Andric 
61430b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61440b57cec5SDimitry Andric 
61450b57cec5SDimitry Andric   auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
61460b57cec5SDimitry Andric 
61470b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
61480b57cec5SDimitry Andric     return MCDisassembler::Fail;
61490b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
61500b57cec5SDimitry Andric     return MCDisassembler::Fail;
61510b57cec5SDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
61520b57cec5SDimitry Andric     return MCDisassembler::Fail;
61530b57cec5SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
61540b57cec5SDimitry Andric     return MCDisassembler::Fail;
61550b57cec5SDimitry Andric   // The lane index does not have any bits in the encoding, because it can only
61560b57cec5SDimitry Andric   // be 0.
61570b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
61580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(rotate));
61590b57cec5SDimitry Andric 
61600b57cec5SDimitry Andric   return S;
61610b57cec5SDimitry Andric }
61620b57cec5SDimitry Andric 
616381ad6265SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address,
616481ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
61650b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61660b57cec5SDimitry Andric 
61670b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
61680b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
61690b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
61700b57cec5SDimitry Andric   Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
61710b57cec5SDimitry Andric   unsigned Cond = fieldFromInstruction(Val, 28, 4);
61720b57cec5SDimitry Andric 
61730b57cec5SDimitry Andric   if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
61740b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
61750b57cec5SDimitry Andric 
61760b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
61770b57cec5SDimitry Andric     return MCDisassembler::Fail;
61780b57cec5SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
61790b57cec5SDimitry Andric     return MCDisassembler::Fail;
61800b57cec5SDimitry Andric   if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
61810b57cec5SDimitry Andric     return MCDisassembler::Fail;
61820b57cec5SDimitry Andric   if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
61830b57cec5SDimitry Andric     return MCDisassembler::Fail;
61840b57cec5SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
61850b57cec5SDimitry Andric     return MCDisassembler::Fail;
61860b57cec5SDimitry Andric 
61870b57cec5SDimitry Andric   return S;
61880b57cec5SDimitry Andric }
61890b57cec5SDimitry Andric 
61900b57cec5SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
619181ad6265SDimitry Andric                                             uint64_t Address,
619281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
61930b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
61940b57cec5SDimitry Andric 
61950b57cec5SDimitry Andric   unsigned CRm = fieldFromInstruction(Val, 0, 4);
61960b57cec5SDimitry Andric   unsigned opc1 = fieldFromInstruction(Val, 4, 4);
61970b57cec5SDimitry Andric   unsigned cop = fieldFromInstruction(Val, 8, 4);
61980b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
61990b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
62000b57cec5SDimitry Andric 
62010b57cec5SDimitry Andric   if ((cop & ~0x1) == 0xa)
62020b57cec5SDimitry Andric     return MCDisassembler::Fail;
62030b57cec5SDimitry Andric 
62040b57cec5SDimitry Andric   if (Rt == Rt2)
62050b57cec5SDimitry Andric     S = MCDisassembler::SoftFail;
62060b57cec5SDimitry Andric 
62070b57cec5SDimitry Andric   // We have to check if the instruction is MRRC2
62080b57cec5SDimitry Andric   // or MCRR2 when constructing the operands for
62090b57cec5SDimitry Andric   // Inst. Reason is because MRRC2 stores to two
62105f757f3fSDimitry Andric   // registers so it's tablegen desc has two
62110b57cec5SDimitry Andric   // outputs whereas MCRR doesn't store to any
62120b57cec5SDimitry Andric   // registers so all of it's operands are listed
62130b57cec5SDimitry Andric   // as inputs, therefore the operand order for
62140b57cec5SDimitry Andric   // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
62150b57cec5SDimitry Andric   // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
62160b57cec5SDimitry Andric 
62170b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MRRC2) {
62180b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
62190b57cec5SDimitry Andric       return MCDisassembler::Fail;
62200b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
62210b57cec5SDimitry Andric       return MCDisassembler::Fail;
62220b57cec5SDimitry Andric   }
62230b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(cop));
62240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(opc1));
62250b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MCRR2) {
62260b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
62270b57cec5SDimitry Andric       return MCDisassembler::Fail;
62280b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
62290b57cec5SDimitry Andric       return MCDisassembler::Fail;
62300b57cec5SDimitry Andric   }
62310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRm));
62320b57cec5SDimitry Andric 
62330b57cec5SDimitry Andric   return S;
62340b57cec5SDimitry Andric }
62350b57cec5SDimitry Andric 
62360b57cec5SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
62370b57cec5SDimitry Andric                                          uint64_t Address,
623881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
62390b57cec5SDimitry Andric   const FeatureBitset &featureBits =
62400b57cec5SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
62410b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
62420b57cec5SDimitry Andric 
62430b57cec5SDimitry Andric   // Add explicit operand for the destination sysreg, for cases where
62440b57cec5SDimitry Andric   // we have to model it for code generation purposes.
62450b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
62460b57cec5SDimitry Andric   case ARM::VMSR_FPSCR_NZCVQC:
62470b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
62480b57cec5SDimitry Andric     break;
62490b57cec5SDimitry Andric   case ARM::VMSR_P0:
62500b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::VPR));
62510b57cec5SDimitry Andric     break;
62520b57cec5SDimitry Andric   }
62530b57cec5SDimitry Andric 
62540b57cec5SDimitry Andric   if (Inst.getOpcode() != ARM::FMSTAT) {
62550b57cec5SDimitry Andric     unsigned Rt = fieldFromInstruction(Val, 12, 4);
62560b57cec5SDimitry Andric 
62570b57cec5SDimitry Andric     if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
62580b57cec5SDimitry Andric       if (Rt == 13 || Rt == 15)
62590b57cec5SDimitry Andric         S = MCDisassembler::SoftFail;
62600b57cec5SDimitry Andric       Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
62610b57cec5SDimitry Andric     } else
62620b57cec5SDimitry Andric       Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
62630b57cec5SDimitry Andric   }
62640b57cec5SDimitry Andric 
62650b57cec5SDimitry Andric   // Add explicit operand for the source sysreg, similarly to above.
62660b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
62670b57cec5SDimitry Andric   case ARM::VMRS_FPSCR_NZCVQC:
62680b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
62690b57cec5SDimitry Andric     break;
62700b57cec5SDimitry Andric   case ARM::VMRS_P0:
62710b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::VPR));
62720b57cec5SDimitry Andric     break;
62730b57cec5SDimitry Andric   }
62740b57cec5SDimitry Andric 
62750b57cec5SDimitry Andric   if (featureBits[ARM::ModeThumb]) {
62760b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARMCC::AL));
62770b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
62780b57cec5SDimitry Andric   } else {
62790b57cec5SDimitry Andric     unsigned pred = fieldFromInstruction(Val, 28, 4);
62800b57cec5SDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
62810b57cec5SDimitry Andric       return MCDisassembler::Fail;
62820b57cec5SDimitry Andric   }
62830b57cec5SDimitry Andric 
62840b57cec5SDimitry Andric   return S;
62850b57cec5SDimitry Andric }
62860b57cec5SDimitry Andric 
62870b57cec5SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
62880b57cec5SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned Val,
62890b57cec5SDimitry Andric                                          uint64_t Address,
629081ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
62910b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
62920b57cec5SDimitry Andric   if (Val == 0 && !zeroPermitted)
62930b57cec5SDimitry Andric     S = MCDisassembler::Fail;
62940b57cec5SDimitry Andric 
62950b57cec5SDimitry Andric   uint64_t DecVal;
62960b57cec5SDimitry Andric   if (isSigned)
62970b57cec5SDimitry Andric     DecVal = SignExtend32<size + 1>(Val << 1);
62980b57cec5SDimitry Andric   else
62990b57cec5SDimitry Andric     DecVal = (Val << 1);
63000b57cec5SDimitry Andric 
63010b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + DecVal + 4, true, 4, Inst,
63020b57cec5SDimitry Andric                                 Decoder))
63030b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(isNeg ? -DecVal : DecVal));
63040b57cec5SDimitry Andric   return S;
63050b57cec5SDimitry Andric }
63060b57cec5SDimitry Andric 
63070b57cec5SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned Val,
63080b57cec5SDimitry Andric                                                uint64_t Address,
630981ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
63100b57cec5SDimitry Andric 
63110b57cec5SDimitry Andric   uint64_t LocImm = Inst.getOperand(0).getImm();
63120b57cec5SDimitry Andric   Val = LocImm + (2 << Val);
63130b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + Val + 4, true, 4, Inst,
63140b57cec5SDimitry Andric                                 Decoder))
63150b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val));
63160b57cec5SDimitry Andric   return MCDisassembler::Success;
63170b57cec5SDimitry Andric }
63180b57cec5SDimitry Andric 
63190b57cec5SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
63200b57cec5SDimitry Andric                                           uint64_t Address,
632181ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
63220b57cec5SDimitry Andric   if (Val >= ARMCC::AL)  // also exclude the non-condition NV
63230b57cec5SDimitry Andric     return MCDisassembler::Fail;
63240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
63250b57cec5SDimitry Andric   return MCDisassembler::Success;
63260b57cec5SDimitry Andric }
63270b57cec5SDimitry Andric 
63280b57cec5SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
632981ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
63300b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63310b57cec5SDimitry Andric 
63320b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::MVE_LCTP)
63330b57cec5SDimitry Andric     return S;
63340b57cec5SDimitry Andric 
63350b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 11, 1) |
63360b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 1, 10) << 1;
63370b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
63380b57cec5SDimitry Andric   case ARM::t2LEUpdate:
63390b57cec5SDimitry Andric   case ARM::MVE_LETP:
63400b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
63410b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
6342bdd1243dSDimitry Andric     [[fallthrough]];
63430b57cec5SDimitry Andric   case ARM::t2LE:
63440b57cec5SDimitry Andric     if (!Check(S, DecodeBFLabelOperand<false, true, true, 11>(
63450b57cec5SDimitry Andric                    Inst, Imm, Address, Decoder)))
63460b57cec5SDimitry Andric       return MCDisassembler::Fail;
63470b57cec5SDimitry Andric     break;
63480b57cec5SDimitry Andric   case ARM::t2WLS:
63490b57cec5SDimitry Andric   case ARM::MVE_WLSTP_8:
63500b57cec5SDimitry Andric   case ARM::MVE_WLSTP_16:
63510b57cec5SDimitry Andric   case ARM::MVE_WLSTP_32:
63520b57cec5SDimitry Andric   case ARM::MVE_WLSTP_64:
63530b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::LR));
63540b57cec5SDimitry Andric     if (!Check(S,
63550b57cec5SDimitry Andric                DecoderGPRRegisterClass(Inst, fieldFromInstruction(Insn, 16, 4),
63560b57cec5SDimitry Andric                                        Address, Decoder)) ||
63570b57cec5SDimitry Andric         !Check(S, DecodeBFLabelOperand<false, false, true, 11>(
63580b57cec5SDimitry Andric                    Inst, Imm, Address, Decoder)))
63590b57cec5SDimitry Andric       return MCDisassembler::Fail;
63600b57cec5SDimitry Andric     break;
63610b57cec5SDimitry Andric   case ARM::t2DLS:
63620b57cec5SDimitry Andric   case ARM::MVE_DLSTP_8:
63630b57cec5SDimitry Andric   case ARM::MVE_DLSTP_16:
63640b57cec5SDimitry Andric   case ARM::MVE_DLSTP_32:
63650b57cec5SDimitry Andric   case ARM::MVE_DLSTP_64:
63660b57cec5SDimitry Andric     unsigned Rn = fieldFromInstruction(Insn, 16, 4);
63670b57cec5SDimitry Andric     if (Rn == 0xF) {
63680b57cec5SDimitry Andric       // Enforce all the rest of the instruction bits in LCTP, which
63690b57cec5SDimitry Andric       // won't have been reliably checked based on LCTP's own tablegen
63700b57cec5SDimitry Andric       // record, because we came to this decode by a roundabout route.
63710b57cec5SDimitry Andric       uint32_t CanonicalLCTP = 0xF00FE001, SBZMask = 0x00300FFE;
63720b57cec5SDimitry Andric       if ((Insn & ~SBZMask) != CanonicalLCTP)
63730b57cec5SDimitry Andric         return MCDisassembler::Fail;   // a mandatory bit is wrong: hard fail
63740b57cec5SDimitry Andric       if (Insn != CanonicalLCTP)
63750b57cec5SDimitry Andric         Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail
63760b57cec5SDimitry Andric 
63770b57cec5SDimitry Andric       Inst.setOpcode(ARM::MVE_LCTP);
63780b57cec5SDimitry Andric     } else {
63790b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::LR));
63800b57cec5SDimitry Andric       if (!Check(S, DecoderGPRRegisterClass(Inst,
63810b57cec5SDimitry Andric                                             fieldFromInstruction(Insn, 16, 4),
63820b57cec5SDimitry Andric                                             Address, Decoder)))
63830b57cec5SDimitry Andric         return MCDisassembler::Fail;
63840b57cec5SDimitry Andric     }
63850b57cec5SDimitry Andric     break;
63860b57cec5SDimitry Andric   }
63870b57cec5SDimitry Andric   return S;
63880b57cec5SDimitry Andric }
63890b57cec5SDimitry Andric 
63900b57cec5SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
63910b57cec5SDimitry Andric                                            uint64_t Address,
639281ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
63930b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
63940b57cec5SDimitry Andric 
63950b57cec5SDimitry Andric   if (Val == 0)
63960b57cec5SDimitry Andric     Val = 32;
63970b57cec5SDimitry Andric 
63980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
63990b57cec5SDimitry Andric 
64000b57cec5SDimitry Andric   return S;
64010b57cec5SDimitry Andric }
64020b57cec5SDimitry Andric 
64030b57cec5SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
640481ad6265SDimitry Andric                                                uint64_t Address,
640581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
64060b57cec5SDimitry Andric   if ((RegNo) + 1 > 11)
64070b57cec5SDimitry Andric     return MCDisassembler::Fail;
64080b57cec5SDimitry Andric 
64090b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[(RegNo) + 1];
64100b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64110b57cec5SDimitry Andric   return MCDisassembler::Success;
64120b57cec5SDimitry Andric }
64130b57cec5SDimitry Andric 
64140b57cec5SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
641581ad6265SDimitry Andric                                                 uint64_t Address,
641681ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
64170b57cec5SDimitry Andric   if ((RegNo) > 14)
64180b57cec5SDimitry Andric     return MCDisassembler::Fail;
64190b57cec5SDimitry Andric 
64200b57cec5SDimitry Andric   unsigned Register = GPRDecoderTable[(RegNo)];
64210b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64220b57cec5SDimitry Andric   return MCDisassembler::Success;
64230b57cec5SDimitry Andric }
64240b57cec5SDimitry Andric 
64255ffd83dbSDimitry Andric static DecodeStatus
64265ffd83dbSDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
642781ad6265SDimitry Andric                                         uint64_t Address,
642881ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
64295ffd83dbSDimitry Andric   if (RegNo == 15) {
64305ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
64315ffd83dbSDimitry Andric     return MCDisassembler::Success;
64325ffd83dbSDimitry Andric   }
64335ffd83dbSDimitry Andric 
64345ffd83dbSDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
64355ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64365ffd83dbSDimitry Andric 
64375ffd83dbSDimitry Andric   if (RegNo == 13)
64385ffd83dbSDimitry Andric     return MCDisassembler::SoftFail;
64395ffd83dbSDimitry Andric 
64405ffd83dbSDimitry Andric   return MCDisassembler::Success;
64415ffd83dbSDimitry Andric }
64425ffd83dbSDimitry Andric 
64430b57cec5SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
644481ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
64450b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
64460b57cec5SDimitry Andric 
64470b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMCC::AL));
64480b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
64490b57cec5SDimitry Andric   if (Inst.getOpcode() == ARM::VSCCLRMD) {
64500b57cec5SDimitry Andric     unsigned reglist = (fieldFromInstruction(Insn, 1, 7) << 1) |
64510b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 12, 4) << 8) |
64520b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 22, 1) << 12);
64530b57cec5SDimitry Andric     if (!Check(S, DecodeDPRRegListOperand(Inst, reglist, Address, Decoder))) {
64540b57cec5SDimitry Andric       return MCDisassembler::Fail;
64550b57cec5SDimitry Andric     }
64560b57cec5SDimitry Andric   } else {
64570b57cec5SDimitry Andric     unsigned reglist = fieldFromInstruction(Insn, 0, 8) |
64580b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 22, 1) << 8) |
64590b57cec5SDimitry Andric                        (fieldFromInstruction(Insn, 12, 4) << 9);
64600b57cec5SDimitry Andric     if (!Check(S, DecodeSPRRegListOperand(Inst, reglist, Address, Decoder))) {
64610b57cec5SDimitry Andric       return MCDisassembler::Fail;
64620b57cec5SDimitry Andric     }
64630b57cec5SDimitry Andric   }
64640b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
64650b57cec5SDimitry Andric 
64660b57cec5SDimitry Andric   return S;
64670b57cec5SDimitry Andric }
64680b57cec5SDimitry Andric 
64690b57cec5SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
64700b57cec5SDimitry Andric                                             uint64_t Address,
647181ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
64720b57cec5SDimitry Andric   if (RegNo > 7)
64730b57cec5SDimitry Andric     return MCDisassembler::Fail;
64740b57cec5SDimitry Andric 
64750b57cec5SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
64760b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64770b57cec5SDimitry Andric   return MCDisassembler::Success;
64780b57cec5SDimitry Andric }
64790b57cec5SDimitry Andric 
64800b57cec5SDimitry Andric static const uint16_t QQPRDecoderTable[] = {
64810b57cec5SDimitry Andric      ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
64820b57cec5SDimitry Andric      ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
64830b57cec5SDimitry Andric };
64840b57cec5SDimitry Andric 
6485349cc55cSDimitry Andric static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
64860b57cec5SDimitry Andric                                              uint64_t Address,
648781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
64880b57cec5SDimitry Andric   if (RegNo > 6)
64890b57cec5SDimitry Andric     return MCDisassembler::Fail;
64900b57cec5SDimitry Andric 
64910b57cec5SDimitry Andric   unsigned Register = QQPRDecoderTable[RegNo];
64920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
64930b57cec5SDimitry Andric   return MCDisassembler::Success;
64940b57cec5SDimitry Andric }
64950b57cec5SDimitry Andric 
64960b57cec5SDimitry Andric static const uint16_t QQQQPRDecoderTable[] = {
64970b57cec5SDimitry Andric      ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
64980b57cec5SDimitry Andric      ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
64990b57cec5SDimitry Andric };
65000b57cec5SDimitry Andric 
6501349cc55cSDimitry Andric static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
65020b57cec5SDimitry Andric                                                uint64_t Address,
650381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
65040b57cec5SDimitry Andric   if (RegNo > 4)
65050b57cec5SDimitry Andric     return MCDisassembler::Fail;
65060b57cec5SDimitry Andric 
65070b57cec5SDimitry Andric   unsigned Register = QQQQPRDecoderTable[RegNo];
65080b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
65090b57cec5SDimitry Andric   return MCDisassembler::Success;
65100b57cec5SDimitry Andric }
65110b57cec5SDimitry Andric 
65120b57cec5SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
65130b57cec5SDimitry Andric                                          uint64_t Address,
651481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
65150b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
65160b57cec5SDimitry Andric 
65170b57cec5SDimitry Andric   // Parse VPT mask and encode it in the MCInst as an immediate with the same
65180b57cec5SDimitry Andric   // format as the it_mask.  That is, from the second 'e|t' encode 'e' as 1 and
65190b57cec5SDimitry Andric   // 't' as 0 and finish with a 1.
65200b57cec5SDimitry Andric   unsigned Imm = 0;
65210b57cec5SDimitry Andric   // We always start with a 't'.
65220b57cec5SDimitry Andric   unsigned CurBit = 0;
65230b57cec5SDimitry Andric   for (int i = 3; i >= 0; --i) {
65240b57cec5SDimitry Andric     // If the bit we are looking at is not the same as last one, invert the
65250b57cec5SDimitry Andric     // CurBit, if it is the same leave it as is.
65260b57cec5SDimitry Andric     CurBit ^= (Val >> i) & 1U;
65270b57cec5SDimitry Andric 
65280b57cec5SDimitry Andric     // Encode the CurBit at the right place in the immediate.
65290b57cec5SDimitry Andric     Imm |= (CurBit << i);
65300b57cec5SDimitry Andric 
65310b57cec5SDimitry Andric     // If we are done, finish the encoding with a 1.
65320b57cec5SDimitry Andric     if ((Val & ~(~0U << i)) == 0) {
65330b57cec5SDimitry Andric       Imm |= 1U << i;
65340b57cec5SDimitry Andric       break;
65350b57cec5SDimitry Andric     }
65360b57cec5SDimitry Andric   }
65370b57cec5SDimitry Andric 
65380b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
65390b57cec5SDimitry Andric 
65400b57cec5SDimitry Andric   return S;
65410b57cec5SDimitry Andric }
65420b57cec5SDimitry Andric 
65430b57cec5SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
654481ad6265SDimitry Andric                                         uint64_t Address,
654581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
65460b57cec5SDimitry Andric   // The vpred_r operand type includes an MQPR register field derived
65470b57cec5SDimitry Andric   // from the encoding. But we don't actually want to add an operand
65480b57cec5SDimitry Andric   // to the MCInst at this stage, because AddThumbPredicate will do it
65490b57cec5SDimitry Andric   // later, and will infer the register number from the TIED_TO
65500b57cec5SDimitry Andric   // constraint. So this is a deliberately empty decoder method that
65510b57cec5SDimitry Andric   // will inhibit the auto-generated disassembly code from adding an
65520b57cec5SDimitry Andric   // operand at all.
65530b57cec5SDimitry Andric   return MCDisassembler::Success;
65540b57cec5SDimitry Andric }
65550b57cec5SDimitry Andric 
6556bdd1243dSDimitry Andric [[maybe_unused]] static DecodeStatus
6557bdd1243dSDimitry Andric DecodeVpredNOperand(MCInst &Inst, unsigned RegNo, uint64_t Address,
6558bdd1243dSDimitry Andric                     const MCDisassembler *Decoder) {
6559bdd1243dSDimitry Andric   // Similar to above, we want to ensure that no operands are added for the
6560bdd1243dSDimitry Andric   // vpred operands. (This is marked "maybe_unused" for the moment; because
6561bdd1243dSDimitry Andric   // DecoderEmitter currently (wrongly) omits operands with no instruction bits,
6562bdd1243dSDimitry Andric   // the decoder doesn't actually call it yet. That will be addressed in a
6563bdd1243dSDimitry Andric   // future change.)
6564bdd1243dSDimitry Andric   return MCDisassembler::Success;
6565bdd1243dSDimitry Andric }
6566bdd1243dSDimitry Andric 
656781ad6265SDimitry Andric static DecodeStatus
656881ad6265SDimitry Andric DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
656981ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
65700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE));
65710b57cec5SDimitry Andric   return MCDisassembler::Success;
65720b57cec5SDimitry Andric }
65730b57cec5SDimitry Andric 
657481ad6265SDimitry Andric static DecodeStatus
657581ad6265SDimitry Andric DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
657681ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
65770b57cec5SDimitry Andric   unsigned Code;
65780b57cec5SDimitry Andric   switch (Val & 0x3) {
65790b57cec5SDimitry Andric   case 0:
65800b57cec5SDimitry Andric     Code = ARMCC::GE;
65810b57cec5SDimitry Andric     break;
65820b57cec5SDimitry Andric   case 1:
65830b57cec5SDimitry Andric     Code = ARMCC::LT;
65840b57cec5SDimitry Andric     break;
65850b57cec5SDimitry Andric   case 2:
65860b57cec5SDimitry Andric     Code = ARMCC::GT;
65870b57cec5SDimitry Andric     break;
65880b57cec5SDimitry Andric   case 3:
65890b57cec5SDimitry Andric     Code = ARMCC::LE;
65900b57cec5SDimitry Andric     break;
65910b57cec5SDimitry Andric   }
65920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Code));
65930b57cec5SDimitry Andric   return MCDisassembler::Success;
65940b57cec5SDimitry Andric }
65950b57cec5SDimitry Andric 
659681ad6265SDimitry Andric static DecodeStatus
659781ad6265SDimitry Andric DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
659881ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
65990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI));
66000b57cec5SDimitry Andric   return MCDisassembler::Success;
66010b57cec5SDimitry Andric }
66020b57cec5SDimitry Andric 
660381ad6265SDimitry Andric static DecodeStatus
660481ad6265SDimitry Andric DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
660581ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
66060b57cec5SDimitry Andric   unsigned Code;
66070b57cec5SDimitry Andric   switch (Val) {
66080b57cec5SDimitry Andric   default:
66090b57cec5SDimitry Andric     return MCDisassembler::Fail;
66100b57cec5SDimitry Andric   case 0:
66110b57cec5SDimitry Andric     Code = ARMCC::EQ;
66120b57cec5SDimitry Andric     break;
66130b57cec5SDimitry Andric   case 1:
66140b57cec5SDimitry Andric     Code = ARMCC::NE;
66150b57cec5SDimitry Andric     break;
66160b57cec5SDimitry Andric   case 4:
66170b57cec5SDimitry Andric     Code = ARMCC::GE;
66180b57cec5SDimitry Andric     break;
66190b57cec5SDimitry Andric   case 5:
66200b57cec5SDimitry Andric     Code = ARMCC::LT;
66210b57cec5SDimitry Andric     break;
66220b57cec5SDimitry Andric   case 6:
66230b57cec5SDimitry Andric     Code = ARMCC::GT;
66240b57cec5SDimitry Andric     break;
66250b57cec5SDimitry Andric   case 7:
66260b57cec5SDimitry Andric     Code = ARMCC::LE;
66270b57cec5SDimitry Andric     break;
66280b57cec5SDimitry Andric   }
66290b57cec5SDimitry Andric 
66300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Code));
66310b57cec5SDimitry Andric   return MCDisassembler::Success;
66320b57cec5SDimitry Andric }
66330b57cec5SDimitry Andric 
66340b57cec5SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Val,
663581ad6265SDimitry Andric                                          uint64_t Address,
663681ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
66370b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
66380b57cec5SDimitry Andric 
66390b57cec5SDimitry Andric   unsigned DecodedVal = 64 - Val;
66400b57cec5SDimitry Andric 
66410b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
66420b57cec5SDimitry Andric   case ARM::MVE_VCVTf16s16_fix:
66430b57cec5SDimitry Andric   case ARM::MVE_VCVTs16f16_fix:
66440b57cec5SDimitry Andric   case ARM::MVE_VCVTf16u16_fix:
66450b57cec5SDimitry Andric   case ARM::MVE_VCVTu16f16_fix:
66460b57cec5SDimitry Andric     if (DecodedVal > 16)
66470b57cec5SDimitry Andric       return MCDisassembler::Fail;
66480b57cec5SDimitry Andric     break;
66490b57cec5SDimitry Andric   case ARM::MVE_VCVTf32s32_fix:
66500b57cec5SDimitry Andric   case ARM::MVE_VCVTs32f32_fix:
66510b57cec5SDimitry Andric   case ARM::MVE_VCVTf32u32_fix:
66520b57cec5SDimitry Andric   case ARM::MVE_VCVTu32f32_fix:
66530b57cec5SDimitry Andric     if (DecodedVal > 32)
66540b57cec5SDimitry Andric       return MCDisassembler::Fail;
66550b57cec5SDimitry Andric     break;
66560b57cec5SDimitry Andric   }
66570b57cec5SDimitry Andric 
66580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
66590b57cec5SDimitry Andric 
66600b57cec5SDimitry Andric   return S;
66610b57cec5SDimitry Andric }
66620b57cec5SDimitry Andric 
66630b57cec5SDimitry Andric static unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) {
66640b57cec5SDimitry Andric   switch (Opcode) {
66650b57cec5SDimitry Andric   case ARM::VSTR_P0_off:
66660b57cec5SDimitry Andric   case ARM::VSTR_P0_pre:
66670b57cec5SDimitry Andric   case ARM::VSTR_P0_post:
66680b57cec5SDimitry Andric   case ARM::VLDR_P0_off:
66690b57cec5SDimitry Andric   case ARM::VLDR_P0_pre:
66700b57cec5SDimitry Andric   case ARM::VLDR_P0_post:
66710b57cec5SDimitry Andric     return ARM::P0;
66720b57cec5SDimitry Andric   default:
66730b57cec5SDimitry Andric     return 0;
66740b57cec5SDimitry Andric   }
66750b57cec5SDimitry Andric }
66760b57cec5SDimitry Andric 
66770b57cec5SDimitry Andric template <bool Writeback>
66780b57cec5SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val,
66790b57cec5SDimitry Andric                                           uint64_t Address,
668081ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
66810b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
66820b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_pre:
66830b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_pre:
66840b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_pre:
66850b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_pre:
66860b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_off:
66870b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_off:
66880b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_off:
66890b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_off:
66900b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_post:
66910b57cec5SDimitry Andric   case ARM::VSTR_FPSCR_NZCVQC_post:
66920b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_post:
66930b57cec5SDimitry Andric   case ARM::VLDR_FPSCR_NZCVQC_post:
66940b57cec5SDimitry Andric     const FeatureBitset &featureBits =
66950b57cec5SDimitry Andric         ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
66960b57cec5SDimitry Andric 
66970b57cec5SDimitry Andric     if (!featureBits[ARM::HasMVEIntegerOps] && !featureBits[ARM::FeatureVFP2])
66980b57cec5SDimitry Andric       return MCDisassembler::Fail;
66990b57cec5SDimitry Andric   }
67000b57cec5SDimitry Andric 
67010b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67020b57cec5SDimitry Andric   if (unsigned Sysreg = FixedRegForVSTRVLDR_SYSREG(Inst.getOpcode()))
67030b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Sysreg));
67040b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
67050b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Val, 0, 7) |
67060b57cec5SDimitry Andric                   (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
67070b57cec5SDimitry Andric 
67080b57cec5SDimitry Andric   if (Writeback) {
67090b57cec5SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
67100b57cec5SDimitry Andric       return MCDisassembler::Fail;
67110b57cec5SDimitry Andric   }
67120b57cec5SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm7s4(Inst, addr, Address, Decoder)))
67130b57cec5SDimitry Andric     return MCDisassembler::Fail;
67140b57cec5SDimitry Andric 
67150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMCC::AL));
67160b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
67170b57cec5SDimitry Andric 
67180b57cec5SDimitry Andric   return S;
67190b57cec5SDimitry Andric }
67200b57cec5SDimitry Andric 
672181ad6265SDimitry Andric static inline DecodeStatus
672281ad6265SDimitry Andric DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
672381ad6265SDimitry Andric                   const MCDisassembler *Decoder, unsigned Rn,
672481ad6265SDimitry Andric                   OperandDecoder RnDecoder, OperandDecoder AddrDecoder) {
67250b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67260b57cec5SDimitry Andric 
67270b57cec5SDimitry Andric   unsigned Qd = fieldFromInstruction(Val, 13, 3);
67280b57cec5SDimitry Andric   unsigned addr = fieldFromInstruction(Val, 0, 7) |
67290b57cec5SDimitry Andric                   (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
67300b57cec5SDimitry Andric 
67310b57cec5SDimitry Andric   if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder)))
67320b57cec5SDimitry Andric     return MCDisassembler::Fail;
67330b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
67340b57cec5SDimitry Andric     return MCDisassembler::Fail;
67350b57cec5SDimitry Andric   if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
67360b57cec5SDimitry Andric     return MCDisassembler::Fail;
67370b57cec5SDimitry Andric 
67380b57cec5SDimitry Andric   return S;
67390b57cec5SDimitry Andric }
67400b57cec5SDimitry Andric 
67410b57cec5SDimitry Andric template <int shift>
67420b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
674381ad6265SDimitry Andric                                         uint64_t Address,
674481ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
67450b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
67460b57cec5SDimitry Andric                            fieldFromInstruction(Val, 16, 3),
67470b57cec5SDimitry Andric                            DecodetGPRRegisterClass,
67480b57cec5SDimitry Andric                            DecodeTAddrModeImm7<shift>);
67490b57cec5SDimitry Andric }
67500b57cec5SDimitry Andric 
67510b57cec5SDimitry Andric template <int shift>
67520b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
675381ad6265SDimitry Andric                                         uint64_t Address,
675481ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
67550b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
67560b57cec5SDimitry Andric                            fieldFromInstruction(Val, 16, 4),
67570b57cec5SDimitry Andric                            DecoderGPRRegisterClass,
67580b57cec5SDimitry Andric                            DecodeT2AddrModeImm7<shift,1>);
67590b57cec5SDimitry Andric }
67600b57cec5SDimitry Andric 
67610b57cec5SDimitry Andric template <int shift>
67620b57cec5SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
676381ad6265SDimitry Andric                                         uint64_t Address,
676481ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
67650b57cec5SDimitry Andric   return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
67660b57cec5SDimitry Andric                            fieldFromInstruction(Val, 17, 3),
67670b57cec5SDimitry Andric                            DecodeMQPRRegisterClass,
67680b57cec5SDimitry Andric                            DecodeMveAddrModeQ<shift>);
67690b57cec5SDimitry Andric }
67700b57cec5SDimitry Andric 
67710b57cec5SDimitry Andric template <unsigned MinLog, unsigned MaxLog>
67720b57cec5SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
67730b57cec5SDimitry Andric                                           uint64_t Address,
677481ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
67750b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67760b57cec5SDimitry Andric 
67770b57cec5SDimitry Andric   if (Val < MinLog || Val > MaxLog)
67780b57cec5SDimitry Andric     return MCDisassembler::Fail;
67790b57cec5SDimitry Andric 
67800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(1LL << Val));
67810b57cec5SDimitry Andric   return S;
67820b57cec5SDimitry Andric }
67830b57cec5SDimitry Andric 
67840b57cec5SDimitry Andric template <unsigned start>
678581ad6265SDimitry Andric static DecodeStatus
678681ad6265SDimitry Andric DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, uint64_t Address,
678781ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
67880b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67890b57cec5SDimitry Andric 
67900b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(start + Val));
67910b57cec5SDimitry Andric 
67920b57cec5SDimitry Andric   return S;
67930b57cec5SDimitry Andric }
67940b57cec5SDimitry Andric 
67950b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
679681ad6265SDimitry Andric                                          uint64_t Address,
679781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
67980b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
67990b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
68000b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
68010b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
68020b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
68030b57cec5SDimitry Andric   unsigned index = fieldFromInstruction(Insn, 4, 1);
68040b57cec5SDimitry Andric 
68050b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
68060b57cec5SDimitry Andric     return MCDisassembler::Fail;
68070b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
68080b57cec5SDimitry Andric     return MCDisassembler::Fail;
68090b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
68100b57cec5SDimitry Andric     return MCDisassembler::Fail;
68110b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
68120b57cec5SDimitry Andric     return MCDisassembler::Fail;
68130b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
68140b57cec5SDimitry Andric     return MCDisassembler::Fail;
68150b57cec5SDimitry Andric 
68160b57cec5SDimitry Andric   return S;
68170b57cec5SDimitry Andric }
68180b57cec5SDimitry Andric 
68190b57cec5SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
682081ad6265SDimitry Andric                                          uint64_t Address,
682181ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
68220b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
68230b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
68240b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
68250b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
68260b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
68270b57cec5SDimitry Andric   unsigned index = fieldFromInstruction(Insn, 4, 1);
68280b57cec5SDimitry Andric 
68290b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
68300b57cec5SDimitry Andric     return MCDisassembler::Fail;
68310b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
68320b57cec5SDimitry Andric     return MCDisassembler::Fail;
68330b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
68340b57cec5SDimitry Andric     return MCDisassembler::Fail;
68350b57cec5SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
68360b57cec5SDimitry Andric     return MCDisassembler::Fail;
68370b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
68380b57cec5SDimitry Andric     return MCDisassembler::Fail;
68390b57cec5SDimitry Andric   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
68400b57cec5SDimitry Andric     return MCDisassembler::Fail;
68410b57cec5SDimitry Andric 
68420b57cec5SDimitry Andric   return S;
68430b57cec5SDimitry Andric }
68440b57cec5SDimitry Andric 
684581ad6265SDimitry Andric static DecodeStatus
684681ad6265SDimitry Andric DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, uint64_t Address,
684781ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
68480b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
68490b57cec5SDimitry Andric 
68500b57cec5SDimitry Andric   unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1;
68510b57cec5SDimitry Andric   unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1;
68520b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 12, 4);
68530b57cec5SDimitry Andric 
68540b57cec5SDimitry Andric   if (RdaHi == 14) {
68550b57cec5SDimitry Andric     // This value of RdaHi (really indicating pc, because RdaHi has to
68560b57cec5SDimitry Andric     // be an odd-numbered register, so the low bit will be set by the
68570b57cec5SDimitry Andric     // decode function below) indicates that we must decode as SQRSHR
68580b57cec5SDimitry Andric     // or UQRSHL, which both have a single Rda register field with all
68590b57cec5SDimitry Andric     // four bits.
68600b57cec5SDimitry Andric     unsigned Rda = fieldFromInstruction(Insn, 16, 4);
68610b57cec5SDimitry Andric 
68620b57cec5SDimitry Andric     switch (Inst.getOpcode()) {
68630b57cec5SDimitry Andric       case ARM::MVE_ASRLr:
68640b57cec5SDimitry Andric       case ARM::MVE_SQRSHRL:
68650b57cec5SDimitry Andric         Inst.setOpcode(ARM::MVE_SQRSHR);
68660b57cec5SDimitry Andric         break;
68670b57cec5SDimitry Andric       case ARM::MVE_LSLLr:
68680b57cec5SDimitry Andric       case ARM::MVE_UQRSHLL:
68690b57cec5SDimitry Andric         Inst.setOpcode(ARM::MVE_UQRSHL);
68700b57cec5SDimitry Andric         break;
68710b57cec5SDimitry Andric       default:
68720b57cec5SDimitry Andric         llvm_unreachable("Unexpected starting opcode!");
68730b57cec5SDimitry Andric     }
68740b57cec5SDimitry Andric 
68750b57cec5SDimitry Andric     // Rda as output parameter
68760b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
68770b57cec5SDimitry Andric       return MCDisassembler::Fail;
68780b57cec5SDimitry Andric 
68790b57cec5SDimitry Andric     // Rda again as input parameter
68800b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
68810b57cec5SDimitry Andric       return MCDisassembler::Fail;
68820b57cec5SDimitry Andric 
68830b57cec5SDimitry Andric     // Rm, the amount to shift by
68840b57cec5SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
68850b57cec5SDimitry Andric       return MCDisassembler::Fail;
68860b57cec5SDimitry Andric 
68878bcb0991SDimitry Andric     if (fieldFromInstruction (Insn, 6, 3) != 4)
68888bcb0991SDimitry Andric       return MCDisassembler::SoftFail;
68898bcb0991SDimitry Andric 
68908bcb0991SDimitry Andric     if (Rda == Rm)
68918bcb0991SDimitry Andric       return MCDisassembler::SoftFail;
68928bcb0991SDimitry Andric 
68930b57cec5SDimitry Andric     return S;
68940b57cec5SDimitry Andric   }
68950b57cec5SDimitry Andric 
68960b57cec5SDimitry Andric   // Otherwise, we decode as whichever opcode our caller has already
68970b57cec5SDimitry Andric   // put into Inst. Those all look the same:
68980b57cec5SDimitry Andric 
68990b57cec5SDimitry Andric   // RdaLo,RdaHi as output parameters
69000b57cec5SDimitry Andric   if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
69010b57cec5SDimitry Andric     return MCDisassembler::Fail;
69020b57cec5SDimitry Andric   if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
69030b57cec5SDimitry Andric     return MCDisassembler::Fail;
69040b57cec5SDimitry Andric 
69050b57cec5SDimitry Andric   // RdaLo,RdaHi again as input parameters
69060b57cec5SDimitry Andric   if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
69070b57cec5SDimitry Andric     return MCDisassembler::Fail;
69080b57cec5SDimitry Andric   if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
69090b57cec5SDimitry Andric     return MCDisassembler::Fail;
69100b57cec5SDimitry Andric 
69110b57cec5SDimitry Andric   // Rm, the amount to shift by
69120b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
69130b57cec5SDimitry Andric     return MCDisassembler::Fail;
69140b57cec5SDimitry Andric 
69158bcb0991SDimitry Andric   if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
69168bcb0991SDimitry Andric       Inst.getOpcode() == ARM::MVE_UQRSHLL) {
69178bcb0991SDimitry Andric     unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
69188bcb0991SDimitry Andric     // Saturate, the bit position for saturation
69198bcb0991SDimitry Andric     Inst.addOperand(MCOperand::createImm(Saturate));
69208bcb0991SDimitry Andric   }
69218bcb0991SDimitry Andric 
69220b57cec5SDimitry Andric   return S;
69230b57cec5SDimitry Andric }
69240b57cec5SDimitry Andric 
692581ad6265SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
692681ad6265SDimitry Andric                                       uint64_t Address,
692781ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
69280b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69290b57cec5SDimitry Andric   unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
69300b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 13, 3));
69310b57cec5SDimitry Andric   unsigned Qm = ((fieldFromInstruction(Insn, 5, 1) << 3) |
69320b57cec5SDimitry Andric                  fieldFromInstruction(Insn, 1, 3));
69330b57cec5SDimitry Andric   unsigned imm6 = fieldFromInstruction(Insn, 16, 6);
69340b57cec5SDimitry Andric 
69350b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
69360b57cec5SDimitry Andric     return MCDisassembler::Fail;
69370b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
69380b57cec5SDimitry Andric     return MCDisassembler::Fail;
69390b57cec5SDimitry Andric   if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
69400b57cec5SDimitry Andric     return MCDisassembler::Fail;
69410b57cec5SDimitry Andric 
69420b57cec5SDimitry Andric   return S;
69430b57cec5SDimitry Andric }
69440b57cec5SDimitry Andric 
69450b57cec5SDimitry Andric template <bool scalar, OperandDecoder predicate_decoder>
69460b57cec5SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
694781ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
69480b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69490b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69500b57cec5SDimitry Andric   unsigned Qn = fieldFromInstruction(Insn, 17, 3);
69510b57cec5SDimitry Andric   if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
69520b57cec5SDimitry Andric     return MCDisassembler::Fail;
69530b57cec5SDimitry Andric 
69540b57cec5SDimitry Andric   unsigned fc;
69550b57cec5SDimitry Andric 
69560b57cec5SDimitry Andric   if (scalar) {
69570b57cec5SDimitry Andric     fc = fieldFromInstruction(Insn, 12, 1) << 2 |
69580b57cec5SDimitry Andric          fieldFromInstruction(Insn, 7, 1) |
69590b57cec5SDimitry Andric          fieldFromInstruction(Insn, 5, 1) << 1;
69600b57cec5SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 0, 4);
69610b57cec5SDimitry Andric     if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder)))
69620b57cec5SDimitry Andric       return MCDisassembler::Fail;
69630b57cec5SDimitry Andric   } else {
69640b57cec5SDimitry Andric     fc = fieldFromInstruction(Insn, 12, 1) << 2 |
69650b57cec5SDimitry Andric          fieldFromInstruction(Insn, 7, 1) |
69660b57cec5SDimitry Andric          fieldFromInstruction(Insn, 0, 1) << 1;
69670b57cec5SDimitry Andric     unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 |
69680b57cec5SDimitry Andric                   fieldFromInstruction(Insn, 1, 3);
69690b57cec5SDimitry Andric     if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
69700b57cec5SDimitry Andric       return MCDisassembler::Fail;
69710b57cec5SDimitry Andric   }
69720b57cec5SDimitry Andric 
69730b57cec5SDimitry Andric   if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
69740b57cec5SDimitry Andric     return MCDisassembler::Fail;
69750b57cec5SDimitry Andric 
69760b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
69770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(0));
69780b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
69790b57cec5SDimitry Andric 
69800b57cec5SDimitry Andric   return S;
69810b57cec5SDimitry Andric }
69820b57cec5SDimitry Andric 
69830b57cec5SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
698481ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
69850b57cec5SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69860b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69870b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
69880b57cec5SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
69890b57cec5SDimitry Andric     return MCDisassembler::Fail;
69900b57cec5SDimitry Andric   return S;
69910b57cec5SDimitry Andric }
69928bcb0991SDimitry Andric 
699381ad6265SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
699481ad6265SDimitry Andric                                    uint64_t Address,
699581ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
69968bcb0991SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
69978bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69988bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::VPR));
69998bcb0991SDimitry Andric   return S;
70008bcb0991SDimitry Andric }
7001480093f4SDimitry Andric 
7002480093f4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
700381ad6265SDimitry Andric                                         uint64_t Address,
700481ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
7005480093f4SDimitry Andric   const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
7006480093f4SDimitry Andric   const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
7007480093f4SDimitry Andric   const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 |
7008480093f4SDimitry Andric                          fieldFromInstruction(Insn, 12, 3) << 8 |
7009480093f4SDimitry Andric                          fieldFromInstruction(Insn, 0, 8);
7010480093f4SDimitry Andric   const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1);
7011480093f4SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
7012480093f4SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
7013480093f4SDimitry Andric   unsigned S = fieldFromInstruction(Insn, 20, 1);
7014480093f4SDimitry Andric   if (sign1 != sign2)
7015480093f4SDimitry Andric     return MCDisassembler::Fail;
7016480093f4SDimitry Andric 
7017480093f4SDimitry Andric   // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm)
7018480093f4SDimitry Andric   DecodeStatus DS = MCDisassembler::Success;
7019480093f4SDimitry Andric   if ((!Check(DS,
7020480093f4SDimitry Andric               DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst
7021480093f4SDimitry Andric       (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder))))
7022480093f4SDimitry Andric     return MCDisassembler::Fail;
7023480093f4SDimitry Andric   if (TypeT3) {
7024480093f4SDimitry Andric     Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
7025480093f4SDimitry Andric     Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
7026480093f4SDimitry Andric   } else {
7027480093f4SDimitry Andric     Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
7028480093f4SDimitry Andric     if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
7029480093f4SDimitry Andric       return MCDisassembler::Fail;
7030480093f4SDimitry Andric     if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
7031480093f4SDimitry Andric       return MCDisassembler::Fail;
7032fe6060f1SDimitry Andric   }
7033480093f4SDimitry Andric 
7034480093f4SDimitry Andric   return DS;
7035480093f4SDimitry Andric }
7036*0fca6ea1SDimitry Andric 
7037*0fca6ea1SDimitry Andric static DecodeStatus DecodeLazyLoadStoreMul(MCInst &Inst, unsigned Insn,
7038*0fca6ea1SDimitry Andric                                            uint64_t Address,
7039*0fca6ea1SDimitry Andric                                            const MCDisassembler *Decoder) {
7040*0fca6ea1SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
7041*0fca6ea1SDimitry Andric 
7042*0fca6ea1SDimitry Andric   const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
7043*0fca6ea1SDimitry Andric   // Adding Rn, holding memory location to save/load to/from, the only argument
7044*0fca6ea1SDimitry Andric   // that is being encoded.
7045*0fca6ea1SDimitry Andric   // '$Rn' in the assembly.
7046*0fca6ea1SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
7047*0fca6ea1SDimitry Andric     return MCDisassembler::Fail;
7048*0fca6ea1SDimitry Andric   // An optional predicate, '$p' in the assembly.
7049*0fca6ea1SDimitry Andric   DecodePredicateOperand(Inst, ARMCC::AL, Address, Decoder);
7050*0fca6ea1SDimitry Andric   // An immediate that represents a floating point registers list. '$regs' in
7051*0fca6ea1SDimitry Andric   // the assembly.
7052*0fca6ea1SDimitry Andric   Inst.addOperand(MCOperand::createImm(0)); // Arbitrary value, has no effect.
7053*0fca6ea1SDimitry Andric 
7054*0fca6ea1SDimitry Andric   return S;
7055*0fca6ea1SDimitry Andric }
7056